import WebIDL def WebIDLTest(parser, harness): parser.parse(""" [SecureContext] interface TestSecureContextOnInterface { const octet TEST_CONSTANT = 0; readonly attribute byte testAttribute; void testMethod(byte foo); }; partial interface TestSecureContextOnInterface { const octet TEST_CONSTANT_2 = 0; readonly attribute byte testAttribute2; void testMethod2(byte foo); }; """) results = parser.finish() harness.check(len(results[0].members), 6, "TestSecureContextOnInterface should have six members") harness.ok(results[0].getExtendedAttribute("SecureContext"), "Interface should have [SecureContext] extended attribute") harness.ok(results[0].members[0].getExtendedAttribute("SecureContext"), "[SecureContext] should propagate from interface to constant members") harness.ok(results[0].members[1].getExtendedAttribute("SecureContext"), "[SecureContext] should propagate from interface to attribute members") harness.ok(results[0].members[2].getExtendedAttribute("SecureContext"), "[SecureContext] should propagate from interface to method members") harness.ok(results[0].members[3].getExtendedAttribute("SecureContext"), "[SecureContext] should propagate from interface to constant members from partial interface") harness.ok(results[0].members[4].getExtendedAttribute("SecureContext"), "[SecureContext] should propagate from interface to attribute members from partial interface") harness.ok(results[0].members[5].getExtendedAttribute("SecureContext"), "[SecureContext] should propagate from interface to method members from partial interface") # Same thing, but with the partial interface specified first: parser = parser.reset() parser.parse(""" partial interface TestSecureContextOnInterfaceAfterPartialInterface { const octet TEST_CONSTANT_2 = 0; readonly attribute byte testAttribute2; void testMethod2(byte foo); }; [SecureContext] interface TestSecureContextOnInterfaceAfterPartialInterface { const octet TEST_CONSTANT = 0; readonly attribute byte testAttribute; void testMethod(byte foo); }; """) results = parser.finish() harness.check(len(results[1].members), 6, "TestSecureContextOnInterfaceAfterPartialInterface should have six members") harness.ok(results[1].getExtendedAttribute("SecureContext"), "Interface should have [SecureContext] extended attribute") harness.ok(results[1].members[0].getExtendedAttribute("SecureContext"), "[SecureContext] should propagate from interface to constant members") harness.ok(results[1].members[1].getExtendedAttribute("SecureContext"), "[SecureContext] should propagate from interface to attribute members") harness.ok(results[1].members[2].getExtendedAttribute("SecureContext"), "[SecureContext] should propagate from interface to method members") harness.ok(results[1].members[3].getExtendedAttribute("SecureContext"), "[SecureContext] should propagate from interface to constant members from partial interface") harness.ok(results[1].members[4].getExtendedAttribute("SecureContext"), "[SecureContext] should propagate from interface to attribute members from partial interface") harness.ok(results[1].members[5].getExtendedAttribute("SecureContext"), "[SecureContext] should propagate from interface to method members from partial interface") parser = parser.reset() parser.parse(""" interface TestSecureContextOnPartialInterface { const octet TEST_CONSTANT = 0; readonly attribute byte testAttribute; void testMethod(byte foo); }; [SecureContext] partial interface TestSecureContextOnPartialInterface { const octet TEST_CONSTANT_2 = 0; readonly attribute byte testAttribute2; void testMethod2(byte foo); }; """) results = parser.finish() harness.check(len(results[0].members), 6, "TestSecureContextOnPartialInterface should have six members") harness.ok(results[0].getExtendedAttribute("SecureContext") is None, "[SecureContext] should not propagate from a partial interface to the interface") harness.ok(results[0].members[0].getExtendedAttribute("SecureContext") is None, "[SecureContext] should not propagate from a partial interface to the interface's constant members") harness.ok(results[0].members[1].getExtendedAttribute("SecureContext") is None, "[SecureContext] should not propagate from a partial interface to the interface's attribute members") harness.ok(results[0].members[2].getExtendedAttribute("SecureContext") is None, "[SecureContext] should not propagate from a partial interface to the interface's method members") harness.ok(results[0].members[3].getExtendedAttribute("SecureContext"), "Constant members from [SecureContext] partial interface should be [SecureContext]") harness.ok(results[0].members[4].getExtendedAttribute("SecureContext"), "Attribute members from [SecureContext] partial interface should be [SecureContext]") harness.ok(results[0].members[5].getExtendedAttribute("SecureContext"), "Method members from [SecureContext] partial interface should be [SecureContext]") parser = parser.reset() parser.parse(""" interface TestSecureContextOnInterfaceMembers { const octet TEST_NON_SECURE_CONSTANT_1 = 0; [SecureContext] const octet TEST_SECURE_CONSTANT = 1; const octet TEST_NON_SECURE_CONSTANT_2 = 2; readonly attribute byte testNonSecureAttribute1; [SecureContext] readonly attribute byte testSecureAttribute; readonly attribute byte testNonSecureAttribute2; void testNonSecureMethod1(byte foo); [SecureContext] void testSecureMethod(byte foo); void testNonSecureMethod2(byte foo); }; """) results = parser.finish() harness.check(len(results[0].members), 9, "TestSecureContextOnInterfaceMembers should have nine members") harness.ok(results[0].getExtendedAttribute("SecureContext") is None, "[SecureContext] on members should not propagate up to the interface") harness.ok(results[0].members[0].getExtendedAttribute("SecureContext") is None, "Constant should not have [SecureContext] extended attribute") harness.ok(results[0].members[1].getExtendedAttribute("SecureContext"), "Constant should have [SecureContext] extended attribute") harness.ok(results[0].members[2].getExtendedAttribute("SecureContext") is None, "Constant should not have [SecureContext] extended attribute") harness.ok(results[0].members[3].getExtendedAttribute("SecureContext") is None, "Attribute should not have [SecureContext] extended attribute") harness.ok(results[0].members[4].getExtendedAttribute("SecureContext"), "Attribute should have [SecureContext] extended attribute") harness.ok(results[0].members[5].getExtendedAttribute("SecureContext") is None, "Attribute should not have [SecureContext] extended attribute") harness.ok(results[0].members[6].getExtendedAttribute("SecureContext") is None, "Method should not have [SecureContext] extended attribute") harness.ok(results[0].members[7].getExtendedAttribute("SecureContext"), "Method should have [SecureContext] extended attribute") harness.ok(results[0].members[8].getExtendedAttribute("SecureContext") is None, "Method should not have [SecureContext] extended attribute") parser = parser.reset() parser.parse(""" interface TestSecureContextOnPartialInterfaceMembers { }; partial interface TestSecureContextOnPartialInterfaceMembers { const octet TEST_NON_SECURE_CONSTANT_1 = 0; [SecureContext] const octet TEST_SECURE_CONSTANT = 1; const octet TEST_NON_SECURE_CONSTANT_2 = 2; readonly attribute byte testNonSecureAttribute1; [SecureContext] readonly attribute byte testSecureAttribute; readonly attribute byte testNonSecureAttribute2; void testNonSecureMethod1(byte foo); [SecureContext] void testSecureMethod(byte foo); void testNonSecureMethod2(byte foo); }; """) results = parser.finish() harness.check(len(results[0].members), 9, "TestSecureContextOnPartialInterfaceMembers should have nine members") harness.ok(results[0].members[0].getExtendedAttribute("SecureContext") is None, "Constant from partial interface should not have [SecureContext] extended attribute") harness.ok(results[0].members[1].getExtendedAttribute("SecureContext"), "Constant from partial interface should have [SecureContext] extended attribute") harness.ok(results[0].members[2].getExtendedAttribute("SecureContext") is None, "Constant from partial interface should not have [SecureContext] extended attribute") harness.ok(results[0].members[3].getExtendedAttribute("SecureContext") is None, "Attribute from partial interface should not have [SecureContext] extended attribute") harness.ok(results[0].members[4].getExtendedAttribute("SecureContext"), "Attribute from partial interface should have [SecureContext] extended attribute") harness.ok(results[0].members[5].getExtendedAttribute("SecureContext") is None, "Attribute from partial interface should not have [SecureContext] extended attribute") harness.ok(results[0].members[6].getExtendedAttribute("SecureContext") is None, "Method from partial interface should not have [SecureContext] extended attribute") harness.ok(results[0].members[7].getExtendedAttribute("SecureContext"), "Method from partial interface should have [SecureContext] extended attribute") harness.ok(results[0].members[8].getExtendedAttribute("SecureContext") is None, "Method from partial interface should not have [SecureContext] extended attribute") parser = parser.reset() threw = False try: parser.parse(""" [SecureContext=something] interface TestSecureContextTakesNoValue1 { const octet TEST_SECURE_CONSTANT = 0; }; """) results = parser.finish() except: threw = True harness.ok(threw, "[SecureContext] must take no arguments (testing on interface)") parser = parser.reset() threw = False try: parser.parse(""" interface TestSecureContextForOverloads1 { [SecureContext] void testSecureMethod(byte foo); }; partial interface TestSecureContextForOverloads1 { void testSecureMethod(byte foo, byte bar); }; """) results = parser.finish() except: threw = True harness.ok(threw, "If [SecureContext] appears on an overloaded operation, then it MUST appear on all overloads") parser = parser.reset() threw = False try: parser.parse(""" interface TestSecureContextForOverloads2 { [SecureContext] void testSecureMethod(byte foo); }; partial interface TestSecureContextForOverloads2 { [SecureContext] void testSecureMethod(byte foo, byte bar); }; """) results = parser.finish() except: threw = True harness.ok(not threw, "[SecureContext] can appear on an overloaded operation if it appears on all overloads") parser = parser.reset() threw = False try: parser.parse(""" [SecureContext] interface TestSecureContextOnInterfaceAndMember { [SecureContext] void testSecureMethod(byte foo); }; """) results = parser.finish() except: threw = True harness.ok(threw, "[SecureContext] must not appear on an interface and interface member") parser = parser.reset() threw = False try: parser.parse(""" interface TestSecureContextOnPartialInterfaceAndMember { }; [SecureContext] partial interface TestSecureContextOnPartialInterfaceAndMember { [SecureContext] void testSecureMethod(byte foo); }; """) results = parser.finish() except: threw = True harness.ok(threw, "[SecureContext] must not appear on a partial interface and one of the partial interface's member's") parser = parser.reset() threw = False try: parser.parse(""" [SecureContext] interface TestSecureContextOnInterfaceAndPartialInterfaceMember { }; partial interface TestSecureContextOnInterfaceAndPartialInterfaceMember { [SecureContext] void testSecureMethod(byte foo); }; """) results = parser.finish() except: threw = True harness.ok(threw, "[SecureContext] must not appear on an interface and one of its partial interface's member's") parser = parser.reset() threw = False try: parser.parse(""" [SecureContext] interface TestSecureContextOnInheritedInterface { }; interface TestSecureContextNotOnInheritingInterface : TestSecureContextOnInheritedInterface { void testSecureMethod(byte foo); }; """) results = parser.finish() except: threw = True harness.ok(threw, "[SecureContext] must appear on interfaces that inherit from another [SecureContext] interface") # Test 'implements'. The behavior tested here may have to change depending # on the resolution of https://github.com/heycam/webidl/issues/118 parser = parser.reset() parser.parse(""" [SecureContext] interface TestSecureContextInterfaceThatImplementsNonSecureContextInterface { const octet TEST_CONSTANT = 0; }; interface TestNonSecureContextInterface { const octet TEST_CONSTANT_2 = 0; readonly attribute byte testAttribute2; void testMethod2(byte foo); }; TestSecureContextInterfaceThatImplementsNonSecureContextInterface implements TestNonSecureContextInterface; """) results = parser.finish() harness.check(len(results[0].members), 4, "TestSecureContextInterfaceThatImplementsNonSecureContextInterface should have two members") harness.ok(results[0].getExtendedAttribute("SecureContext"), "Interface should have [SecureContext] extended attribute") harness.ok(results[0].members[0].getExtendedAttribute("SecureContext"), "[SecureContext] should propagate from interface to constant members even when other members are copied from a non-[SecureContext] interface") harness.ok(results[0].members[1].getExtendedAttribute("SecureContext") is None, "Constants copied from non-[SecureContext] interface should not be [SecureContext]") harness.ok(results[0].members[2].getExtendedAttribute("SecureContext") is None, "Attributes copied from non-[SecureContext] interface should not be [SecureContext]") harness.ok(results[0].members[3].getExtendedAttribute("SecureContext") is None, "Methods copied from non-[SecureContext] interface should not be [SecureContext]") # Test SecureContext and NoInterfaceObject parser = parser.reset() parser.parse(""" [NoInterfaceObject, SecureContext] interface TestSecureContextNoInterfaceObject { void testSecureMethod(byte foo); }; """) results = parser.finish() harness.check(len(results[0].members), 1, "TestSecureContextNoInterfaceObject should have only one member") harness.ok(results[0].getExtendedAttribute("SecureContext"), "Interface should have [SecureContext] extended attribute") harness.ok(results[0].members[0].getExtendedAttribute("SecureContext"), "Interface member should have [SecureContext] extended attribute")