summaryrefslogtreecommitdiffstats
path: root/dom/bindings/parser/tests/test_interface.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /dom/bindings/parser/tests/test_interface.py
parentInitial commit. (diff)
downloadthunderbird-upstream.tar.xz
thunderbird-upstream.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/bindings/parser/tests/test_interface.py')
-rw-r--r--dom/bindings/parser/tests/test_interface.py459
1 files changed, 459 insertions, 0 deletions
diff --git a/dom/bindings/parser/tests/test_interface.py b/dom/bindings/parser/tests/test_interface.py
new file mode 100644
index 0000000000..c078a593bb
--- /dev/null
+++ b/dom/bindings/parser/tests/test_interface.py
@@ -0,0 +1,459 @@
+import WebIDL
+
+
+def WebIDLTest(parser, harness):
+ parser.parse("interface Foo { };")
+ results = parser.finish()
+ harness.ok(True, "Empty interface parsed without error.")
+ harness.check(len(results), 1, "Should be one production")
+ harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface")
+ iface = results[0]
+ harness.check(iface.identifier.QName(), "::Foo", "Interface has the right QName")
+ harness.check(iface.identifier.name, "Foo", "Interface has the right name")
+ harness.check(iface.parent, None, "Interface has no parent")
+
+ parser.parse("interface Bar : Foo { };")
+ results = parser.finish()
+ harness.ok(True, "Empty interface parsed without error.")
+ harness.check(len(results), 2, "Should be two productions")
+ harness.ok(isinstance(results[1], WebIDL.IDLInterface), "Should be an IDLInterface")
+ iface = results[1]
+ harness.check(iface.identifier.QName(), "::Bar", "Interface has the right QName")
+ harness.check(iface.identifier.name, "Bar", "Interface has the right name")
+ harness.ok(isinstance(iface.parent, WebIDL.IDLInterface), "Interface has a parent")
+
+ parser = parser.reset()
+ parser.parse(
+ """
+ interface QNameBase {
+ attribute long foo;
+ };
+
+ interface QNameDerived : QNameBase {
+ attribute long long foo;
+ attribute byte bar;
+ };
+ """
+ )
+ results = parser.finish()
+ harness.check(len(results), 2, "Should be two productions")
+ harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface")
+ harness.ok(isinstance(results[1], WebIDL.IDLInterface), "Should be an IDLInterface")
+ harness.check(results[1].parent, results[0], "Inheritance chain is right")
+ harness.check(len(results[0].members), 1, "Expect 1 productions")
+ harness.check(len(results[1].members), 2, "Expect 2 productions")
+ base = results[0]
+ derived = results[1]
+ harness.check(
+ base.members[0].identifier.QName(),
+ "::QNameBase::foo",
+ "Member has the right QName",
+ )
+ harness.check(
+ derived.members[0].identifier.QName(),
+ "::QNameDerived::foo",
+ "Member has the right QName",
+ )
+ harness.check(
+ derived.members[1].identifier.QName(),
+ "::QNameDerived::bar",
+ "Member has the right QName",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ interface A : B {};
+ interface B : A {};
+ """
+ )
+ results = parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(threw, "Should not allow cycles in interface inheritance chains")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ interface A : C {};
+ interface C : B {};
+ interface B : A {};
+ """
+ )
+ results = parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(
+ threw, "Should not allow indirect cycles in interface inheritance chains"
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ interface A;
+ interface B : A {};
+ """
+ )
+ results = parser.finish()
+ except Exception:
+ threw = True
+
+ harness.ok(
+ threw,
+ "Should not allow inheriting from an interface that is only forward declared",
+ )
+
+ parser = parser.reset()
+ parser.parse(
+ """
+ interface A {
+ constructor();
+ constructor(long arg);
+ readonly attribute boolean x;
+ undefined foo();
+ };
+ partial interface A {
+ readonly attribute boolean y;
+ undefined foo(long arg);
+ };
+ """
+ )
+ results = parser.finish()
+ harness.check(len(results), 2, "Should have two results with partial interface")
+ iface = results[0]
+ harness.check(
+ len(iface.members), 3, "Should have three members with partial interface"
+ )
+ harness.check(
+ iface.members[0].identifier.name,
+ "x",
+ "First member should be x with partial interface",
+ )
+ harness.check(
+ iface.members[1].identifier.name,
+ "foo",
+ "Second member should be foo with partial interface",
+ )
+ harness.check(
+ len(iface.members[1].signatures()),
+ 2,
+ "Should have two foo signatures with partial interface",
+ )
+ harness.check(
+ iface.members[2].identifier.name,
+ "y",
+ "Third member should be y with partial interface",
+ )
+ harness.check(
+ len(iface.ctor().signatures()),
+ 2,
+ "Should have two constructors with partial interface",
+ )
+
+ parser = parser.reset()
+ parser.parse(
+ """
+ partial interface A {
+ readonly attribute boolean y;
+ undefined foo(long arg);
+ };
+ interface A {
+ constructor();
+ constructor(long arg);
+ readonly attribute boolean x;
+ undefined foo();
+ };
+ """
+ )
+ results = parser.finish()
+ harness.check(
+ len(results), 2, "Should have two results with reversed partial interface"
+ )
+ iface = results[1]
+ harness.check(
+ len(iface.members),
+ 3,
+ "Should have three members with reversed partial interface",
+ )
+ harness.check(
+ iface.members[0].identifier.name,
+ "x",
+ "First member should be x with reversed partial interface",
+ )
+ harness.check(
+ iface.members[1].identifier.name,
+ "foo",
+ "Second member should be foo with reversed partial interface",
+ )
+ harness.check(
+ len(iface.members[1].signatures()),
+ 2,
+ "Should have two foo signatures with reversed partial interface",
+ )
+ harness.check(
+ iface.members[2].identifier.name,
+ "y",
+ "Third member should be y with reversed partial interface",
+ )
+ harness.check(
+ len(iface.ctor().signatures()),
+ 2,
+ "Should have two constructors with reversed partial interface",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ interface A {
+ readonly attribute boolean x;
+ };
+ interface A {
+ readonly attribute boolean y;
+ };
+ """
+ )
+ results = parser.finish()
+ except Exception:
+ threw = True
+ harness.ok(threw, "Should not allow two non-partial interfaces with the same name")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ partial interface A {
+ readonly attribute boolean x;
+ };
+ partial interface A {
+ readonly attribute boolean y;
+ };
+ """
+ )
+ results = parser.finish()
+ except Exception:
+ threw = True
+ harness.ok(threw, "Must have a non-partial interface for a given name")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ boolean x;
+ };
+ partial interface A {
+ readonly attribute boolean y;
+ };
+ """
+ )
+ results = parser.finish()
+ except Exception:
+ threw = True
+ harness.ok(
+ threw,
+ "Should not allow a name collision between partial interface "
+ "and other object",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ boolean x;
+ };
+ interface A {
+ readonly attribute boolean y;
+ };
+ """
+ )
+ results = parser.finish()
+ except Exception:
+ threw = True
+ harness.ok(
+ threw, "Should not allow a name collision between interface " "and other object"
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ dictionary A {
+ boolean x;
+ };
+ interface A;
+ """
+ )
+ results = parser.finish()
+ except Exception:
+ threw = True
+ harness.ok(
+ threw,
+ "Should not allow a name collision between external interface "
+ "and other object",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ interface A {
+ readonly attribute boolean x;
+ };
+ interface A;
+ """
+ )
+ results = parser.finish()
+ except Exception:
+ threw = True
+ harness.ok(
+ threw,
+ "Should not allow a name collision between external interface " "and interface",
+ )
+
+ parser = parser.reset()
+ parser.parse(
+ """
+ interface A;
+ interface A;
+ """
+ )
+ results = parser.finish()
+ harness.ok(
+ len(results) == 1 and isinstance(results[0], WebIDL.IDLExternalInterface),
+ "Should allow name collisions between external interface " "declarations",
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ [SomeRandomAnnotation]
+ interface A {
+ readonly attribute boolean y;
+ };
+ """
+ )
+ results = parser.finish()
+ except Exception:
+ threw = True
+ harness.ok(threw, "Should not allow unknown extended attributes on interfaces")
+
+ parser = parser.reset()
+ parser.parse(
+ """
+ [Global, Exposed=Window] interface Window {};
+ [Exposed=Window, LegacyWindowAlias=A]
+ interface B {};
+ [Exposed=Window, LegacyWindowAlias=(C, D)]
+ interface E {};
+ """
+ )
+ results = parser.finish()
+ harness.check(
+ results[1].legacyWindowAliases, ["A"], "Should support a single identifier"
+ )
+ harness.check(
+ results[2].legacyWindowAliases, ["C", "D"], "Should support an identifier list"
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ [LegacyWindowAlias]
+ interface A {};
+ """
+ )
+ results = parser.finish()
+ except Exception:
+ threw = True
+ harness.ok(threw, "Should not allow [LegacyWindowAlias] with no value")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ [Exposed=Worker, LegacyWindowAlias=B]
+ interface A {};
+ """
+ )
+ results = parser.finish()
+ except Exception:
+ threw = True
+ harness.ok(threw, "Should not allow [LegacyWindowAlias] without Window exposure")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ [Global, Exposed=Window] interface Window {};
+ [Exposed=Window]
+ interface A {};
+ [Exposed=Window, LegacyWindowAlias=A]
+ interface B {};
+ """
+ )
+ results = parser.finish()
+ except Exception:
+ threw = True
+ harness.ok(
+ threw, "Should not allow [LegacyWindowAlias] to conflict with other identifiers"
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ [Global, Exposed=Window] interface Window {};
+ [Exposed=Window, LegacyWindowAlias=A]
+ interface B {};
+ [Exposed=Window]
+ interface A {};
+ """
+ )
+ results = parser.finish()
+ except Exception:
+ threw = True
+ harness.ok(
+ threw, "Should not allow [LegacyWindowAlias] to conflict with other identifiers"
+ )
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(
+ """
+ [Global, Exposed=Window] interface Window {};
+ [Exposed=Window, LegacyWindowAlias=A]
+ interface B {};
+ [Exposed=Window, LegacyWindowAlias=A]
+ interface C {};
+ """
+ )
+ results = parser.finish()
+ except Exception:
+ threw = True
+ harness.ok(
+ threw, "Should not allow [LegacyWindowAlias] to conflict with other identifiers"
+ )