summaryrefslogtreecommitdiffstats
path: root/dom/bindings/parser/tests/test_dictionary.py
diff options
context:
space:
mode:
Diffstat (limited to 'dom/bindings/parser/tests/test_dictionary.py')
-rw-r--r--dom/bindings/parser/tests/test_dictionary.py875
1 files changed, 875 insertions, 0 deletions
diff --git a/dom/bindings/parser/tests/test_dictionary.py b/dom/bindings/parser/tests/test_dictionary.py
new file mode 100644
index 0000000000..26411b96d7
--- /dev/null
+++ b/dom/bindings/parser/tests/test_dictionary.py
@@ -0,0 +1,875 @@
+def WebIDLTest(parser, harness):
+ parser.parse(
+ """
+ dictionary Dict2 : Dict1 {
+ long child = 5;
+ Dict1 aaandAnother;
+ };
+ dictionary Dict1 {
+ long parent;
+ double otherParent;
+ };
+ """
+ )
+ results = parser.finish()
+
+ dict1 = results[1]
+ dict2 = results[0]
+
+ harness.check(len(dict1.members), 2, "Dict1 has two members")
+ harness.check(len(dict2.members), 2, "Dict2 has four members")
+
+ harness.check(
+ dict1.members[0].identifier.name, "otherParent", "'o' comes before 'p'"
+ )
+ harness.check(
+ dict1.members[1].identifier.name, "parent", "'o' really comes before 'p'"
+ )
+ harness.check(
+ dict2.members[0].identifier.name, "aaandAnother", "'a' comes before 'c'"
+ )
+ harness.check(
+ dict2.members[1].identifier.name, "child", "'a' really comes before 'c'"
+ )
+
+ # Test partial dictionary.
+ parser = parser.reset()
+ parser.parse(
+ """
+ dictionary A {
+ long c;
+ long g;
+ };
+ partial dictionary A {
+ long h;
+ long d;
+ };
+ """
+ )
+ results = parser.finish()
+
+ dict1 = results[0]
+ harness.check(len(dict1.members), 4, "Dict1 has four members")
+ harness.check(dict1.members[0].identifier.name, "c", "c should be first")
+ harness.check(dict1.members[1].identifier.name, "d", "d should come after c")
+ harness.check(dict1.members[2].identifier.name, "g", "g should come after d")
+ harness.check(dict1.members[3].identifier.name, "h", "h should be last")
+
+ # Now reset our parser
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Dict {
+ long prop = 5;
+ long prop;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Should not allow name duplication in a dictionary")
+
+ # Test no name duplication across normal and partial dictionary.
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ long prop = 5;
+ };
+ partial dictionary A {
+ long prop;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(
+ threw, "Should not allow name duplication across normal and partial dictionary"
+ )
+
+ # Now reset our parser again
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Dict1 : Dict2 {
+ long prop = 5;
+ };
+ dictionary Dict2 : Dict3 {
+ long prop2;
+ };
+ dictionary Dict3 {
+ double prop;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(
+ threw, "Should not allow name duplication in a dictionary and " "its ancestor"
+ )
+
+ # More reset
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ interface Iface {};
+ dictionary Dict : Iface {
+ long prop;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Should not allow non-dictionary parents for dictionaries")
+
+ # Even more reset
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A : B {};
+ dictionary B : A {};
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Should not allow cycles in dictionary inheritance chains")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ [LegacyNullToEmptyString] DOMString foo;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(
+ threw, "Should not allow [LegacyNullToEmptyString] on dictionary members"
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(A arg);
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Trailing dictionary arg must be optional")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(optional A arg);
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Trailing dictionary arg must have a default value")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo((A or DOMString) arg);
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Trailing union arg containing a dictionary must be optional")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(optional (A or DOMString) arg);
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(
+ threw, "Trailing union arg containing a dictionary must have a default value"
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(A arg1, optional long arg2);
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Dictionary arg followed by optional arg must be optional")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(optional A arg1, optional long arg2);
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Dictionary arg followed by optional arg must have default value")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(A arg1, optional long arg2, long arg3);
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(
+ not threw,
+ "Dictionary arg followed by non-optional arg doesn't have to be optional",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo((A or DOMString) arg1, optional long arg2);
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(
+ threw,
+ "Union arg containing dictionary followed by optional arg must " "be optional",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(optional (A or DOMString) arg1, optional long arg2);
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(
+ threw,
+ "Union arg containing dictionary followed by optional arg must "
+ "have a default value",
+ )
+
+ parser = parser.reset()
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(A arg1, long arg2);
+ };
+ """
+ )
+ parser.finish()
+ harness.ok(True, "Dictionary arg followed by required arg can be required")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(optional A? arg1 = {});
+ };
+ """
+ )
+ parser.finish()
+ except Exception as x:
+ threw = x
+
+ harness.ok(threw, "Optional dictionary arg must not be nullable")
+ harness.ok(
+ "nullable" in str(threw),
+ "Must have the expected exception for optional nullable dictionary arg",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ required long x;
+ };
+ interface X {
+ undefined doFoo(A? arg1);
+ };
+ """
+ )
+ parser.finish()
+ except Exception as x:
+ threw = x
+
+ harness.ok(threw, "Required dictionary arg must not be nullable")
+ harness.ok(
+ "nullable" in str(threw),
+ "Must have the expected exception for required nullable " "dictionary arg",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(optional (A or long)? arg1 = {});
+ };
+ """
+ )
+ parser.finish()
+ except Exception as x:
+ threw = x
+
+ harness.ok(threw, "Dictionary arg must not be in an optional nullable union")
+ harness.ok(
+ "nullable" in str(threw),
+ "Must have the expected exception for optional nullable union "
+ "arg containing dictionary",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ required long x;
+ };
+ interface X {
+ undefined doFoo((A or long)? arg1);
+ };
+ """
+ )
+ parser.finish()
+ except Exception as x:
+ threw = x
+
+ harness.ok(threw, "Dictionary arg must not be in a required nullable union")
+ harness.ok(
+ "nullable" in str(threw),
+ "Must have the expected exception for required nullable union "
+ "arg containing dictionary",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(sequence<A?> arg1);
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(not threw, "Nullable union should be allowed in a sequence argument")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(optional (A or long?) arg1);
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+ harness.ok(threw, "Dictionary must not be in a union with a nullable type")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(optional (long? or A) arg1);
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+ harness.ok(threw, "A nullable type must not be in a union with a dictionary")
+
+ parser = parser.reset()
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ A? doFoo();
+ };
+ """
+ )
+ parser.finish()
+ harness.ok(True, "Dictionary return value can be nullable")
+
+ parser = parser.reset()
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(optional A arg = {});
+ };
+ """
+ )
+ parser.finish()
+ harness.ok(True, "Dictionary arg should actually parse")
+
+ parser = parser.reset()
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(optional (A or DOMString) arg = {});
+ };
+ """
+ )
+ parser.finish()
+ harness.ok(True, "Union arg containing a dictionary should actually parse")
+
+ parser = parser.reset()
+ parser.parse(
+ """
+ dictionary A {
+ };
+ interface X {
+ undefined doFoo(optional (A or DOMString) arg = "abc");
+ };
+ """
+ )
+ parser.finish()
+ harness.ok(
+ True,
+ "Union arg containing a dictionary with string default should actually parse",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Foo {
+ Foo foo;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Member type must not be its Dictionary.")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Foo3 : Foo {
+ short d;
+ };
+
+ dictionary Foo2 : Foo3 {
+ boolean c;
+ };
+
+ dictionary Foo1 : Foo2 {
+ long a;
+ };
+
+ dictionary Foo {
+ Foo1 b;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(
+ threw,
+ "Member type must not be a Dictionary that " "inherits from its Dictionary.",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Foo {
+ (Foo or DOMString)[]? b;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(
+ threw,
+ "Member type must not be a Nullable type "
+ "whose inner type includes its Dictionary.",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Foo {
+ (DOMString or Foo) b;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(
+ threw,
+ "Member type must not be a Union type, one of "
+ "whose member types includes its Dictionary.",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Foo {
+ sequence<sequence<sequence<Foo>>> c;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(
+ threw,
+ "Member type must not be a Sequence type "
+ "whose element type includes its Dictionary.",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Foo {
+ (DOMString or Foo)[] d;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(
+ threw,
+ "Member type must not be an Array type "
+ "whose element type includes its Dictionary.",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Foo {
+ Foo1 b;
+ };
+
+ dictionary Foo3 {
+ Foo d;
+ };
+
+ dictionary Foo2 : Foo3 {
+ short c;
+ };
+
+ dictionary Foo1 : Foo2 {
+ long a;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(
+ threw,
+ "Member type must not be a Dictionary, one of whose "
+ "members or inherited members has a type that includes "
+ "its Dictionary.",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Foo {
+ };
+
+ dictionary Bar {
+ Foo? d;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Member type must not be a nullable dictionary")
+
+ parser = parser.reset()
+ parser.parse(
+ """
+ dictionary Foo {
+ unrestricted float urFloat = 0;
+ unrestricted float urFloat2 = 1.1;
+ unrestricted float urFloat3 = -1.1;
+ unrestricted float? urFloat4 = null;
+ unrestricted float infUrFloat = Infinity;
+ unrestricted float negativeInfUrFloat = -Infinity;
+ unrestricted float nanUrFloat = NaN;
+
+ unrestricted double urDouble = 0;
+ unrestricted double urDouble2 = 1.1;
+ unrestricted double urDouble3 = -1.1;
+ unrestricted double? urDouble4 = null;
+ unrestricted double infUrDouble = Infinity;
+ unrestricted double negativeInfUrDouble = -Infinity;
+ unrestricted double nanUrDouble = NaN;
+ };
+ """
+ )
+ parser.finish()
+ harness.ok(True, "Parsing default values for unrestricted types succeeded.")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Foo {
+ double f = Infinity;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Only unrestricted values can be initialized to Infinity")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Foo {
+ double f = -Infinity;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Only unrestricted values can be initialized to -Infinity")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Foo {
+ double f = NaN;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Only unrestricted values can be initialized to NaN")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Foo {
+ float f = Infinity;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Only unrestricted values can be initialized to Infinity")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Foo {
+ float f = -Infinity;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Only unrestricted values can be initialized to -Infinity")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Foo {
+ float f = NaN;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Only unrestricted values can be initialized to NaN")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary Foo {
+ long module;
+ };
+ """
+ )
+ parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(not threw, "Should be able to use 'module' as a dictionary member name")