summaryrefslogtreecommitdiffstats
path: root/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py
diff options
context:
space:
mode:
Diffstat (limited to 'dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py')
-rw-r--r--dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py691
1 files changed, 691 insertions, 0 deletions
diff --git a/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py b/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py
new file mode 100644
index 000000000..ee5d870c2
--- /dev/null
+++ b/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py
@@ -0,0 +1,691 @@
+import WebIDL
+import traceback
+def WebIDLTest(parser, harness):
+
+ def shouldPass(prefix, iface, expectedMembers, numProductions=1):
+ p = parser.reset()
+ p.parse(iface)
+ results = p.finish()
+ harness.check(len(results), numProductions,
+ "%s - Should have production count %d" % (prefix, numProductions))
+ harness.ok(isinstance(results[0], WebIDL.IDLInterface),
+ "%s - Should be an IDLInterface" % (prefix))
+ # Make a copy, since we plan to modify it
+ expectedMembers = list(expectedMembers)
+ for m in results[0].members:
+ name = m.identifier.name
+ if (name, type(m)) in expectedMembers:
+ harness.ok(True, "%s - %s - Should be a %s" % (prefix, name,
+ type(m)))
+ expectedMembers.remove((name, type(m)))
+ else:
+ harness.ok(False, "%s - %s - Unknown symbol of type %s" %
+ (prefix, name, type(m)))
+ # A bit of a hoop because we can't generate the error string if we pass
+ if len(expectedMembers) == 0:
+ harness.ok(True, "Found all the members")
+ else:
+ harness.ok(False,
+ "Expected member not found: %s of type %s" %
+ (expectedMembers[0][0], expectedMembers[0][1]))
+ return results
+
+ def shouldFail(prefix, iface):
+ try:
+ p = parser.reset()
+ p.parse(iface)
+ p.finish()
+ harness.ok(False,
+ prefix + " - Interface passed when should've failed")
+ except WebIDL.WebIDLError, e:
+ harness.ok(True,
+ prefix + " - Interface failed as expected")
+ except Exception, e:
+ harness.ok(False,
+ prefix + " - Interface failed but not as a WebIDLError exception: %s" % e)
+
+ iterableMembers = [(x, WebIDL.IDLMethod) for x in ["entries", "keys",
+ "values", "forEach"]]
+ setROMembers = ([(x, WebIDL.IDLMethod) for x in ["has"]] +
+ [("__setlike", WebIDL.IDLMaplikeOrSetlike)] +
+ iterableMembers)
+ setROMembers.extend([("size", WebIDL.IDLAttribute)])
+ setRWMembers = ([(x, WebIDL.IDLMethod) for x in ["add",
+ "clear",
+ "delete"]] +
+ setROMembers)
+ setROChromeMembers = ([(x, WebIDL.IDLMethod) for x in ["__add",
+ "__clear",
+ "__delete"]] +
+ setROMembers)
+ setRWChromeMembers = ([(x, WebIDL.IDLMethod) for x in ["__add",
+ "__clear",
+ "__delete"]] +
+ setRWMembers)
+ mapROMembers = ([(x, WebIDL.IDLMethod) for x in ["get", "has"]] +
+ [("__maplike", WebIDL.IDLMaplikeOrSetlike)] +
+ iterableMembers)
+ mapROMembers.extend([("size", WebIDL.IDLAttribute)])
+ mapRWMembers = ([(x, WebIDL.IDLMethod) for x in ["set",
+ "clear",
+ "delete"]] + mapROMembers)
+ mapRWChromeMembers = ([(x, WebIDL.IDLMethod) for x in ["__set",
+ "__clear",
+ "__delete"]] +
+ mapRWMembers)
+
+ # OK, now that we've used iterableMembers to set up the above, append
+ # __iterable to it for the iterable<> case.
+ iterableMembers.append(("__iterable", WebIDL.IDLIterable))
+
+ valueIterableMembers = [("__iterable", WebIDL.IDLIterable)]
+ valueIterableMembers.append(("__indexedgetter", WebIDL.IDLMethod))
+ valueIterableMembers.append(("length", WebIDL.IDLAttribute))
+
+ disallowedIterableNames = ["keys", "entries", "values"]
+ disallowedMemberNames = ["forEach", "has", "size"] + disallowedIterableNames
+ mapDisallowedMemberNames = ["get"] + disallowedMemberNames
+ disallowedNonMethodNames = ["clear", "delete"]
+ mapDisallowedNonMethodNames = ["set"] + disallowedNonMethodNames
+ setDisallowedNonMethodNames = ["add"] + disallowedNonMethodNames
+ unrelatedMembers = [("unrelatedAttribute", WebIDL.IDLAttribute),
+ ("unrelatedMethod", WebIDL.IDLMethod)]
+
+ #
+ # Simple Usage Tests
+ #
+
+ shouldPass("Iterable (key only)",
+ """
+ interface Foo1 {
+ iterable<long>;
+ readonly attribute unsigned long length;
+ getter long(unsigned long index);
+ attribute long unrelatedAttribute;
+ long unrelatedMethod();
+ };
+ """, valueIterableMembers + unrelatedMembers)
+
+ shouldPass("Iterable (key only) inheriting from parent",
+ """
+ interface Foo1 : Foo2 {
+ iterable<long>;
+ readonly attribute unsigned long length;
+ getter long(unsigned long index);
+ };
+ interface Foo2 {
+ attribute long unrelatedAttribute;
+ long unrelatedMethod();
+ };
+ """, valueIterableMembers, numProductions=2)
+
+ shouldPass("Iterable (key and value)",
+ """
+ interface Foo1 {
+ iterable<long, long>;
+ attribute long unrelatedAttribute;
+ long unrelatedMethod();
+ };
+ """, iterableMembers + unrelatedMembers,
+ # numProductions == 2 because of the generated iterator iface,
+ numProductions=2)
+
+ shouldPass("Iterable (key and value) inheriting from parent",
+ """
+ interface Foo1 : Foo2 {
+ iterable<long, long>;
+ };
+ interface Foo2 {
+ attribute long unrelatedAttribute;
+ long unrelatedMethod();
+ };
+ """, iterableMembers,
+ # numProductions == 3 because of the generated iterator iface,
+ numProductions=3)
+
+ shouldPass("Maplike (readwrite)",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ attribute long unrelatedAttribute;
+ long unrelatedMethod();
+ };
+ """, mapRWMembers + unrelatedMembers)
+
+ shouldPass("Maplike (readwrite) inheriting from parent",
+ """
+ interface Foo1 : Foo2 {
+ maplike<long, long>;
+ };
+ interface Foo2 {
+ attribute long unrelatedAttribute;
+ long unrelatedMethod();
+ };
+ """, mapRWMembers, numProductions=2)
+
+ shouldPass("Maplike (readwrite)",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ attribute long unrelatedAttribute;
+ long unrelatedMethod();
+ };
+ """, mapRWMembers + unrelatedMembers)
+
+ shouldPass("Maplike (readwrite) inheriting from parent",
+ """
+ interface Foo1 : Foo2 {
+ maplike<long, long>;
+ };
+ interface Foo2 {
+ attribute long unrelatedAttribute;
+ long unrelatedMethod();
+ };
+ """, mapRWMembers, numProductions=2)
+
+ shouldPass("Maplike (readonly)",
+ """
+ interface Foo1 {
+ readonly maplike<long, long>;
+ attribute long unrelatedAttribute;
+ long unrelatedMethod();
+ };
+ """, mapROMembers + unrelatedMembers)
+
+ shouldPass("Maplike (readonly) inheriting from parent",
+ """
+ interface Foo1 : Foo2 {
+ readonly maplike<long, long>;
+ };
+ interface Foo2 {
+ attribute long unrelatedAttribute;
+ long unrelatedMethod();
+ };
+ """, mapROMembers, numProductions=2)
+
+ shouldPass("Setlike (readwrite)",
+ """
+ interface Foo1 {
+ setlike<long>;
+ attribute long unrelatedAttribute;
+ long unrelatedMethod();
+ };
+ """, setRWMembers + unrelatedMembers)
+
+ shouldPass("Setlike (readwrite) inheriting from parent",
+ """
+ interface Foo1 : Foo2 {
+ setlike<long>;
+ };
+ interface Foo2 {
+ attribute long unrelatedAttribute;
+ long unrelatedMethod();
+ };
+ """, setRWMembers, numProductions=2)
+
+ shouldPass("Setlike (readonly)",
+ """
+ interface Foo1 {
+ readonly setlike<long>;
+ attribute long unrelatedAttribute;
+ long unrelatedMethod();
+ };
+ """, setROMembers + unrelatedMembers)
+
+ shouldPass("Setlike (readonly) inheriting from parent",
+ """
+ interface Foo1 : Foo2 {
+ readonly setlike<long>;
+ };
+ interface Foo2 {
+ attribute long unrelatedAttribute;
+ long unrelatedMethod();
+ };
+ """, setROMembers, numProductions=2)
+
+ shouldPass("Inheritance of maplike/setlike",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ interface Foo2 : Foo1 {
+ };
+ """, mapRWMembers, numProductions=2)
+
+ shouldPass("Implements with maplike/setlike",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ interface Foo2 {
+ };
+ Foo2 implements Foo1;
+ """, mapRWMembers, numProductions=3)
+
+ shouldPass("JS Implemented maplike interface",
+ """
+ [JSImplementation="@mozilla.org/dom/test-interface-js-maplike;1",
+ Constructor()]
+ interface Foo1 {
+ setlike<long>;
+ };
+ """, setRWChromeMembers)
+
+ shouldPass("JS Implemented maplike interface",
+ """
+ [JSImplementation="@mozilla.org/dom/test-interface-js-maplike;1",
+ Constructor()]
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ """, mapRWChromeMembers)
+
+ #
+ # Multiple maplike/setlike tests
+ #
+
+ shouldFail("Two maplike/setlikes on same interface",
+ """
+ interface Foo1 {
+ setlike<long>;
+ maplike<long, long>;
+ };
+ """)
+
+ shouldFail("Two iterable/setlikes on same interface",
+ """
+ interface Foo1 {
+ iterable<long>;
+ maplike<long, long>;
+ };
+ """)
+
+ shouldFail("Two iterables on same interface",
+ """
+ interface Foo1 {
+ iterable<long>;
+ iterable<long, long>;
+ };
+ """)
+
+ shouldFail("Two maplike/setlikes in partials",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ partial interface Foo1 {
+ setlike<long>;
+ };
+ """)
+
+ shouldFail("Conflicting maplike/setlikes across inheritance",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ interface Foo2 : Foo1 {
+ setlike<long>;
+ };
+ """)
+
+ shouldFail("Conflicting maplike/iterable across inheritance",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ interface Foo2 : Foo1 {
+ iterable<long>;
+ };
+ """)
+
+ shouldFail("Conflicting maplike/setlikes across multistep inheritance",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ interface Foo2 : Foo1 {
+ };
+ interface Foo3 : Foo2 {
+ setlike<long>;
+ };
+ """)
+
+ shouldFail("Consequential interface with conflicting maplike/setlike",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ interface Foo2 {
+ setlike<long>;
+ };
+ Foo2 implements Foo1;
+ """)
+
+ shouldFail("Consequential interfaces with conflicting maplike/setlike",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ interface Foo2 {
+ setlike<long>;
+ };
+ interface Foo3 {
+ };
+ Foo3 implements Foo1;
+ Foo3 implements Foo2;
+ """)
+
+ #
+ # Member name collision tests
+ #
+
+ def testConflictingMembers(likeMember, conflictName, expectedMembers, methodPasses):
+ """
+ Tests for maplike/setlike member generation against conflicting member
+ names. If methodPasses is True, this means we expect the interface to
+ pass in the case of method shadowing, and expectedMembers should be the
+ list of interface members to check against on the passing interface.
+
+ """
+ if methodPasses:
+ shouldPass("Conflicting method: %s and %s" % (likeMember, conflictName),
+ """
+ interface Foo1 {
+ %s;
+ [Throws]
+ void %s(long test1, double test2, double test3);
+ };
+ """ % (likeMember, conflictName), expectedMembers)
+ else:
+ shouldFail("Conflicting method: %s and %s" % (likeMember, conflictName),
+ """
+ interface Foo1 {
+ %s;
+ [Throws]
+ void %s(long test1, double test2, double test3);
+ };
+ """ % (likeMember, conflictName))
+ # Inherited conflicting methods should ALWAYS fail
+ shouldFail("Conflicting inherited method: %s and %s" % (likeMember, conflictName),
+ """
+ interface Foo1 {
+ void %s(long test1, double test2, double test3);
+ };
+ interface Foo2 : Foo1 {
+ %s;
+ };
+ """ % (conflictName, likeMember))
+ shouldFail("Conflicting static method: %s and %s" % (likeMember, conflictName),
+ """
+ interface Foo1 {
+ %s;
+ static void %s(long test1, double test2, double test3);
+ };
+ """ % (likeMember, conflictName))
+ shouldFail("Conflicting attribute: %s and %s" % (likeMember, conflictName),
+ """
+ interface Foo1 {
+ %s
+ attribute double %s;
+ };
+ """ % (likeMember, conflictName))
+ shouldFail("Conflicting const: %s and %s" % (likeMember, conflictName),
+ """
+ interface Foo1 {
+ %s;
+ const double %s = 0;
+ };
+ """ % (likeMember, conflictName))
+ shouldFail("Conflicting static attribute: %s and %s" % (likeMember, conflictName),
+ """
+ interface Foo1 {
+ %s;
+ static attribute long %s;
+ };
+ """ % (likeMember, conflictName))
+
+ for member in disallowedIterableNames:
+ testConflictingMembers("iterable<long, long>", member, iterableMembers, False)
+ for member in mapDisallowedMemberNames:
+ testConflictingMembers("maplike<long, long>", member, mapRWMembers, False)
+ for member in disallowedMemberNames:
+ testConflictingMembers("setlike<long>", member, setRWMembers, False)
+ for member in mapDisallowedNonMethodNames:
+ testConflictingMembers("maplike<long, long>", member, mapRWMembers, True)
+ for member in setDisallowedNonMethodNames:
+ testConflictingMembers("setlike<long>", member, setRWMembers, True)
+
+ shouldPass("Inheritance of maplike/setlike with child member collision",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ interface Foo2 : Foo1 {
+ void entries();
+ };
+ """, mapRWMembers, numProductions=2)
+
+ shouldPass("Inheritance of multi-level maplike/setlike with child member collision",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ interface Foo2 : Foo1 {
+ };
+ interface Foo3 : Foo2 {
+ void entries();
+ };
+ """, mapRWMembers, numProductions=3)
+
+ shouldFail("Interface with consequential maplike/setlike interface member collision",
+ """
+ interface Foo1 {
+ void entries();
+ };
+ interface Foo2 {
+ maplike<long, long>;
+ };
+ Foo1 implements Foo2;
+ """)
+
+ shouldFail("Maplike interface with consequential interface member collision",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ interface Foo2 {
+ void entries();
+ };
+ Foo1 implements Foo2;
+ """)
+
+ shouldPass("Consequential Maplike interface with inherited interface member collision",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ interface Foo2 {
+ void entries();
+ };
+ interface Foo3 : Foo2 {
+ };
+ Foo3 implements Foo1;
+ """, mapRWMembers, numProductions=4)
+
+ shouldPass("Inherited Maplike interface with consequential interface member collision",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ interface Foo2 {
+ void entries();
+ };
+ interface Foo3 : Foo1 {
+ };
+ Foo3 implements Foo2;
+ """, mapRWMembers, numProductions=4)
+
+ shouldFail("Inheritance of name collision with child maplike/setlike",
+ """
+ interface Foo1 {
+ void entries();
+ };
+ interface Foo2 : Foo1 {
+ maplike<long, long>;
+ };
+ """)
+
+ shouldFail("Inheritance of multi-level name collision with child maplike/setlike",
+ """
+ interface Foo1 {
+ void entries();
+ };
+ interface Foo2 : Foo1 {
+ };
+ interface Foo3 : Foo2 {
+ maplike<long, long>;
+ };
+ """)
+
+ shouldPass("Inheritance of attribute collision with parent maplike/setlike",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ interface Foo2 : Foo1 {
+ attribute double size;
+ };
+ """, mapRWMembers, numProductions=2)
+
+ shouldPass("Inheritance of multi-level attribute collision with parent maplike/setlike",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ interface Foo2 : Foo1 {
+ };
+ interface Foo3 : Foo2 {
+ attribute double size;
+ };
+ """, mapRWMembers, numProductions=3)
+
+ shouldFail("Inheritance of attribute collision with child maplike/setlike",
+ """
+ interface Foo1 {
+ attribute double size;
+ };
+ interface Foo2 : Foo1 {
+ maplike<long, long>;
+ };
+ """)
+
+ shouldFail("Inheritance of multi-level attribute collision with child maplike/setlike",
+ """
+ interface Foo1 {
+ attribute double size;
+ };
+ interface Foo2 : Foo1 {
+ };
+ interface Foo3 : Foo2 {
+ maplike<long, long>;
+ };
+ """)
+
+ shouldFail("Inheritance of attribute/rw function collision with child maplike/setlike",
+ """
+ interface Foo1 {
+ attribute double set;
+ };
+ interface Foo2 : Foo1 {
+ maplike<long, long>;
+ };
+ """)
+
+ shouldFail("Inheritance of const/rw function collision with child maplike/setlike",
+ """
+ interface Foo1 {
+ const double set = 0;
+ };
+ interface Foo2 : Foo1 {
+ maplike<long, long>;
+ };
+ """)
+
+ shouldPass("Inheritance of rw function with same name in child maplike/setlike",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ interface Foo2 : Foo1 {
+ void clear();
+ };
+ """, mapRWMembers, numProductions=2)
+
+ shouldFail("Inheritance of unforgeable attribute collision with child maplike/setlike",
+ """
+ interface Foo1 {
+ [Unforgeable]
+ attribute double size;
+ };
+ interface Foo2 : Foo1 {
+ maplike<long, long>;
+ };
+ """)
+
+ shouldFail("Inheritance of multi-level unforgeable attribute collision with child maplike/setlike",
+ """
+ interface Foo1 {
+ [Unforgeable]
+ attribute double size;
+ };
+ interface Foo2 : Foo1 {
+ };
+ interface Foo3 : Foo2 {
+ maplike<long, long>;
+ };
+ """)
+
+ shouldPass("Implemented interface with readonly allowable overrides",
+ """
+ interface Foo1 {
+ readonly setlike<long>;
+ readonly attribute boolean clear;
+ };
+ """, setROMembers + [("clear", WebIDL.IDLAttribute)])
+
+ shouldPass("JS Implemented read-only interface with readonly allowable overrides",
+ """
+ [JSImplementation="@mozilla.org/dom/test-interface-js-maplike;1",
+ Constructor()]
+ interface Foo1 {
+ readonly setlike<long>;
+ readonly attribute boolean clear;
+ };
+ """, setROChromeMembers + [("clear", WebIDL.IDLAttribute)])
+
+ shouldFail("JS Implemented read-write interface with non-readwrite allowable overrides",
+ """
+ [JSImplementation="@mozilla.org/dom/test-interface-js-maplike;1",
+ Constructor()]
+ interface Foo1 {
+ setlike<long>;
+ readonly attribute boolean clear;
+ };
+ """)
+
+ r = shouldPass("Check proper override of clear/delete/set",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ long clear(long a, long b, double c, double d);
+ long set(long a, long b, double c, double d);
+ long delete(long a, long b, double c, double d);
+ };
+ """, mapRWMembers)
+
+ for m in r[0].members:
+ if m.identifier.name in ["clear", "set", "delete"]:
+ harness.ok(m.isMethod(), "%s should be a method" % m.identifier.name)
+ harness.check(m.maxArgCount, 4, "%s should have 4 arguments" % m.identifier.name)
+ harness.ok(not m.isMaplikeOrSetlikeOrIterableMethod(),
+ "%s should not be a maplike/setlike function" % m.identifier.name)