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 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>> 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")