aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/codegen/parser
diff options
context:
space:
mode:
authorAgostonSzepessy <agszepp@gmail.com>2016-03-06 18:47:35 -0500
committerAgostonSzepessy <agszepp@gmail.com>2016-03-22 23:13:30 -0400
commitd3528ffce4092e0b28b9494f96555368bf8945b9 (patch)
treeaf13c09d65a3a61e6131b96e4aa45e6bab27905b /components/script/dom/bindings/codegen/parser
parent003fdd41769652188a5954e6499f3cb44eef6b10 (diff)
downloadservo-d3528ffce4092e0b28b9494f96555368bf8945b9.tar.gz
servo-d3528ffce4092e0b28b9494f96555368bf8945b9.zip
components/script/dom/bindings/codegen/parser/update.sh now downloads all
the latest *.py tests from https://hg.mozilla.org/mozilla-central/archive/tip.tar.gz/dom/bindings/parser/tests/
Diffstat (limited to 'components/script/dom/bindings/codegen/parser')
-rw-r--r--components/script/dom/bindings/codegen/parser/WebIDL.py140
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_array.py18
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_bytestring.py72
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_callback.py2
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py47
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_const.py54
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py8
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_date.py15
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_dictionary.py367
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py146
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_empty_sequence_default_value.py45
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_enum.py12
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_exposed_extended_attribute.py222
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_float_types.py125
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_global_extended_attr.py122
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_interface.py217
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_interface_maplikesetlikeiterable.py594
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_method.py47
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_mozmap.py39
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_overload.py15
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_promise.py63
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_prototype_ident.py80
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_putForwards.py107
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_replaceable.py58
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_stringifier.py46
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_unforgeable.py253
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_union.py2
-rw-r--r--components/script/dom/bindings/codegen/parser/tests/test_usvstring.py36
-rwxr-xr-xcomponents/script/dom/bindings/codegen/parser/update.sh6
29 files changed, 2899 insertions, 59 deletions
diff --git a/components/script/dom/bindings/codegen/parser/WebIDL.py b/components/script/dom/bindings/codegen/parser/WebIDL.py
index e653ad7e9ac..09fab2e7a74 100644
--- a/components/script/dom/bindings/codegen/parser/WebIDL.py
+++ b/components/script/dom/bindings/codegen/parser/WebIDL.py
@@ -508,6 +508,9 @@ class IDLExposureMixins():
def isExposedInAnyWorker(self):
return len(self.getWorkerExposureSet()) > 0
+ def isExposedInWorkerDebugger(self):
+ return len(self.getWorkerDebuggerExposureSet()) > 0
+
def isExposedInSystemGlobals(self):
return 'BackstagePass' in self.exposureSet
@@ -527,6 +530,10 @@ class IDLExposureMixins():
workerScopes = self._globalScope.globalNameMapping["Worker"]
return workerScopes.intersection(self.exposureSet)
+ def getWorkerDebuggerExposureSet(self):
+ workerDebuggerScopes = self._globalScope.globalNameMapping["WorkerDebugger"]
+ return workerDebuggerScopes.intersection(self.exposureSet)
+
class IDLExternalInterface(IDLObjectWithIdentifier, IDLExposureMixins):
def __init__(self, location, parentScope, identifier):
@@ -978,7 +985,9 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
(member.getExtendedAttribute("StoreInSlot") or
member.getExtendedAttribute("Cached"))) or
member.isMaplikeOrSetlike()):
- member.slotIndex = self.totalMembersInSlots
+ if member.slotIndices is None:
+ member.slotIndices = dict()
+ member.slotIndices[self.identifier.name] = self.totalMembersInSlots
self.totalMembersInSlots += 1
if member.getExtendedAttribute("StoreInSlot"):
self._ownMembersInSlots += 1
@@ -1102,7 +1111,7 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
def validate(self):
# We don't support consequential unforgeable interfaces. Need to check
- # this here, becaue in finish() an interface might not know yet that
+ # this here, because in finish() an interface might not know yet that
# it's consequential.
if self.getExtendedAttribute("Unforgeable") and self.isConsequential():
raise WebIDLError(
@@ -1121,6 +1130,8 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
self.identifier.name,
locations)
+ indexedGetter = None
+ hasLengthAttribute = False
for member in self.members:
member.validate()
@@ -1131,8 +1142,13 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
[self.location, member.location])
# Check that PutForwards refers to another attribute and that no
- # cycles exist in forwarded assignments.
+ # cycles exist in forwarded assignments. Also check for a
+ # integer-typed "length" attribute.
if member.isAttr():
+ if (member.identifier.name == "length" and
+ member.type.isInteger()):
+ hasLengthAttribute = True
+
iface = self
attr = member
putForwards = attr.getExtendedAttribute("PutForwards")
@@ -1170,8 +1186,11 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
putForwards = attr.getExtendedAttribute("PutForwards")
# Check that the name of an [Alias] doesn't conflict with an
- # interface member.
+ # interface member and whether we support indexed properties.
if member.isMethod():
+ if member.isGetter() and member.isIndexed():
+ indexedGetter = member
+
for alias in member.aliases:
if self.isOnGlobalProtoChain():
raise WebIDLError("[Alias] must not be used on a "
@@ -1232,6 +1251,35 @@ class IDLInterface(IDLObjectWithScope, IDLExposureMixins):
"exposed conditionally",
[self.location])
+ # Value iterators are only allowed on interfaces with indexed getters,
+ # and pair iterators are only allowed on interfaces without indexed
+ # getters.
+ if self.isIterable():
+ iterableDecl = self.maplikeOrSetlikeOrIterable
+ if iterableDecl.isValueIterator():
+ if not indexedGetter:
+ raise WebIDLError("Interface with value iterator does not "
+ "support indexed properties",
+ [self.location])
+
+ if iterableDecl.valueType != indexedGetter.signatures()[0][0]:
+ raise WebIDLError("Iterable type does not match indexed "
+ "getter type",
+ [iterableDecl.location,
+ indexedGetter.location])
+
+ if not hasLengthAttribute:
+ raise WebIDLError('Interface with value iterator does not '
+ 'have an integer-typed "length" attribute',
+ [self.location])
+ else:
+ assert iterableDecl.isPairIterator()
+ if indexedGetter:
+ raise WebIDLError("Interface with pair iterator supports "
+ "indexed properties",
+ [self.location, iterableDecl.location,
+ indexedGetter.location])
+
def isInterface(self):
return True
@@ -3432,7 +3480,10 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
def __init__(self, location, identifier, ifaceType, keyType, valueType, ifaceKind):
IDLInterfaceMember.__init__(self, location, identifier, ifaceKind)
- assert isinstance(keyType, IDLType)
+ if keyType is not None:
+ assert isinstance(keyType, IDLType)
+ else:
+ assert valueType is not None
assert ifaceType in ['maplike', 'setlike', 'iterable']
if valueType is not None:
assert isinstance(valueType, IDLType)
@@ -3451,6 +3502,9 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
def isIterable(self):
return self.maplikeOrSetlikeOrIterableType == "iterable"
+ def hasKeyType(self):
+ return self.keyType is not None
+
def hasValueType(self):
return self.valueType is not None
@@ -3475,7 +3529,8 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
[self.location, member.location])
def addMethod(self, name, members, allowExistingOperations, returnType, args=[],
- chromeOnly=False, isPure=False, affectsNothing=False, newObject=False):
+ chromeOnly=False, isPure=False, affectsNothing=False, newObject=False,
+ isIteratorAlias=False):
"""
Create an IDLMethod based on the parameters passed in.
@@ -3535,16 +3590,20 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
if newObject:
method.addExtendedAttributes(
[IDLExtendedAttribute(self.location, ("NewObject",))])
+ if isIteratorAlias:
+ method.addExtendedAttributes(
+ [IDLExtendedAttribute(self.location, ("Alias", "@@iterator"))])
members.append(method)
def resolve(self, parentScope):
- self.keyType.resolveType(parentScope)
+ if self.keyType:
+ self.keyType.resolveType(parentScope)
if self.valueType:
self.valueType.resolveType(parentScope)
def finish(self, scope):
IDLInterfaceMember.finish(self, scope)
- if not self.keyType.isComplete():
+ if self.keyType and not self.keyType.isComplete():
t = self.keyType.complete(scope)
assert not isinstance(t, IDLUnresolvedType)
@@ -3566,9 +3625,23 @@ class IDLMaplikeOrSetlikeOrIterableBase(IDLInterfaceMember):
IDLInterfaceMember.handleExtendedAttribute(self, attr)
def _getDependentObjects(self):
+ deps = set()
+ if self.keyType:
+ deps.add(self.keyType)
if self.valueType:
- return set([self.keyType, self.valueType])
- return set([self.keyType])
+ deps.add(self.valueType)
+ return deps
+
+ def getForEachArguments(self):
+ return [IDLArgument(self.location,
+ IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
+ "callback"),
+ BuiltinTypes[IDLBuiltinType.Types.object]),
+ IDLArgument(self.location,
+ IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
+ "thisArg"),
+ BuiltinTypes[IDLBuiltinType.Types.any],
+ optional=True)]
# Iterable adds ES6 iterator style functions and traits
# (keys/values/entries/@@iterator) to an interface.
@@ -3589,9 +3662,15 @@ class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase):
we generate our functions as if they were part of the interface
specification during parsing.
"""
+ # We only need to add entries/keys/values here if we're a pair iterator.
+ # Value iterators just copy these from %ArrayPrototype% instead.
+ if not self.isPairIterator():
+ return
+
# object entries()
self.addMethod("entries", members, False, self.iteratorType,
- affectsNothing=True, newObject=True)
+ affectsNothing=True, newObject=True,
+ isIteratorAlias=True)
# object keys()
self.addMethod("keys", members, False, self.iteratorType,
affectsNothing=True, newObject=True)
@@ -3599,6 +3678,17 @@ class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase):
self.addMethod("values", members, False, self.iteratorType,
affectsNothing=True, newObject=True)
+ # void forEach(callback(valueType, keyType), optional any thisArg)
+ self.addMethod("forEach", members, False,
+ BuiltinTypes[IDLBuiltinType.Types.void],
+ self.getForEachArguments())
+
+ def isValueIterator(self):
+ return not self.isPairIterator()
+
+ def isPairIterator(self):
+ return self.hasKeyType()
+
# MaplikeOrSetlike adds ES6 map-or-set-like traits to an interface.
class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
@@ -3607,7 +3697,7 @@ class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
IDLMaplikeOrSetlikeOrIterableBase.__init__(self, location, identifier, maplikeOrSetlikeType,
keyType, valueType, IDLInterfaceMember.Tags.MaplikeOrSetlike)
self.readonly = readonly
- self.slotIndex = None
+ self.slotIndices = None
# When generating JSAPI access code, we need to know the backing object
# type prefix to create the correct function. Generate here for reuse.
@@ -3635,26 +3725,17 @@ class IDLMaplikeOrSetlike(IDLMaplikeOrSetlikeOrIterableBase):
# object entries()
self.addMethod("entries", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
- affectsNothing=True)
+ affectsNothing=True, isIteratorAlias=self.isMaplike())
# object keys()
self.addMethod("keys", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
affectsNothing=True)
# object values()
self.addMethod("values", members, False, BuiltinTypes[IDLBuiltinType.Types.object],
- affectsNothing=True)
+ affectsNothing=True, isIteratorAlias=self.isSetlike())
# void forEach(callback(valueType, keyType), thisVal)
- foreachArguments = [IDLArgument(self.location,
- IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
- "callback"),
- BuiltinTypes[IDLBuiltinType.Types.object]),
- IDLArgument(self.location,
- IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"),
- "thisArg"),
- BuiltinTypes[IDLBuiltinType.Types.any],
- optional=True)]
self.addMethod("forEach", members, False, BuiltinTypes[IDLBuiltinType.Types.void],
- foreachArguments)
+ self.getForEachArguments())
def getKeyArg():
return IDLArgument(self.location,
@@ -3801,7 +3882,7 @@ class IDLAttribute(IDLInterfaceMember):
self.stringifier = stringifier
self.enforceRange = False
self.clamp = False
- self.slotIndex = None
+ self.slotIndices = None
assert maplikeOrSetlike is None or isinstance(maplikeOrSetlike, IDLMaplikeOrSetlike)
self.maplikeOrSetlike = maplikeOrSetlike
self.dependsOn = "Everything"
@@ -5444,10 +5525,13 @@ class Parser(Tokenizer):
location = self.getLocation(p, 2)
identifier = IDLUnresolvedIdentifier(location, "__iterable",
allowDoubleUnderscore=True)
- keyType = p[3]
- valueType = None
if (len(p) > 6):
+ keyType = p[3]
valueType = p[5]
+ else:
+ keyType = None
+ valueType = p[3]
+
p[0] = IDLIterable(location, identifier, keyType, valueType, self.globalScope())
def p_Setlike(self, p):
@@ -6518,7 +6602,7 @@ class Parser(Tokenizer):
if isinstance(m, IDLIterable):
iterable = m
break
- if iterable:
+ if iterable and iterable.isPairIterator():
def simpleExtendedAttr(str):
return IDLExtendedAttribute(iface.location, (str, ))
nextMethod = IDLMethod(
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_array.py b/components/script/dom/bindings/codegen/parser/tests/test_array.py
new file mode 100644
index 00000000000..8f9e9c96854
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_array.py
@@ -0,0 +1,18 @@
+def WebIDLTest(parser, harness):
+ threw = False
+ try:
+ parser.parse("""
+ dictionary Foo {
+ short a;
+ };
+
+ dictionary Foo1 {
+ Foo[] b;
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "Array must not contain dictionary "
+ "as element type.")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_bytestring.py b/components/script/dom/bindings/codegen/parser/tests/test_bytestring.py
new file mode 100644
index 00000000000..d73455f8812
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_bytestring.py
@@ -0,0 +1,72 @@
+# -*- coding: UTF-8 -*-
+
+import WebIDL
+
+def WebIDLTest(parser, harness):
+ parser.parse("""
+ interface TestByteString {
+ attribute ByteString bs;
+ attribute DOMString ds;
+ };
+ """)
+
+ results = parser.finish();
+
+ harness.ok(True, "TestByteString 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(), "::TestByteString", "Interface has the right QName")
+ harness.check(iface.identifier.name, "TestByteString", "Interface has the right name")
+ harness.check(iface.parent, None, "Interface has no parent")
+
+ members = iface.members
+ harness.check(len(members), 2, "Should be two productions")
+
+ attr = members[0]
+ harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute")
+ harness.check(attr.identifier.QName(), "::TestByteString::bs", "Attr has correct QName")
+ harness.check(attr.identifier.name, "bs", "Attr has correct name")
+ harness.check(str(attr.type), "ByteString", "Attr type is the correct name")
+ harness.ok(attr.type.isByteString(), "Should be ByteString type")
+ harness.ok(attr.type.isString(), "Should be String collective type")
+ harness.ok(not attr.type.isDOMString(), "Should be not be DOMString type")
+
+ # now check we haven't broken DOMStrings in the process.
+ attr = members[1]
+ harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute")
+ harness.check(attr.identifier.QName(), "::TestByteString::ds", "Attr has correct QName")
+ harness.check(attr.identifier.name, "ds", "Attr has correct name")
+ harness.check(str(attr.type), "String", "Attr type is the correct name")
+ harness.ok(attr.type.isDOMString(), "Should be DOMString type")
+ harness.ok(attr.type.isString(), "Should be String collective type")
+ harness.ok(not attr.type.isByteString(), "Should be not be ByteString type")
+
+ # Cannot represent constant ByteString in IDL.
+ threw = False
+ try:
+ parser.parse("""
+ interface ConstByteString {
+ const ByteString foo = "hello"
+ };
+ """)
+ except WebIDL.WebIDLError:
+ threw = True
+ harness.ok(threw, "Should have thrown a WebIDL error")
+
+ # Cannot have optional ByteStrings with default values
+ threw = False
+ try:
+ parser.parse("""
+ interface OptionalByteString {
+ void passByteString(optional ByteString arg = "hello");
+ };
+ """)
+ results2 = parser.finish();
+ except WebIDL.WebIDLError:
+ threw = True
+
+ harness.ok(threw, "Should have thrown a WebIDL error")
+
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_callback.py b/components/script/dom/bindings/codegen/parser/tests/test_callback.py
index 267d27dc087..4dfda1c3c76 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_callback.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_callback.py
@@ -12,7 +12,7 @@ def WebIDLTest(parser, harness):
results = parser.finish()
harness.ok(True, "TestCallback interface parsed without error.")
- harness.check(len(results), 2, "Should be one production.")
+ harness.check(len(results), 2, "Should be two productions.")
iface = results[0]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py b/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py
index 80896ca1edb..e4789dae168 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_callback_interface.py
@@ -45,3 +45,50 @@ def WebIDLTest(parser, harness):
harness.ok(threw, "Should not allow callback parent of non-callback interface")
+ parser = parser.reset()
+ parser.parse("""
+ callback interface TestCallbackInterface1 {
+ void foo();
+ };
+ callback interface TestCallbackInterface2 {
+ void foo(DOMString arg);
+ void foo(TestCallbackInterface1 arg);
+ };
+ callback interface TestCallbackInterface3 {
+ void foo(DOMString arg);
+ void foo(TestCallbackInterface1 arg);
+ static void bar();
+ };
+ callback interface TestCallbackInterface4 {
+ void foo(DOMString arg);
+ void foo(TestCallbackInterface1 arg);
+ static void bar();
+ const long baz = 5;
+ };
+ callback interface TestCallbackInterface5 {
+ static attribute boolean bool;
+ void foo();
+ };
+ callback interface TestCallbackInterface6 {
+ void foo(DOMString arg);
+ void foo(TestCallbackInterface1 arg);
+ void bar();
+ };
+ callback interface TestCallbackInterface7 {
+ static attribute boolean bool;
+ };
+ callback interface TestCallbackInterface8 {
+ attribute boolean bool;
+ };
+ callback interface TestCallbackInterface9 : TestCallbackInterface1 {
+ void foo();
+ };
+ callback interface TestCallbackInterface10 : TestCallbackInterface1 {
+ void bar();
+ };
+ """)
+ results = parser.finish()
+ for (i, iface) in enumerate(results):
+ harness.check(iface.isSingleOperationInterface(), i < 4,
+ "Interface %s should be a single operation interface" %
+ iface.identifier.name)
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_const.py b/components/script/dom/bindings/codegen/parser/tests/test_const.py
index 12f411363fb..80b6fb0e9c8 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_const.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_const.py
@@ -1,5 +1,30 @@
import WebIDL
+expected = [
+ ("::TestConsts::zero", "zero", "Byte", 0),
+ ("::TestConsts::b", "b", "Byte", -1),
+ ("::TestConsts::o", "o", "Octet", 2),
+ ("::TestConsts::s", "s", "Short", -3),
+ ("::TestConsts::us", "us", "UnsignedShort", 4),
+ ("::TestConsts::l", "l", "Long", -5),
+ ("::TestConsts::ul", "ul", "UnsignedLong", 6),
+ ("::TestConsts::ull", "ull", "UnsignedLongLong", 7),
+ ("::TestConsts::ll", "ll", "LongLong", -8),
+ ("::TestConsts::t", "t", "Boolean", True),
+ ("::TestConsts::f", "f", "Boolean", False),
+ ("::TestConsts::n", "n", "BooleanOrNull", None),
+ ("::TestConsts::nt", "nt", "BooleanOrNull", True),
+ ("::TestConsts::nf", "nf", "BooleanOrNull", False),
+ ("::TestConsts::fl", "fl", "Float", 0.2),
+ ("::TestConsts::db", "db", "Double", 0.2),
+ ("::TestConsts::ufl", "ufl", "UnrestrictedFloat", 0.2),
+ ("::TestConsts::udb", "udb", "UnrestrictedDouble", 0.2),
+ ("::TestConsts::fli", "fli", "Float", 2),
+ ("::TestConsts::dbi", "dbi", "Double", 2),
+ ("::TestConsts::ufli", "ufli", "UnrestrictedFloat", 2),
+ ("::TestConsts::udbi", "udbi", "UnrestrictedDouble", 2),
+]
+
def WebIDLTest(parser, harness):
parser.parse("""
interface TestConsts {
@@ -17,6 +42,14 @@ def WebIDLTest(parser, harness):
const boolean? n = null;
const boolean? nt = true;
const boolean? nf = false;
+ const float fl = 0.2;
+ const double db = 0.2;
+ const unrestricted float ufl = 0.2;
+ const unrestricted double udb = 0.2;
+ const float fli = 2;
+ const double dbi = 2;
+ const unrestricted float ufli = 2;
+ const unrestricted double udbi = 2;
};
""")
@@ -29,11 +62,9 @@ def WebIDLTest(parser, harness):
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestConsts", "Interface has the right QName")
harness.check(iface.identifier.name, "TestConsts", "Interface has the right name")
- harness.check(len(iface.members), 14, "Expect 14 members")
-
- consts = iface.members
+ harness.check(len(iface.members), len(expected), "Expect %s members" % len(expected))
- def checkConst(const, QName, name, type, value):
+ for (const, (QName, name, type, value)) in zip(iface.members, expected):
harness.ok(isinstance(const, WebIDL.IDLConst),
"Should be an IDLConst")
harness.ok(const.isConst(), "Const is a const")
@@ -47,18 +78,3 @@ def WebIDLTest(parser, harness):
"Const's value has the same type as the type")
harness.check(const.value.value, value, "Const value has the right value.")
- checkConst(consts[0], "::TestConsts::zero", "zero", "Byte", 0)
- checkConst(consts[1], "::TestConsts::b", "b", "Byte", -1)
- checkConst(consts[2], "::TestConsts::o", "o", "Octet", 2)
- checkConst(consts[3], "::TestConsts::s", "s", "Short", -3)
- checkConst(consts[4], "::TestConsts::us", "us", "UnsignedShort", 4)
- checkConst(consts[5], "::TestConsts::l", "l", "Long", -5)
- checkConst(consts[6], "::TestConsts::ul", "ul", "UnsignedLong", 6)
- checkConst(consts[7], "::TestConsts::ull", "ull", "UnsignedLongLong", 7)
- checkConst(consts[8], "::TestConsts::ll", "ll", "LongLong", -8)
- checkConst(consts[9], "::TestConsts::t", "t", "Boolean", True)
- checkConst(consts[10], "::TestConsts::f", "f", "Boolean", False)
- checkConst(consts[11], "::TestConsts::n", "n", "BooleanOrNull", None)
- checkConst(consts[12], "::TestConsts::nt", "nt", "BooleanOrNull", True)
- checkConst(consts[13], "::TestConsts::nf", "nf", "BooleanOrNull", False)
-
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py b/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py
index 192c5f6f97b..2b09ae71e69 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_constructor_no_interface_object.py
@@ -26,3 +26,11 @@ def WebIDLTest(parser, harness):
threw = True
harness.ok(threw, "Should have thrown.")
+
+ parser = parser.reset()
+
+ parser.parse("""
+ [NoInterfaceObject, NamedConstructor=FooBar]
+ interface TestNamedConstructorNoInterfaceObject {
+ };
+ """)
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_date.py b/components/script/dom/bindings/codegen/parser/tests/test_date.py
new file mode 100644
index 00000000000..2bdfc95e14f
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_date.py
@@ -0,0 +1,15 @@
+def WebIDLTest(parser, harness):
+ parser.parse("""
+ interface WithDates {
+ attribute Date foo;
+ void bar(Date arg);
+ void baz(sequence<Date> arg);
+ };
+ """)
+
+ results = parser.finish()
+ harness.ok(results[0].members[0].type.isDate(), "Should have Date")
+ harness.ok(results[0].members[1].signatures()[0][1][0].type.isDate(),
+ "Should have Date argument")
+ harness.ok(not results[0].members[2].signatures()[0][1][0].type.isDate(),
+ "Should have non-Date argument")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py b/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py
index 9ae9eb2b66f..2c0fa61239d 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_dictionary.py
@@ -113,14 +113,16 @@ def WebIDLTest(parser, harness):
try:
parser.parse("""
dictionary A {
- [TreatUndefinedAs=EmptyString] DOMString foo;
+ };
+ interface X {
+ void doFoo(A arg);
};
""")
results = parser.finish()
except:
threw = True
- harness.ok(threw, "Should not allow [TreatUndefinedAs] on dictionary members");
+ harness.ok(threw, "Trailing dictionary arg must be optional")
parser = parser.reset()
threw = False
@@ -129,14 +131,15 @@ def WebIDLTest(parser, harness):
dictionary A {
};
interface X {
- void doFoo(A arg);
+ void doFoo((A or DOMString) arg);
};
""")
results = parser.finish()
except:
threw = True
- harness.ok(threw, "Trailing dictionary arg must be optional")
+ harness.ok(threw,
+ "Trailing union arg containing a dictionary must be optional")
parser = parser.reset()
threw = False
@@ -155,6 +158,41 @@ def WebIDLTest(parser, harness):
harness.ok(threw, "Dictionary arg followed by optional arg must be optional")
parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ dictionary A {
+ };
+ interface X {
+ void doFoo(A arg1, optional long arg2, long arg3);
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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 {
+ void doFoo((A or DOMString) arg1, optional long arg2);
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw,
+ "Union arg containing dictionary followed by optional arg must "
+ "be optional")
+
+ parser = parser.reset()
parser.parse("""
dictionary A {
};
@@ -188,7 +226,7 @@ def WebIDLTest(parser, harness):
dictionary A {
};
interface X {
- void doFoo((A or long)? arg1);
+ void doFoo(optional (A or long)? arg1);
};
""")
results = parser.finish()
@@ -196,3 +234,322 @@ def WebIDLTest(parser, harness):
threw = True
harness.ok(threw, "Dictionary arg must not be in a nullable union")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ dictionary A {
+ };
+ interface X {
+ void doFoo(optional (A or long?) arg1);
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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 {
+ void doFoo(optional (long? or A) arg1);
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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();
+ };
+ """)
+ results = parser.finish()
+ harness.ok(True, "Dictionary return value can be nullable")
+
+ parser = parser.reset()
+ parser.parse("""
+ dictionary A {
+ };
+ interface X {
+ void doFoo(optional A arg);
+ };
+ """)
+ results = parser.finish()
+ harness.ok(True, "Dictionary arg should actually parse")
+
+ parser = parser.reset()
+ parser.parse("""
+ dictionary A {
+ };
+ interface X {
+ void doFoo(optional (A or DOMString) arg);
+ };
+ """)
+ results = parser.finish()
+ harness.ok(True, "Union arg containing a dictionary should actually parse")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ dictionary Foo {
+ Foo foo;
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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;
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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;
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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;
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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;
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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;
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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;
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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;
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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;
+ };
+ """)
+ results = 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;
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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;
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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;
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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;
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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;
+ };
+ """)
+ results = parser.finish()
+ except:
+ 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;
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "Only unrestricted values can be initialized to NaN")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py b/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py
index 86847800631..866816f2e0c 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_distinguishability.py
@@ -148,3 +148,149 @@ def WebIDLTest(parser, harness):
threw = True
harness.ok(threw, "Should throw when there is no distinguishing index")
+
+ # Now let's test our whole distinguishability table
+ argTypes = [ "long", "short", "long?", "short?", "boolean",
+ "boolean?", "DOMString", "ByteString", "Enum", "Enum2",
+ "Interface", "Interface?",
+ "AncestorInterface", "UnrelatedInterface",
+ "ImplementedInterface", "CallbackInterface",
+ "CallbackInterface?", "CallbackInterface2",
+ "object", "Callback", "Callback2", "optional Dict",
+ "optional Dict2", "sequence<long>", "sequence<short>",
+ "MozMap<object>", "MozMap<Dict>", "MozMap<long>",
+ "long[]", "short[]", "Date", "Date?", "any",
+ "Promise<any>", "Promise<any>?",
+ "USVString", "ArrayBuffer", "ArrayBufferView", "SharedArrayBuffer",
+ "Uint8Array", "Uint16Array" ]
+ # When we can parse Date and RegExp, we need to add them here.
+
+ # Try to categorize things a bit to keep list lengths down
+ def allBut(list1, list2):
+ return [a for a in list1 if a not in list2 and
+ (a != "any" and a != "Promise<any>" and a != "Promise<any>?")]
+ numerics = [ "long", "short", "long?", "short?" ]
+ booleans = [ "boolean", "boolean?" ]
+ primitives = numerics + booleans
+ nonNumerics = allBut(argTypes, numerics)
+ nonBooleans = allBut(argTypes, booleans)
+ strings = [ "DOMString", "ByteString", "Enum", "Enum2", "USVString" ]
+ nonStrings = allBut(argTypes, strings)
+ nonObjects = primitives + strings
+ objects = allBut(argTypes, nonObjects )
+ bufferSourceTypes = ["ArrayBuffer", "ArrayBufferView", "Uint8Array", "Uint16Array"]
+ sharedBufferSourceTypes = ["SharedArrayBuffer"]
+ interfaces = [ "Interface", "Interface?", "AncestorInterface",
+ "UnrelatedInterface", "ImplementedInterface" ] + bufferSourceTypes + sharedBufferSourceTypes
+ nullables = ["long?", "short?", "boolean?", "Interface?",
+ "CallbackInterface?", "optional Dict", "optional Dict2",
+ "Date?", "any", "Promise<any>?"]
+ dates = [ "Date", "Date?" ]
+ sequences = [ "sequence<long>", "sequence<short>" ]
+ arrays = [ "long[]", "short[]" ]
+ nonUserObjects = nonObjects + interfaces + dates + sequences
+ otherObjects = allBut(argTypes, nonUserObjects + ["object"])
+ notRelatedInterfaces = (nonObjects + ["UnrelatedInterface"] +
+ otherObjects + dates + sequences + bufferSourceTypes + sharedBufferSourceTypes)
+ mozMaps = [ "MozMap<object>", "MozMap<Dict>", "MozMap<long>" ]
+
+ # Build a representation of the distinguishability table as a dict
+ # of dicts, holding True values where needed, holes elsewhere.
+ data = dict();
+ for type in argTypes:
+ data[type] = dict()
+ def setDistinguishable(type, types):
+ for other in types:
+ data[type][other] = True
+
+ setDistinguishable("long", nonNumerics)
+ setDistinguishable("short", nonNumerics)
+ setDistinguishable("long?", allBut(nonNumerics, nullables))
+ setDistinguishable("short?", allBut(nonNumerics, nullables))
+ setDistinguishable("boolean", nonBooleans)
+ setDistinguishable("boolean?", allBut(nonBooleans, nullables))
+ setDistinguishable("DOMString", nonStrings)
+ setDistinguishable("ByteString", nonStrings)
+ setDistinguishable("USVString", nonStrings)
+ setDistinguishable("Enum", nonStrings)
+ setDistinguishable("Enum2", nonStrings)
+ setDistinguishable("Interface", notRelatedInterfaces)
+ setDistinguishable("Interface?", allBut(notRelatedInterfaces, nullables))
+ setDistinguishable("AncestorInterface", notRelatedInterfaces)
+ setDistinguishable("UnrelatedInterface",
+ allBut(argTypes, ["object", "UnrelatedInterface"]))
+ setDistinguishable("ImplementedInterface", notRelatedInterfaces)
+ setDistinguishable("CallbackInterface", nonUserObjects)
+ setDistinguishable("CallbackInterface?", allBut(nonUserObjects, nullables))
+ setDistinguishable("CallbackInterface2", nonUserObjects)
+ setDistinguishable("object", nonObjects)
+ setDistinguishable("Callback", nonUserObjects)
+ setDistinguishable("Callback2", nonUserObjects)
+ setDistinguishable("optional Dict", allBut(nonUserObjects, nullables))
+ setDistinguishable("optional Dict2", allBut(nonUserObjects, nullables))
+ setDistinguishable("sequence<long>",
+ allBut(argTypes, sequences + arrays + ["object"]))
+ setDistinguishable("sequence<short>",
+ allBut(argTypes, sequences + arrays + ["object"]))
+ setDistinguishable("MozMap<object>", nonUserObjects)
+ setDistinguishable("MozMap<Dict>", nonUserObjects)
+ setDistinguishable("MozMap<long>", nonUserObjects)
+ setDistinguishable("long[]", allBut(nonUserObjects, sequences))
+ setDistinguishable("short[]", allBut(nonUserObjects, sequences))
+ setDistinguishable("Date", allBut(argTypes, dates + ["object"]))
+ setDistinguishable("Date?", allBut(argTypes, dates + nullables + ["object"]))
+ setDistinguishable("any", [])
+ setDistinguishable("Promise<any>", [])
+ setDistinguishable("Promise<any>?", [])
+ setDistinguishable("ArrayBuffer", allBut(argTypes, ["ArrayBuffer", "object"]))
+ setDistinguishable("ArrayBufferView", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "Uint16Array", "object"]))
+ setDistinguishable("Uint8Array", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "object"]))
+ setDistinguishable("Uint16Array", allBut(argTypes, ["ArrayBufferView", "Uint16Array", "object"]))
+ setDistinguishable("SharedArrayBuffer", allBut(argTypes, ["SharedArrayBuffer", "object"]))
+
+ def areDistinguishable(type1, type2):
+ return data[type1].get(type2, False)
+
+ def checkDistinguishability(parser, type1, type2):
+ idlTemplate = """
+ enum Enum { "a", "b" };
+ enum Enum2 { "c", "d" };
+ interface Interface : AncestorInterface {};
+ interface AncestorInterface {};
+ interface UnrelatedInterface {};
+ interface ImplementedInterface {};
+ Interface implements ImplementedInterface;
+ callback interface CallbackInterface {};
+ callback interface CallbackInterface2 {};
+ callback Callback = any();
+ callback Callback2 = long(short arg);
+ dictionary Dict {};
+ dictionary Dict2 {};
+ interface _Promise {};
+ interface TestInterface {%s
+ };
+ """
+ methodTemplate = """
+ void myMethod(%s arg);"""
+ methods = (methodTemplate % type1) + (methodTemplate % type2)
+ idl = idlTemplate % methods
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse(idl)
+ results = parser.finish()
+ except:
+ threw = True
+
+ if areDistinguishable(type1, type2):
+ harness.ok(not threw,
+ "Should not throw for '%s' and '%s' because they are distinguishable" % (type1, type2))
+ else:
+ harness.ok(threw,
+ "Should throw for '%s' and '%s' because they are not distinguishable" % (type1, type2))
+
+ # Enumerate over everything in both orders, since order matters in
+ # terms of our implementation of distinguishability checks
+ for type1 in argTypes:
+ for type2 in argTypes:
+ checkDistinguishability(parser, type1, type2)
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_empty_sequence_default_value.py b/components/script/dom/bindings/codegen/parser/tests/test_empty_sequence_default_value.py
new file mode 100644
index 00000000000..350ae72f022
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_empty_sequence_default_value.py
@@ -0,0 +1,45 @@
+import WebIDL
+
+def WebIDLTest(parser, harness):
+ threw = False
+ try:
+ parser.parse("""
+ interface X {
+ const sequence<long> foo = [];
+ };
+ """)
+
+ results = parser.finish()
+ except Exception,x:
+ threw = True
+
+ harness.ok(threw, "Constant cannot have [] as a default value")
+
+ parser = parser.reset()
+
+ parser.parse("""
+ interface X {
+ void foo(optional sequence<long> arg = []);
+ };
+ """)
+ results = parser.finish();
+
+ harness.ok(isinstance(
+ results[0].members[0].signatures()[0][1][0].defaultValue,
+ WebIDL.IDLEmptySequenceValue),
+ "Should have IDLEmptySequenceValue as default value of argument")
+
+ parser = parser.reset()
+
+ parser.parse("""
+ dictionary X {
+ sequence<long> foo = [];
+ };
+ """)
+ results = parser.finish();
+
+ harness.ok(isinstance(results[0].members[0].defaultValue,
+ WebIDL.IDLEmptySequenceValue),
+ "Should have IDLEmptySequenceValue as default value of "
+ "dictionary member")
+
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_enum.py b/components/script/dom/bindings/codegen/parser/tests/test_enum.py
index 69a6932062d..86228939181 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_enum.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_enum.py
@@ -79,3 +79,15 @@ def WebIDLTest(parser, harness):
threw = True
harness.ok(threw, "Should not allow a bogus default value for an enum")
+
+ # Now reset our parser
+ parser = parser.reset()
+ parser.parse("""
+ enum Enum {
+ "a",
+ "b",
+ "c",
+ };
+ """)
+ results = parser.finish()
+ harness.check(len(results), 1, "Should allow trailing comma in enum")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_exposed_extended_attribute.py b/components/script/dom/bindings/codegen/parser/tests/test_exposed_extended_attribute.py
new file mode 100644
index 00000000000..48957098bfe
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_exposed_extended_attribute.py
@@ -0,0 +1,222 @@
+import WebIDL
+
+def WebIDLTest(parser, harness):
+ parser.parse("""
+ [PrimaryGlobal] interface Foo {};
+ [Global=(Bar1,Bar2)] interface Bar {};
+ [Global=Baz2] interface Baz {};
+
+ [Exposed=(Foo,Bar1)]
+ interface Iface {
+ void method1();
+
+ [Exposed=Bar1]
+ readonly attribute any attr;
+ };
+
+ [Exposed=Foo]
+ partial interface Iface {
+ void method2();
+ };
+ """)
+
+ results = parser.finish()
+
+ harness.check(len(results), 5, "Should know about five things");
+ iface = results[3]
+ harness.ok(isinstance(iface, WebIDL.IDLInterface),
+ "Should have an interface here");
+ members = iface.members
+ harness.check(len(members), 3, "Should have three members")
+
+ harness.ok(members[0].exposureSet == set(["Foo", "Bar"]),
+ "method1 should have the right exposure set")
+ harness.ok(members[0]._exposureGlobalNames == set(["Foo", "Bar1"]),
+ "method1 should have the right exposure global names")
+
+ harness.ok(members[1].exposureSet == set(["Bar"]),
+ "attr should have the right exposure set")
+ harness.ok(members[1]._exposureGlobalNames == set(["Bar1"]),
+ "attr should have the right exposure global names")
+
+ harness.ok(members[2].exposureSet == set(["Foo"]),
+ "method2 should have the right exposure set")
+ harness.ok(members[2]._exposureGlobalNames == set(["Foo"]),
+ "method2 should have the right exposure global names")
+
+ harness.ok(iface.exposureSet == set(["Foo", "Bar"]),
+ "Iface should have the right exposure set")
+ harness.ok(iface._exposureGlobalNames == set(["Foo", "Bar1"]),
+ "Iface should have the right exposure global names")
+
+ parser = parser.reset()
+ parser.parse("""
+ [PrimaryGlobal] interface Foo {};
+ [Global=(Bar1,Bar2)] interface Bar {};
+ [Global=Baz2] interface Baz {};
+
+ interface Iface2 {
+ void method3();
+ };
+ """)
+ results = parser.finish()
+
+ harness.check(len(results), 4, "Should know about four things");
+ iface = results[3]
+ harness.ok(isinstance(iface, WebIDL.IDLInterface),
+ "Should have an interface here");
+ members = iface.members
+ harness.check(len(members), 1, "Should have one member")
+
+ harness.ok(members[0].exposureSet == set(["Foo"]),
+ "method3 should have the right exposure set")
+ harness.ok(members[0]._exposureGlobalNames == set(["Foo"]),
+ "method3 should have the right exposure global names")
+
+ harness.ok(iface.exposureSet == set(["Foo"]),
+ "Iface2 should have the right exposure set")
+ harness.ok(iface._exposureGlobalNames == set(["Foo"]),
+ "Iface2 should have the right exposure global names")
+
+ parser = parser.reset()
+ parser.parse("""
+ [PrimaryGlobal] interface Foo {};
+ [Global=(Bar1,Bar2)] interface Bar {};
+ [Global=Baz2] interface Baz {};
+
+ [Exposed=Foo]
+ interface Iface3 {
+ void method4();
+ };
+
+ [Exposed=(Foo,Bar1)]
+ interface Mixin {
+ void method5();
+ };
+
+ Iface3 implements Mixin;
+ """)
+ results = parser.finish()
+ harness.check(len(results), 6, "Should know about six things");
+ iface = results[3]
+ harness.ok(isinstance(iface, WebIDL.IDLInterface),
+ "Should have an interface here");
+ members = iface.members
+ harness.check(len(members), 2, "Should have two members")
+
+ harness.ok(members[0].exposureSet == set(["Foo"]),
+ "method4 should have the right exposure set")
+ harness.ok(members[0]._exposureGlobalNames == set(["Foo"]),
+ "method4 should have the right exposure global names")
+
+ harness.ok(members[1].exposureSet == set(["Foo", "Bar"]),
+ "method5 should have the right exposure set")
+ harness.ok(members[1]._exposureGlobalNames == set(["Foo", "Bar1"]),
+ "method5 should have the right exposure global names")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ [Exposed=Foo]
+ interface Bar {
+ };
+ """)
+
+ results = parser.finish()
+ except Exception,x:
+ threw = True
+
+ harness.ok(threw, "Should have thrown on invalid Exposed value on interface.")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface Bar {
+ [Exposed=Foo]
+ readonly attribute bool attr;
+ };
+ """)
+
+ results = parser.finish()
+ except Exception,x:
+ threw = True
+
+ harness.ok(threw, "Should have thrown on invalid Exposed value on attribute.")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface Bar {
+ [Exposed=Foo]
+ void operation();
+ };
+ """)
+
+ results = parser.finish()
+ except Exception,x:
+ threw = True
+
+ harness.ok(threw, "Should have thrown on invalid Exposed value on operation.")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface Bar {
+ [Exposed=Foo]
+ const long constant = 5;
+ };
+ """)
+
+ results = parser.finish()
+ except Exception,x:
+ threw = True
+
+ harness.ok(threw, "Should have thrown on invalid Exposed value on constant.")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ [Global] interface Foo {};
+ [Global] interface Bar {};
+
+ [Exposed=Foo]
+ interface Baz {
+ [Exposed=Bar]
+ void method();
+ };
+ """)
+
+ results = parser.finish()
+ except Exception,x:
+ threw = True
+
+ harness.ok(threw, "Should have thrown on member exposed where its interface is not.")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ [Global] interface Foo {};
+ [Global] interface Bar {};
+
+ [Exposed=Foo]
+ interface Baz {
+ void method();
+ };
+
+ [Exposed=Bar]
+ interface Mixin {};
+
+ Baz implements Mixin;
+ """)
+
+ results = parser.finish()
+ except Exception,x:
+ threw = True
+
+ harness.ok(threw, "Should have thrown on LHS of implements being exposed where RHS is not.")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_float_types.py b/components/script/dom/bindings/codegen/parser/tests/test_float_types.py
new file mode 100644
index 00000000000..718f09c114b
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_float_types.py
@@ -0,0 +1,125 @@
+import WebIDL
+
+def WebIDLTest(parser, harness):
+ parser.parse("""
+ typedef float myFloat;
+ typedef unrestricted float myUnrestrictedFloat;
+ interface FloatTypes {
+ attribute float f;
+ attribute unrestricted float uf;
+ attribute double d;
+ attribute unrestricted double ud;
+ [LenientFloat]
+ attribute float lf;
+ [LenientFloat]
+ attribute double ld;
+
+ void m1(float arg1, double arg2, float? arg3, double? arg4,
+ myFloat arg5, unrestricted float arg6,
+ unrestricted double arg7, unrestricted float? arg8,
+ unrestricted double? arg9, myUnrestrictedFloat arg10);
+ [LenientFloat]
+ void m2(float arg1, double arg2, float? arg3, double? arg4,
+ myFloat arg5, unrestricted float arg6,
+ unrestricted double arg7, unrestricted float? arg8,
+ unrestricted double? arg9, myUnrestrictedFloat arg10);
+ [LenientFloat]
+ void m3(float arg);
+ [LenientFloat]
+ void m4(double arg);
+ [LenientFloat]
+ void m5((float or FloatTypes) arg);
+ [LenientFloat]
+ void m6(sequence<float> arg);
+ };
+ """)
+
+ results = parser.finish()
+
+ harness.check(len(results), 3, "Should be two typedefs and one interface.")
+ iface = results[2]
+ harness.ok(isinstance(iface, WebIDL.IDLInterface),
+ "Should be an IDLInterface")
+ types = [a.type for a in iface.members if a.isAttr()]
+ harness.ok(types[0].isFloat(), "'float' is a float")
+ harness.ok(not types[0].isUnrestricted(), "'float' is not unrestricted")
+ harness.ok(types[1].isFloat(), "'unrestricted float' is a float")
+ harness.ok(types[1].isUnrestricted(), "'unrestricted float' is unrestricted")
+ harness.ok(types[2].isFloat(), "'double' is a float")
+ harness.ok(not types[2].isUnrestricted(), "'double' is not unrestricted")
+ harness.ok(types[3].isFloat(), "'unrestricted double' is a float")
+ harness.ok(types[3].isUnrestricted(), "'unrestricted double' is unrestricted")
+
+ method = iface.members[6]
+ harness.ok(isinstance(method, WebIDL.IDLMethod), "Should be an IDLMethod")
+ argtypes = [a.type for a in method.signatures()[0][1]]
+ for (idx, type) in enumerate(argtypes):
+ harness.ok(type.isFloat(), "Type %d should be float" % idx)
+ harness.check(type.isUnrestricted(), idx >= 5,
+ "Type %d should %sbe unrestricted" % (
+ idx, "" if idx >= 4 else "not "))
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface FloatTypes {
+ [LenientFloat]
+ long m(float arg);
+ };
+ """)
+ except Exception, x:
+ threw = True
+ harness.ok(threw, "[LenientFloat] only allowed on void methods")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface FloatTypes {
+ [LenientFloat]
+ void m(unrestricted float arg);
+ };
+ """)
+ except Exception, x:
+ threw = True
+ harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface FloatTypes {
+ [LenientFloat]
+ void m(sequence<unrestricted float> arg);
+ };
+ """)
+ except Exception, x:
+ threw = True
+ harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args (2)")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface FloatTypes {
+ [LenientFloat]
+ void m((unrestricted float or FloatTypes) arg);
+ };
+ """)
+ except Exception, x:
+ threw = True
+ harness.ok(threw, "[LenientFloat] only allowed on methods with unrestricted float args (3)")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface FloatTypes {
+ [LenientFloat]
+ readonly attribute float foo;
+ };
+ """)
+ except Exception, x:
+ threw = True
+ harness.ok(threw, "[LenientFloat] only allowed on writable attributes")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_global_extended_attr.py b/components/script/dom/bindings/codegen/parser/tests/test_global_extended_attr.py
new file mode 100644
index 00000000000..c752cecd298
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_global_extended_attr.py
@@ -0,0 +1,122 @@
+def WebIDLTest(parser, harness):
+ parser.parse("""
+ [Global]
+ interface Foo : Bar {
+ getter any(DOMString name);
+ };
+ interface Bar {};
+ """)
+
+ results = parser.finish()
+
+ harness.ok(results[0].isOnGlobalProtoChain(),
+ "[Global] interface should be on global's proto chain")
+ harness.ok(results[1].isOnGlobalProtoChain(),
+ "[Global] interface should be on global's proto chain")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ [Global]
+ interface Foo {
+ getter any(DOMString name);
+ setter void(DOMString name, any arg);
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw,
+ "Should have thrown for [Global] used on an interface with a "
+ "named setter")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ [Global]
+ interface Foo {
+ getter any(DOMString name);
+ creator void(DOMString name, any arg);
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw,
+ "Should have thrown for [Global] used on an interface with a "
+ "named creator")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ [Global]
+ interface Foo {
+ getter any(DOMString name);
+ deleter void(DOMString name);
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw,
+ "Should have thrown for [Global] used on an interface with a "
+ "named deleter")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ [Global, OverrideBuiltins]
+ interface Foo {
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw,
+ "Should have thrown for [Global] used on an interface with a "
+ "[OverrideBuiltins]")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ [Global]
+ interface Foo : Bar {
+ };
+ [OverrideBuiltins]
+ interface Bar {
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw,
+ "Should have thrown for [Global] used on an interface with an "
+ "[OverrideBuiltins] ancestor")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ [Global]
+ interface Foo {
+ };
+ interface Bar : Foo {
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw,
+ "Should have thrown for [Global] used on an interface with a "
+ "descendant")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_interface.py b/components/script/dom/bindings/codegen/parser/tests/test_interface.py
index 5b07172c636..e8ed67b54b3 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_interface.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_interface.py
@@ -186,3 +186,220 @@ def WebIDLTest(parser, harness):
threw = True
harness.ok(threw, "Should not allow inheriting from an interface that is only forward declared")
+
+ parser = parser.reset()
+ parser.parse("""
+ [Constructor(long arg)]
+ interface A {
+ readonly attribute boolean x;
+ void foo();
+ };
+ [Constructor]
+ partial interface A {
+ readonly attribute boolean y;
+ void 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("""
+ [Constructor]
+ partial interface A {
+ readonly attribute boolean y;
+ void foo(long arg);
+ };
+ [Constructor(long arg)]
+ interface A {
+ readonly attribute boolean x;
+ void 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:
+ 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:
+ 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:
+ 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:
+ 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:
+ 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:
+ 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:
+ threw = True
+ harness.ok(threw,
+ "Should not allow unknown extended attributes on interfaces")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface B {};
+ [ArrayClass]
+ interface A : B {
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+ harness.ok(threw,
+ "Should not allow [ArrayClass] on interfaces with parents")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ [ArrayClass]
+ interface A {
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+ harness.ok(not threw,
+ "Should allow [ArrayClass] on interfaces without parents")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_interface_maplikesetlikeiterable.py b/components/script/dom/bindings/codegen/parser/tests/test_interface_maplikesetlikeiterable.py
new file mode 100644
index 00000000000..159b50f84ff
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_interface_maplikesetlikeiterable.py
@@ -0,0 +1,594 @@
+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
+
+ #
+ # Simple Usage Tests
+ #
+
+ shouldPass("Iterable (key only)",
+ """
+ interface Foo1 {
+ iterable<long>;
+ readonly attribute unsigned long length;
+ getter long(unsigned long index);
+ };
+ """, valueIterableMembers)
+
+ shouldPass("Iterable (key and value)",
+ """
+ interface Foo1 {
+ iterable<long, long>;
+ };
+ """, iterableMembers,
+ # numProductions == 2 because of the generated iterator iface,
+ numProductions=2)
+
+ shouldPass("Maplike (readwrite)",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ """, mapRWMembers)
+
+ shouldPass("Maplike (readwrite)",
+ """
+ interface Foo1 {
+ maplike<long, long>;
+ };
+ """, mapRWMembers)
+
+ shouldPass("Maplike (readonly)",
+ """
+ interface Foo1 {
+ readonly maplike<long, long>;
+ };
+ """, mapROMembers)
+
+ shouldPass("Setlike (readwrite)",
+ """
+ interface Foo1 {
+ setlike<long>;
+ };
+ """, setRWMembers)
+
+ shouldPass("Setlike (readonly)",
+ """
+ interface Foo1 {
+ readonly setlike<long>;
+ };
+ """, setROMembers)
+
+ 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)
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_method.py b/components/script/dom/bindings/codegen/parser/tests/test_method.py
index 40b2d2cf8b9..f6f54c33ab6 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_method.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_method.py
@@ -123,23 +123,62 @@ def WebIDLTest(parser, harness):
try:
parser.parse("""
interface A {
- [GetterInfallible] void foo();
+ void foo(optional float bar = 1);
};
""")
results = parser.finish()
except Exception, x:
threw = True
- harness.ok(threw, "Should not allow [GetterInfallible] on methods")
+ harness.ok(not threw, "Should allow integer to float type corecion")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A {
- [SetterInfallible] void foo();
+ [GetterThrows] void foo();
};
""")
results = parser.finish()
except Exception, x:
threw = True
- harness.ok(threw, "Should not allow [SetterInfallible] on methods")
+ harness.ok(threw, "Should not allow [GetterThrows] on methods")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface A {
+ [SetterThrows] void foo();
+ };
+ """)
+ results = parser.finish()
+ except Exception, x:
+ threw = True
+ harness.ok(threw, "Should not allow [SetterThrows] on methods")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface A {
+ [Throw] void foo();
+ };
+ """)
+ results = parser.finish()
+ except Exception, x:
+ threw = True
+ harness.ok(threw, "Should spell [Throws] correctly on methods")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface A {
+ void __noSuchMethod__();
+ };
+ """)
+ results = parser.finish()
+ except Exception, x:
+ threw = True
+ harness.ok(threw, "Should not allow __noSuchMethod__ methods")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_mozmap.py b/components/script/dom/bindings/codegen/parser/tests/test_mozmap.py
new file mode 100644
index 00000000000..1a36fdd62c4
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_mozmap.py
@@ -0,0 +1,39 @@
+import WebIDL
+
+def WebIDLTest(parser, harness):
+ parser.parse("""
+ dictionary Dict {};
+ interface MozMapArg {
+ void foo(MozMap<Dict> arg);
+ };
+ """)
+
+ results = parser.finish()
+
+ harness.check(len(results), 2, "Should know about two things");
+ harness.ok(isinstance(results[1], WebIDL.IDLInterface),
+ "Should have an interface here");
+ members = results[1].members
+ harness.check(len(members), 1, "Should have one member")
+ harness.ok(members[0].isMethod(), "Should have method")
+ signature = members[0].signatures()[0]
+ args = signature[1]
+ harness.check(len(args), 1, "Should have one arg")
+ harness.ok(args[0].type.isMozMap(), "Should have a MozMap type here")
+ harness.ok(args[0].type.inner.isDictionary(),
+ "Should have a dictionary inner type")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface MozMapVoidArg {
+ void foo(MozMap<void> arg);
+ };
+ """)
+
+ results = parser.finish()
+ except Exception,x:
+ threw = True
+
+ harness.ok(threw, "Should have thrown.")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_overload.py b/components/script/dom/bindings/codegen/parser/tests/test_overload.py
index 59d9be54e53..3c680ad5233 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_overload.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_overload.py
@@ -8,6 +8,11 @@ def WebIDLTest(parser, harness):
boolean abitharder(TestOverloads foo);
boolean abitharder(boolean foo);
void abitharder(ArrayBuffer? foo);
+ void withVariadics(long... numbers);
+ void withVariadics(TestOverloads iface);
+ void withVariadics(long num, TestOverloads iface);
+ void optionalTest();
+ void optionalTest(optional long num1, long num2);
};
""")
@@ -20,7 +25,7 @@ def WebIDLTest(parser, harness):
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestOverloads", "Interface has the right QName")
harness.check(iface.identifier.name, "TestOverloads", "Interface has the right name")
- harness.check(len(iface.members), 2, "Expect %s members" % 2)
+ harness.check(len(iface.members), 4, "Expect %s members" % 4)
member = iface.members[0]
harness.check(member.identifier.QName(), "::TestOverloads::basic", "Method has the right QName")
@@ -45,3 +50,11 @@ def WebIDLTest(parser, harness):
harness.check(argument.identifier.QName(), "::TestOverloads::basic::arg1", "Argument has the right QName")
harness.check(argument.identifier.name, "arg1", "Argument has the right name")
harness.check(str(argument.type), "Long", "Argument has the right type")
+
+ member = iface.members[3]
+ harness.check(len(member.overloadsForArgCount(0)), 1,
+ "Only one overload for no args")
+ harness.check(len(member.overloadsForArgCount(1)), 0,
+ "No overloads for one arg")
+ harness.check(len(member.overloadsForArgCount(2)), 1,
+ "Only one overload for two args")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_promise.py b/components/script/dom/bindings/codegen/parser/tests/test_promise.py
new file mode 100644
index 00000000000..55bc0768092
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_promise.py
@@ -0,0 +1,63 @@
+def WebIDLTest(parser, harness):
+ threw = False
+ try:
+ parser.parse("""
+ interface _Promise {};
+ interface A {
+ legacycaller Promise<any> foo();
+ };
+ """)
+ results = parser.finish()
+
+ except:
+ threw = True
+ harness.ok(threw,
+ "Should not allow Promise return values for legacycaller.")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface _Promise {};
+ interface A {
+ Promise<any> foo();
+ long foo(long arg);
+ };
+ """)
+ results = parser.finish();
+ except:
+ threw = True
+ harness.ok(threw,
+ "Should not allow overloads which have both Promise and "
+ "non-Promise return types.")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface _Promise {};
+ interface A {
+ long foo(long arg);
+ Promise<any> foo();
+ };
+ """)
+ results = parser.finish();
+ except:
+ threw = True
+ harness.ok(threw,
+ "Should not allow overloads which have both Promise and "
+ "non-Promise return types.")
+
+ parser = parser.reset()
+ parser.parse("""
+ interface _Promise {};
+ interface A {
+ Promise<any> foo();
+ Promise<any> foo(long arg);
+ };
+ """)
+ results = parser.finish();
+
+ harness.ok(True,
+ "Should allow overloads which only have Promise and return "
+ "types.")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_prototype_ident.py b/components/script/dom/bindings/codegen/parser/tests/test_prototype_ident.py
new file mode 100644
index 00000000000..d3932b54f8b
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_prototype_ident.py
@@ -0,0 +1,80 @@
+def WebIDLTest(parser, harness):
+ threw = False
+ try:
+ parser.parse("""
+ interface TestIface {
+ static attribute boolean prototype;
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "The identifier of a static attribute must not be 'prototype'")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface TestIface {
+ static boolean prototype();
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "The identifier of a static operation must not be 'prototype'")
+
+ parser = parser.reset()
+ threw = False
+ try:
+ parser.parse("""
+ interface TestIface {
+ const boolean prototype = true;
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "The identifier of a constant must not be 'prototype'")
+
+ # Make sure that we can parse non-static attributes with 'prototype' as identifier.
+ parser = parser.reset()
+ parser.parse("""
+ interface TestIface {
+ attribute boolean prototype;
+ };
+ """)
+ results = parser.finish()
+
+ testIface = results[0];
+ harness.check(testIface.members[0].isStatic(), False, "Attribute should not be static")
+ harness.check(testIface.members[0].identifier.name, "prototype", "Attribute identifier should be 'prototype'")
+
+ # Make sure that we can parse non-static operations with 'prototype' as identifier.
+ parser = parser.reset()
+ parser.parse("""
+ interface TestIface {
+ boolean prototype();
+ };
+ """)
+ results = parser.finish()
+
+ testIface = results[0];
+ harness.check(testIface.members[0].isStatic(), False, "Operation should not be static")
+ harness.check(testIface.members[0].identifier.name, "prototype", "Operation identifier should be 'prototype'")
+
+ # Make sure that we can parse dictionary members with 'prototype' as identifier.
+ parser = parser.reset()
+ parser.parse("""
+ dictionary TestDict {
+ boolean prototype;
+ };
+ """)
+ results = parser.finish()
+
+ testDict = results[0];
+ harness.check(testDict.members[0].identifier.name, "prototype", "Dictionary member should be 'prototype'")
+
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_putForwards.py b/components/script/dom/bindings/codegen/parser/tests/test_putForwards.py
new file mode 100644
index 00000000000..86a1bf115b6
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_putForwards.py
@@ -0,0 +1,107 @@
+def WebIDLTest(parser, harness):
+ threw = False
+ try:
+ parser.parse("""
+ interface I {
+ [PutForwards=B] readonly attribute long A;
+ };
+ """)
+
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "Should have thrown.")
+
+ parser = parser.reset();
+ threw = False
+ try:
+ parser.parse("""
+ interface I {
+ [PutForwards=B] readonly attribute J A;
+ };
+ interface J {
+ };
+ """)
+
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "Should have thrown.")
+
+ parser = parser.reset();
+ threw = False
+ try:
+ parser.parse("""
+ interface I {
+ [PutForwards=B] attribute J A;
+ };
+ interface J {
+ attribute long B;
+ };
+ """)
+
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "Should have thrown.")
+
+ parser = parser.reset();
+ threw = False
+ try:
+ parser.parse("""
+ interface I {
+ [PutForwards=B] static readonly attribute J A;
+ };
+ interface J {
+ attribute long B;
+ };
+ """)
+
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "Should have thrown.")
+
+ parser = parser.reset();
+ threw = False
+ try:
+ parser.parse("""
+ callback interface I {
+ [PutForwards=B] readonly attribute J A;
+ };
+ interface J {
+ attribute long B;
+ };
+ """)
+
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "Should have thrown.")
+
+ parser = parser.reset();
+ threw = False
+ try:
+ parser.parse("""
+ interface I {
+ [PutForwards=C] readonly attribute J A;
+ [PutForwards=C] readonly attribute J B;
+ };
+ interface J {
+ [PutForwards=D] readonly attribute K C;
+ };
+ interface K {
+ [PutForwards=A] readonly attribute I D;
+ };
+ """)
+
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "Should have thrown.")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_replaceable.py b/components/script/dom/bindings/codegen/parser/tests/test_replaceable.py
new file mode 100644
index 00000000000..93ee42ed919
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_replaceable.py
@@ -0,0 +1,58 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+def should_throw(parser, harness, message, code):
+ parser = parser.reset();
+ threw = False
+ try:
+ parser.parse(code)
+ parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "Should have thrown: %s" % message)
+
+
+def WebIDLTest(parser, harness):
+ # The [Replaceable] extended attribute MUST take no arguments.
+ should_throw(parser, harness, "no arguments", """
+ interface I {
+ [Replaceable=X] readonly attribute long A;
+ };
+ """)
+
+ # An attribute with the [Replaceable] extended attribute MUST NOT also be
+ # declared with the [PutForwards] extended attribute.
+ should_throw(parser, harness, "PutForwards", """
+ interface I {
+ [PutForwards=B, Replaceable] readonly attribute J A;
+ };
+ interface J {
+ attribute long B;
+ };
+ """)
+
+ # The [Replaceable] extended attribute MUST NOT be used on an attribute
+ # that is not read only.
+ should_throw(parser, harness, "writable attribute", """
+ interface I {
+ [Replaceable] attribute long A;
+ };
+ """)
+
+ # The [Replaceable] extended attribute MUST NOT be used on a static
+ # attribute.
+ should_throw(parser, harness, "static attribute", """
+ interface I {
+ [Replaceable] static readonly attribute long A;
+ };
+ """)
+
+ # The [Replaceable] extended attribute MUST NOT be used on an attribute
+ # declared on a callback interface.
+ should_throw(parser, harness, "callback interface", """
+ callback interface I {
+ [Replaceable] readonly attribute long A;
+ };
+ """)
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_stringifier.py b/components/script/dom/bindings/codegen/parser/tests/test_stringifier.py
new file mode 100644
index 00000000000..14c2c5226fc
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_stringifier.py
@@ -0,0 +1,46 @@
+import WebIDL
+
+def WebIDLTest(parser, harness):
+ parser.parse("""
+ interface TestStringifier {
+ stringifier;
+ };
+ """)
+
+ results = parser.finish()
+
+ harness.ok(isinstance(results[0].members[0], WebIDL.IDLMethod),
+ "Stringifer should be method")
+
+ parser = parser.reset()
+
+ threw = False
+ try:
+ parser.parse("""
+ interface TestStringifier {
+ stringifier;
+ stringifier;
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "Should not allow two 'stringifier;'")
+
+ parser = parser.reset()
+
+ threw = False
+ try:
+ parser.parse("""
+ interface TestStringifier {
+ stringifier;
+ stringifier DOMString foo();
+ };
+ """)
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "Should not allow a 'stringifier;' and a 'stringifier()'")
+
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_unforgeable.py b/components/script/dom/bindings/codegen/parser/tests/test_unforgeable.py
new file mode 100644
index 00000000000..3787e8c6af1
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_unforgeable.py
@@ -0,0 +1,253 @@
+def WebIDLTest(parser, harness):
+ parser.parse("""
+ interface Child : Parent {
+ };
+ interface Parent {
+ [Unforgeable] readonly attribute long foo;
+ };
+ """)
+
+ results = parser.finish()
+ harness.check(len(results), 2,
+ "Should be able to inherit from an interface with "
+ "[Unforgeable] properties.")
+
+ parser = parser.reset();
+ parser.parse("""
+ interface Child : Parent {
+ const short foo = 10;
+ };
+ interface Parent {
+ [Unforgeable] readonly attribute long foo;
+ };
+ """)
+
+ results = parser.finish()
+ harness.check(len(results), 2,
+ "Should be able to inherit from an interface with "
+ "[Unforgeable] properties even if we have a constant with "
+ "the same name.")
+
+ parser = parser.reset();
+ parser.parse("""
+ interface Child : Parent {
+ static attribute short foo;
+ };
+ interface Parent {
+ [Unforgeable] readonly attribute long foo;
+ };
+ """)
+
+ results = parser.finish()
+ harness.check(len(results), 2,
+ "Should be able to inherit from an interface with "
+ "[Unforgeable] properties even if we have a static attribute "
+ "with the same name.")
+
+ parser = parser.reset();
+ parser.parse("""
+ interface Child : Parent {
+ static void foo();
+ };
+ interface Parent {
+ [Unforgeable] readonly attribute long foo;
+ };
+ """)
+
+ results = parser.finish()
+ harness.check(len(results), 2,
+ "Should be able to inherit from an interface with "
+ "[Unforgeable] properties even if we have a static operation "
+ "with the same name.")
+
+ parser = parser.reset();
+ threw = False
+ try:
+ parser.parse("""
+ interface Child : Parent {
+ void foo();
+ };
+ interface Parent {
+ [Unforgeable] readonly attribute long foo;
+ };
+ """)
+
+ results = parser.finish()
+ except:
+ threw = True
+ harness.ok(threw,
+ "Should have thrown when shadowing unforgeable attribute on "
+ "parent with operation.")
+
+ parser = parser.reset();
+ threw = False
+ try:
+ parser.parse("""
+ interface Child : Parent {
+ void foo();
+ };
+ interface Parent {
+ [Unforgeable] void foo();
+ };
+ """)
+
+ results = parser.finish()
+ except:
+ threw = True
+ harness.ok(threw,
+ "Should have thrown when shadowing unforgeable operation on "
+ "parent with operation.")
+
+ parser = parser.reset();
+ threw = False
+ try:
+ parser.parse("""
+ interface Child : Parent {
+ attribute short foo;
+ };
+ interface Parent {
+ [Unforgeable] readonly attribute long foo;
+ };
+ """)
+
+ results = parser.finish()
+ except Exception,x:
+ threw = True
+ harness.ok(threw,
+ "Should have thrown when shadowing unforgeable attribute on "
+ "parent with attribute.")
+
+ parser = parser.reset();
+ threw = False
+ try:
+ parser.parse("""
+ interface Child : Parent {
+ attribute short foo;
+ };
+ interface Parent {
+ [Unforgeable] void foo();
+ };
+ """)
+
+ results = parser.finish()
+ except Exception,x:
+ threw = True
+ harness.ok(threw,
+ "Should have thrown when shadowing unforgeable operation on "
+ "parent with attribute.")
+
+ parser = parser.reset();
+ parser.parse("""
+ interface Child : Parent {
+ };
+ interface Parent {};
+ interface Consequential {
+ [Unforgeable] readonly attribute long foo;
+ };
+ Parent implements Consequential;
+ """)
+
+ results = parser.finish()
+ harness.check(len(results), 4,
+ "Should be able to inherit from an interface with a "
+ "consequential interface with [Unforgeable] properties.")
+
+ parser = parser.reset();
+ threw = False
+ try:
+ parser.parse("""
+ interface Child : Parent {
+ void foo();
+ };
+ interface Parent {};
+ interface Consequential {
+ [Unforgeable] readonly attribute long foo;
+ };
+ Parent implements Consequential;
+ """)
+
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw,
+ "Should have thrown when shadowing unforgeable attribute "
+ "of parent's consequential interface.")
+
+ parser = parser.reset();
+ threw = False
+ try:
+ parser.parse("""
+ interface Child : Parent {
+ };
+ interface Parent : GrandParent {};
+ interface GrandParent {};
+ interface Consequential {
+ [Unforgeable] readonly attribute long foo;
+ };
+ GrandParent implements Consequential;
+ interface ChildConsequential {
+ void foo();
+ };
+ Child implements ChildConsequential;
+ """)
+
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw,
+ "Should have thrown when our consequential interface shadows unforgeable attribute "
+ "of ancestor's consequential interface.")
+
+ parser = parser.reset();
+ threw = False
+ try:
+ parser.parse("""
+ interface Child : Parent {
+ };
+ interface Parent : GrandParent {};
+ interface GrandParent {};
+ interface Consequential {
+ [Unforgeable] void foo();
+ };
+ GrandParent implements Consequential;
+ interface ChildConsequential {
+ void foo();
+ };
+ Child implements ChildConsequential;
+ """)
+
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw,
+ "Should have thrown when our consequential interface shadows unforgeable operation "
+ "of ancestor's consequential interface.")
+
+ parser = parser.reset();
+ parser.parse("""
+ interface iface {
+ [Unforgeable] attribute long foo;
+ };
+ """)
+
+ results = parser.finish()
+ harness.check(len(results), 1,
+ "Should allow writable [Unforgeable] attribute.")
+
+ parser = parser.reset();
+ threw = False
+ try:
+ parser.parse("""
+ interface iface {
+ [Unforgeable] static readonly attribute long foo;
+ };
+ """)
+
+ results = parser.finish()
+ except:
+ threw = True
+
+ harness.ok(threw, "Should have thrown for static [Unforgeable] attribute.")
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_union.py b/components/script/dom/bindings/codegen/parser/tests/test_union.py
index 68c2bcade8c..36cacf3ccf4 100644
--- a/components/script/dom/bindings/codegen/parser/tests/test_union.py
+++ b/components/script/dom/bindings/codegen/parser/tests/test_union.py
@@ -62,6 +62,8 @@ def WebIDLTest(parser, harness):
"byte",
"octet",
"DOMString",
+ "ByteString",
+ "USVString",
#"sequence<float>",
"object",
"ArrayBuffer",
diff --git a/components/script/dom/bindings/codegen/parser/tests/test_usvstring.py b/components/script/dom/bindings/codegen/parser/tests/test_usvstring.py
new file mode 100644
index 00000000000..3a1369abd02
--- /dev/null
+++ b/components/script/dom/bindings/codegen/parser/tests/test_usvstring.py
@@ -0,0 +1,36 @@
+# -*- coding: UTF-8 -*-
+
+import WebIDL
+
+def WebIDLTest(parser, harness):
+ parser.parse("""
+ interface TestUSVString {
+ attribute USVString svs;
+ };
+ """)
+
+ results = parser.finish();
+
+ 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(), "::TestUSVString",
+ "Interface has the right QName")
+ harness.check(iface.identifier.name, "TestUSVString",
+ "Interface has the right name")
+ harness.check(iface.parent, None, "Interface has no parent")
+
+ members = iface.members
+ harness.check(len(members), 1, "Should be one member")
+
+ attr = members[0]
+ harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute")
+ harness.check(attr.identifier.QName(), "::TestUSVString::svs",
+ "Attr has correct QName")
+ harness.check(attr.identifier.name, "svs", "Attr has correct name")
+ harness.check(str(attr.type), "USVString",
+ "Attr type is the correct name")
+ harness.ok(attr.type.isUSVString(), "Should be USVString type")
+ harness.ok(attr.type.isString(), "Should be String collective type")
+ harness.ok(not attr.type.isDOMString(), "Should be not be DOMString type")
diff --git a/components/script/dom/bindings/codegen/parser/update.sh b/components/script/dom/bindings/codegen/parser/update.sh
index 21491e6c02c..fc764d2300c 100755
--- a/components/script/dom/bindings/codegen/parser/update.sh
+++ b/components/script/dom/bindings/codegen/parser/update.sh
@@ -3,4 +3,8 @@ patch < abstract.patch
patch < debug.patch
patch < legacy-unenumerable-named-properties.patch
-# TODO: update test files from https://dxr.mozilla.org/mozilla-central/source/dom/bindings/parser/tests
+wget https://hg.mozilla.org/mozilla-central/archive/tip.tar.gz/dom/bindings/parser/tests/ -O tests.tar.gz
+rm -r tests
+mkdir tests
+tar xvpf tests.tar.gz -C tests --strip-components=5
+rm tests.tar.gz WebIDL.py.orig