import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View file

@ -0,0 +1 @@
A WebIDL parser written in Python to be used in Mozilla.

View file

@ -0,0 +1 @@
http://dev.w3.org/cvsweb/~checkout~/2006/webapi/WebIDL/Overview.html?rev=1.409;content-type=text%2Fhtml%3b+charset=utf-8

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,108 @@
# 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/.
import os, sys
import glob
import argparse
import traceback
import WebIDL
class TestHarness(object):
def __init__(self, test, verbose):
self.test = test
self.verbose = verbose
self.printed_intro = False
self.passed = 0
self.failures = []
def start(self):
if self.verbose:
self.maybe_print_intro()
def finish(self):
if self.verbose or self.printed_intro:
print "Finished test %s" % self.test
def maybe_print_intro(self):
if not self.printed_intro:
print "Starting test %s" % self.test
self.printed_intro = True
def test_pass(self, msg):
self.passed += 1
if self.verbose:
print "TEST-PASS | %s" % msg
def test_fail(self, msg):
self.maybe_print_intro()
self.failures.append(msg)
print "TEST-UNEXPECTED-FAIL | %s" % msg
def ok(self, condition, msg):
if condition:
self.test_pass(msg)
else:
self.test_fail(msg)
def check(self, a, b, msg):
if a == b:
self.test_pass(msg)
else:
self.test_fail(msg + " | Got %s expected %s" % (a, b))
def run_tests(tests, verbose):
testdir = os.path.join(os.path.dirname(__file__), 'tests')
if not tests:
tests = glob.iglob(os.path.join(testdir, "*.py"))
sys.path.append(testdir)
all_passed = 0
failed_tests = []
for test in tests:
(testpath, ext) = os.path.splitext(os.path.basename(test))
_test = __import__(testpath, globals(), locals(), ['WebIDLTest'])
harness = TestHarness(test, verbose)
harness.start()
try:
_test.WebIDLTest.__call__(WebIDL.Parser(), harness)
except Exception, ex:
harness.test_fail("Unhandled exception in test %s: %s" %
(testpath, ex))
traceback.print_exc()
finally:
harness.finish()
all_passed += harness.passed
if harness.failures:
failed_tests.append((test, harness.failures))
if verbose or failed_tests:
print
print 'Result summary:'
print 'Successful: %d' % all_passed
print 'Unexpected: %d' % \
sum(len(failures) for _, failures in failed_tests)
for test, failures in failed_tests:
print '%s:' % test
for failure in failures:
print 'TEST-UNEXPECTED-FAIL | %s' % failure
def get_parser():
usage = """%(prog)s [OPTIONS] [TESTS]
Where TESTS are relative to the tests directory."""
parser = argparse.ArgumentParser(usage=usage)
parser.add_argument('-q', '--quiet', action='store_false', dest='verbose',
help="Don't print passing tests.", default=None)
parser.add_argument('-v', '--verbose', action='store_true', dest='verbose',
help="Run tests in verbose mode.")
parser.add_argument('tests', nargs="*", help="Tests to run")
return parser
if __name__ == '__main__':
parser = get_parser()
args = parser.parse_args()
if args.verbose is None:
args.verbose = True
run_tests(args.tests, verbose=args.verbose)

View file

@ -0,0 +1,14 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface DoubleNull {
attribute any? foo;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View file

@ -0,0 +1,14 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface ArgumentIdentifierConflict {
void foo(boolean arg1, boolean arg1);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View file

@ -0,0 +1,14 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface VoidArgument1 {
void foo(void arg2);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View file

@ -0,0 +1,81 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestArrayBuffer {
attribute ArrayBuffer bufferAttr;
void bufferMethod(ArrayBuffer arg1, ArrayBuffer? arg2, sequence<ArrayBuffer> arg3);
attribute ArrayBufferView viewAttr;
void viewMethod(ArrayBufferView arg1, ArrayBufferView? arg2, sequence<ArrayBufferView> arg3);
attribute Int8Array int8ArrayAttr;
void int8ArrayMethod(Int8Array arg1, Int8Array? arg2, sequence<Int8Array> arg3);
attribute Uint8Array uint8ArrayAttr;
void uint8ArrayMethod(Uint8Array arg1, Uint8Array? arg2, sequence<Uint8Array> arg3);
attribute Uint8ClampedArray uint8ClampedArrayAttr;
void uint8ClampedArrayMethod(Uint8ClampedArray arg1, Uint8ClampedArray? arg2, sequence<Uint8ClampedArray> arg3);
attribute Int16Array int16ArrayAttr;
void int16ArrayMethod(Int16Array arg1, Int16Array? arg2, sequence<Int16Array> arg3);
attribute Uint16Array uint16ArrayAttr;
void uint16ArrayMethod(Uint16Array arg1, Uint16Array? arg2, sequence<Uint16Array> arg3);
attribute Int32Array int32ArrayAttr;
void int32ArrayMethod(Int32Array arg1, Int32Array? arg2, sequence<Int32Array> arg3);
attribute Uint32Array uint32ArrayAttr;
void uint32ArrayMethod(Uint32Array arg1, Uint32Array? arg2, sequence<Uint32Array> arg3);
attribute Float32Array float32ArrayAttr;
void float32ArrayMethod(Float32Array arg1, Float32Array? arg2, sequence<Float32Array> arg3);
attribute Float64Array float64ArrayAttr;
void float64ArrayMethod(Float64Array arg1, Float64Array? arg2, sequence<Float64Array> arg3);
};
""")
results = parser.finish()
iface = results[0]
harness.ok(True, "TestArrayBuffer interface parsed without error")
harness.check(len(iface.members), 22, "Interface should have twenty two members")
members = iface.members
def checkStuff(attr, method, t):
harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Expect an IDLAttribute")
harness.ok(isinstance(method, WebIDL.IDLMethod), "Expect an IDLMethod")
harness.check(str(attr.type), t, "Expect an ArrayBuffer type")
harness.ok(attr.type.isSpiderMonkeyInterface(), "Should test as a js interface")
(retType, arguments) = method.signatures()[0]
harness.ok(retType.isVoid(), "Should have a void return type")
harness.check(len(arguments), 3, "Expect 3 arguments")
harness.check(str(arguments[0].type), t, "Expect an ArrayBuffer type")
harness.ok(arguments[0].type.isSpiderMonkeyInterface(), "Should test as a js interface")
harness.check(str(arguments[1].type), t + "OrNull", "Expect an ArrayBuffer type")
harness.ok(arguments[1].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface")
harness.check(str(arguments[2].type), t + "Sequence", "Expect an ArrayBuffer type")
harness.ok(arguments[2].type.inner.isSpiderMonkeyInterface(), "Should test as a js interface")
checkStuff(members[0], members[1], "ArrayBuffer")
checkStuff(members[2], members[3], "ArrayBufferView")
checkStuff(members[4], members[5], "Int8Array")
checkStuff(members[6], members[7], "Uint8Array")
checkStuff(members[8], members[9], "Uint8ClampedArray")
checkStuff(members[10], members[11], "Int16Array")
checkStuff(members[12], members[13], "Uint16Array")
checkStuff(members[14], members[15], "Int32Array")
checkStuff(members[16], members[17], "Uint32Array")
checkStuff(members[18], members[19], "Float32Array")
checkStuff(members[20], members[21], "Float64Array")

View file

@ -0,0 +1,177 @@
import WebIDL
def WebIDLTest(parser, harness):
testData = [("::TestAttr%s::b", "b", "Byte%s", False),
("::TestAttr%s::rb", "rb", "Byte%s", True),
("::TestAttr%s::o", "o", "Octet%s", False),
("::TestAttr%s::ro", "ro", "Octet%s", True),
("::TestAttr%s::s", "s", "Short%s", False),
("::TestAttr%s::rs", "rs", "Short%s", True),
("::TestAttr%s::us", "us", "UnsignedShort%s", False),
("::TestAttr%s::rus", "rus", "UnsignedShort%s", True),
("::TestAttr%s::l", "l", "Long%s", False),
("::TestAttr%s::rl", "rl", "Long%s", True),
("::TestAttr%s::ul", "ul", "UnsignedLong%s", False),
("::TestAttr%s::rul", "rul", "UnsignedLong%s", True),
("::TestAttr%s::ll", "ll", "LongLong%s", False),
("::TestAttr%s::rll", "rll", "LongLong%s", True),
("::TestAttr%s::ull", "ull", "UnsignedLongLong%s", False),
("::TestAttr%s::rull", "rull", "UnsignedLongLong%s", True),
("::TestAttr%s::str", "str", "String%s", False),
("::TestAttr%s::rstr", "rstr", "String%s", True),
("::TestAttr%s::obj", "obj", "Object%s", False),
("::TestAttr%s::robj", "robj", "Object%s", True),
("::TestAttr%s::object", "object", "Object%s", False),
("::TestAttr%s::f", "f", "Float%s", False),
("::TestAttr%s::rf", "rf", "Float%s", True)]
parser.parse("""
interface TestAttr {
attribute byte b;
readonly attribute byte rb;
attribute octet o;
readonly attribute octet ro;
attribute short s;
readonly attribute short rs;
attribute unsigned short us;
readonly attribute unsigned short rus;
attribute long l;
readonly attribute long rl;
attribute unsigned long ul;
readonly attribute unsigned long rul;
attribute long long ll;
readonly attribute long long rll;
attribute unsigned long long ull;
readonly attribute unsigned long long rull;
attribute DOMString str;
readonly attribute DOMString rstr;
attribute object obj;
readonly attribute object robj;
attribute object _object;
attribute float f;
readonly attribute float rf;
};
interface TestAttrNullable {
attribute byte? b;
readonly attribute byte? rb;
attribute octet? o;
readonly attribute octet? ro;
attribute short? s;
readonly attribute short? rs;
attribute unsigned short? us;
readonly attribute unsigned short? rus;
attribute long? l;
readonly attribute long? rl;
attribute unsigned long? ul;
readonly attribute unsigned long? rul;
attribute long long? ll;
readonly attribute long long? rll;
attribute unsigned long long? ull;
readonly attribute unsigned long long? rull;
attribute DOMString? str;
readonly attribute DOMString? rstr;
attribute object? obj;
readonly attribute object? robj;
attribute object? _object;
attribute float? f;
readonly attribute float? rf;
};
""")
results = parser.finish()
def checkAttr(attr, QName, name, type, readonly):
harness.ok(isinstance(attr, WebIDL.IDLAttribute),
"Should be an IDLAttribute")
harness.ok(attr.isAttr(), "Attr is an Attr")
harness.ok(not attr.isMethod(), "Attr is not an method")
harness.ok(not attr.isConst(), "Attr is not a const")
harness.check(attr.identifier.QName(), QName, "Attr has the right QName")
harness.check(attr.identifier.name, name, "Attr has the right name")
harness.check(str(attr.type), type, "Attr has the right type")
harness.check(attr.readonly, readonly, "Attr's readonly state is correct")
harness.ok(True, "TestAttr interface parsed without error.")
harness.check(len(results), 2, "Should be two productions.")
iface = results[0]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestAttr", "Interface has the right QName")
harness.check(iface.identifier.name, "TestAttr", "Interface has the right name")
harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
attrs = iface.members
for i in range(len(attrs)):
data = testData[i]
attr = attrs[i]
(QName, name, type, readonly) = data
checkAttr(attr, QName % "", name, type % "", readonly)
iface = results[1]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestAttrNullable", "Interface has the right QName")
harness.check(iface.identifier.name, "TestAttrNullable", "Interface has the right name")
harness.check(len(iface.members), len(testData), "Expect %s members" % len(testData))
attrs = iface.members
for i in range(len(attrs)):
data = testData[i]
attr = attrs[i]
(QName, name, type, readonly) = data
checkAttr(attr, QName % "Nullable", name, type % "OrNull", readonly)
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A {
[SetterThrows] readonly attribute boolean foo;
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should not allow [SetterThrows] on readonly attributes")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A {
[Throw] readonly attribute boolean foo;
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should spell [Throws] correctly")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A {
[SameObject] readonly attribute boolean foo;
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should not allow [SameObject] on attributes not of interface type")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A {
[SameObject] readonly attribute A foo;
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(not threw, "Should allow [SameObject] on attributes of interface type")

View file

@ -0,0 +1,67 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface AttrSequenceType {
attribute sequence<object> foo;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Attribute type must not be a sequence type")
parser.reset()
threw = False
try:
parser.parse("""
interface AttrUnionWithSequenceType {
attribute (sequence<object> or DOMString) foo;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Attribute type must not be a union with a sequence member type")
parser.reset()
threw = False
try:
parser.parse("""
interface AttrNullableUnionWithSequenceType {
attribute (sequence<object>? or DOMString) foo;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Attribute type must not be a union with a nullable sequence "
"member type")
parser.reset()
threw = False
try:
parser.parse("""
interface AttrUnionWithUnionWithSequenceType {
attribute ((sequence<object> or DOMString) or AttrUnionWithUnionWithSequenceType) foo;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Attribute type must not be a union type with a union member "
"type that has a sequence member type")

View file

@ -0,0 +1,11 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface Test {
attribute long b;
};
""");
attr = parser.finish()[0].members[0]
harness.check(attr.type.filename(), '<builtin>', 'Filename on builtin type')

View file

@ -0,0 +1,41 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestBuiltins {
attribute boolean b;
attribute byte s8;
attribute octet u8;
attribute short s16;
attribute unsigned short u16;
attribute long s32;
attribute unsigned long u32;
attribute long long s64;
attribute unsigned long long u64;
attribute DOMTimeStamp ts;
};
""")
results = parser.finish()
harness.ok(True, "TestBuiltins 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(), "::TestBuiltins", "Interface has the right QName")
harness.check(iface.identifier.name, "TestBuiltins", "Interface has the right name")
harness.check(iface.parent, None, "Interface has no parent")
members = iface.members
harness.check(len(members), 10, "Should be one production")
names = ["b", "s8", "u8", "s16", "u16", "s32", "u32", "s64", "u64", "ts"]
types = ["Boolean", "Byte", "Octet", "Short", "UnsignedShort", "Long", "UnsignedLong", "LongLong", "UnsignedLongLong", "UnsignedLongLong"]
for i in range(10):
attr = members[i]
harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute")
harness.check(attr.identifier.QName(), "::TestBuiltins::" + names[i], "Attr has correct QName")
harness.check(attr.identifier.name, names[i], "Attr has correct name")
harness.check(str(attr.type), types[i], "Attr type is the correct name")
harness.ok(attr.type.isPrimitive(), "Should be a primitive type")

View file

@ -0,0 +1,99 @@
# -*- 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 for ByteString default in interface")
# Can have optional ByteStrings with default values
try:
parser.parse("""
interface OptionalByteString {
void passByteString(optional ByteString arg = "hello");
};
""")
results2 = parser.finish();
except WebIDL.WebIDLError as e:
harness.ok(False,
"Should not have thrown a WebIDL error for ByteString "
"default in dictionary. " + str(e))
# Can have a default ByteString value in a dictionary
try:
parser.parse("""
dictionary OptionalByteStringDict {
ByteString item = "some string";
};
""")
results3 = parser.finish();
except WebIDL.WebIDLError as e:
harness.ok(False,
"Should not have thrown a WebIDL error for ByteString "
"default in dictionary. " + str(e))
# Don't allow control characters in ByteString literals
threw = False
try:
parser.parse("""
dictionary OptionalByteStringDict2 {
ByteString item = "\x03";
};
""")
results4 = parser.finish()
except WebIDL.WebIDLError as e:
threw = True
harness.ok(threw,
"Should have thrown a WebIDL error for invalid ByteString "
"default in dictionary")

View file

@ -0,0 +1,34 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestCallback {
attribute CallbackType? listener;
};
callback CallbackType = boolean (unsigned long arg);
""")
results = parser.finish()
harness.ok(True, "TestCallback interface parsed without error.")
harness.check(len(results), 2, "Should be two productions.")
iface = results[0]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestCallback", "Interface has the right QName")
harness.check(iface.identifier.name, "TestCallback", "Interface has the right name")
harness.check(len(iface.members), 1, "Expect %s members" % 1)
attr = iface.members[0]
harness.ok(isinstance(attr, WebIDL.IDLAttribute),
"Should be an IDLAttribute")
harness.ok(attr.isAttr(), "Should be an attribute")
harness.ok(not attr.isMethod(), "Attr is not an method")
harness.ok(not attr.isConst(), "Attr is not a const")
harness.check(attr.identifier.QName(), "::TestCallback::listener", "Attr has the right QName")
harness.check(attr.identifier.name, "listener", "Attr has the right name")
t = attr.type
harness.ok(not isinstance(t, WebIDL.IDLWrapperType), "Attr has the right type")
harness.ok(isinstance(t, WebIDL.IDLNullableType), "Attr has the right type")
harness.ok(t.isCallback(), "Attr has the right type")

View file

@ -0,0 +1,94 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
callback interface TestCallbackInterface {
attribute boolean bool;
};
""")
results = parser.finish()
iface = results[0]
harness.ok(iface.isCallback(), "Interface should be a callback")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface TestInterface {
};
callback interface TestCallbackInterface : TestInterface {
attribute boolean bool;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow non-callback parent of callback interface")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface TestInterface : TestCallbackInterface {
};
callback interface TestCallbackInterface {
attribute boolean bool;
};
""")
results = parser.finish()
except:
threw = True
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)

View file

@ -0,0 +1,110 @@
def WebIDLTest(parser, harness):
parser.parse("""
dictionary Dict {
any foo;
[ChromeOnly] any bar;
};
""")
results = parser.finish()
harness.check(len(results), 1, "Should have a dictionary")
members = results[0].members;
harness.check(len(members), 2, "Should have two members")
# Note that members are ordered lexicographically, so "bar" comes
# before "foo".
harness.ok(members[0].getExtendedAttribute("ChromeOnly"),
"First member is not ChromeOnly")
harness.ok(not members[1].getExtendedAttribute("ChromeOnly"),
"Second member is ChromeOnly")
parser = parser.reset()
parser.parse("""
dictionary Dict {
any foo;
any bar;
};
interface Iface {
[Constant, Cached] readonly attribute Dict dict;
};
""")
results = parser.finish()
harness.check(len(results), 2, "Should have a dictionary and an interface")
parser = parser.reset()
exception = None
try:
parser.parse("""
dictionary Dict {
any foo;
[ChromeOnly] any bar;
};
interface Iface {
[Constant, Cached] readonly attribute Dict dict;
};
""")
results = parser.finish()
except Exception, exception:
pass
harness.ok(exception, "Should have thrown.")
harness.check(exception.message,
"[Cached] and [StoreInSlot] must not be used on an attribute "
"whose type contains a [ChromeOnly] dictionary member",
"Should have thrown the right exception")
parser = parser.reset()
exception = None
try:
parser.parse("""
dictionary ParentDict {
[ChromeOnly] any bar;
};
dictionary Dict : ParentDict {
any foo;
};
interface Iface {
[Constant, Cached] readonly attribute Dict dict;
};
""")
results = parser.finish()
except Exception, exception:
pass
harness.ok(exception, "Should have thrown (2).")
harness.check(exception.message,
"[Cached] and [StoreInSlot] must not be used on an attribute "
"whose type contains a [ChromeOnly] dictionary member",
"Should have thrown the right exception (2)")
parser = parser.reset()
exception = None
try:
parser.parse("""
dictionary GrandParentDict {
[ChromeOnly] any baz;
};
dictionary ParentDict : GrandParentDict {
any bar;
};
dictionary Dict : ParentDict {
any foo;
};
interface Iface {
[Constant, Cached] readonly attribute Dict dict;
};
""")
results = parser.finish()
except Exception, exception:
pass
harness.ok(exception, "Should have thrown (3).")
harness.check(exception.message,
"[Cached] and [StoreInSlot] must not be used on an attribute "
"whose type contains a [ChromeOnly] dictionary member",
"Should have thrown the right exception (3)")

View file

@ -0,0 +1,80 @@
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 {
const byte zero = 0;
const byte b = -1;
const octet o = 2;
const short s = -3;
const unsigned short us = 0x4;
const long l = -0X5;
const unsigned long ul = 6;
const unsigned long long ull = 7;
const long long ll = -010;
const boolean t = true;
const boolean f = false;
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;
};
""")
results = parser.finish()
harness.ok(True, "TestConsts interface parsed without error.")
harness.check(len(results), 1, "Should be one production.")
iface = results[0]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"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), len(expected), "Expect %s members" % len(expected))
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")
harness.ok(not const.isAttr(), "Const is not an attr")
harness.ok(not const.isMethod(), "Const is not a method")
harness.check(const.identifier.QName(), QName, "Const has the right QName")
harness.check(const.identifier.name, name, "Const has the right name")
harness.check(str(const.type), type, "Const has the right type")
harness.ok(const.type.isPrimitive(), "All consts should be primitive")
harness.check(str(const.value.type), str(const.type),
"Const's value has the same type as the type")
harness.check(const.value.value, value, "Const value has the right value.")

View file

@ -0,0 +1,109 @@
import WebIDL
def WebIDLTest(parser, harness):
def checkArgument(argument, QName, name, type, optional, variadic):
harness.ok(isinstance(argument, WebIDL.IDLArgument),
"Should be an IDLArgument")
harness.check(argument.identifier.QName(), QName, "Argument has the right QName")
harness.check(argument.identifier.name, name, "Argument has the right name")
harness.check(str(argument.type), type, "Argument has the right return type")
harness.check(argument.optional, optional, "Argument has the right optional value")
harness.check(argument.variadic, variadic, "Argument has the right variadic value")
def checkMethod(method, QName, name, signatures,
static=True, getter=False, setter=False, creator=False,
deleter=False, legacycaller=False, stringifier=False,
chromeOnly=False):
harness.ok(isinstance(method, WebIDL.IDLMethod),
"Should be an IDLMethod")
harness.ok(method.isMethod(), "Method is a method")
harness.ok(not method.isAttr(), "Method is not an attr")
harness.ok(not method.isConst(), "Method is not a const")
harness.check(method.identifier.QName(), QName, "Method has the right QName")
harness.check(method.identifier.name, name, "Method has the right name")
harness.check(method.isStatic(), static, "Method has the correct static value")
harness.check(method.isGetter(), getter, "Method has the correct getter value")
harness.check(method.isSetter(), setter, "Method has the correct setter value")
harness.check(method.isCreator(), creator, "Method has the correct creator value")
harness.check(method.isDeleter(), deleter, "Method has the correct deleter value")
harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value")
harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value")
harness.check(method.getExtendedAttribute("ChromeOnly") is not None, chromeOnly, "Method has the correct value for ChromeOnly")
harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures")
sigpairs = zip(method.signatures(), signatures)
for (gotSignature, expectedSignature) in sigpairs:
(gotRetType, gotArgs) = gotSignature
(expectedRetType, expectedArgs) = expectedSignature
harness.check(str(gotRetType), expectedRetType,
"Method has the expected return type.")
for i in range(0, len(gotArgs)):
(QName, name, type, optional, variadic) = expectedArgs[i]
checkArgument(gotArgs[i], QName, name, type, optional, variadic)
parser.parse("""
[Constructor]
interface TestConstructorNoArgs {
};
[Constructor(DOMString name)]
interface TestConstructorWithArgs {
};
[Constructor(object foo), Constructor(boolean bar)]
interface TestConstructorOverloads {
};
""")
results = parser.finish()
harness.check(len(results), 3, "Should be three productions")
harness.ok(isinstance(results[0], WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.ok(isinstance(results[1], WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.ok(isinstance(results[2], WebIDL.IDLInterface),
"Should be an IDLInterface")
checkMethod(results[0].ctor(), "::TestConstructorNoArgs::constructor",
"constructor", [("TestConstructorNoArgs (Wrapper)", [])])
checkMethod(results[1].ctor(), "::TestConstructorWithArgs::constructor",
"constructor",
[("TestConstructorWithArgs (Wrapper)",
[("::TestConstructorWithArgs::constructor::name", "name", "String", False, False)])])
checkMethod(results[2].ctor(), "::TestConstructorOverloads::constructor",
"constructor",
[("TestConstructorOverloads (Wrapper)",
[("::TestConstructorOverloads::constructor::foo", "foo", "Object", False, False)]),
("TestConstructorOverloads (Wrapper)",
[("::TestConstructorOverloads::constructor::bar", "bar", "Boolean", False, False)])])
parser = parser.reset()
parser.parse("""
[ChromeConstructor()]
interface TestChromeConstructor {
};
""")
results = parser.finish()
harness.check(len(results), 1, "Should be one production")
harness.ok(isinstance(results[0], WebIDL.IDLInterface),
"Should be an IDLInterface")
checkMethod(results[0].ctor(), "::TestChromeConstructor::constructor",
"constructor", [("TestChromeConstructor (Wrapper)", [])],
chromeOnly=True)
parser = parser.reset()
threw = False
try:
parser.parse("""
[Constructor(),
ChromeConstructor(DOMString a)]
interface TestChromeConstructor {
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Can't have both a Constructor and a ChromeConstructor")

View file

@ -0,0 +1,36 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
[Constructor, NoInterfaceObject]
interface TestConstructorNoInterfaceObject {
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
[NoInterfaceObject, Constructor]
interface TestConstructorNoInterfaceObject {
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
parser.parse("""
[NoInterfaceObject, NamedConstructor=FooBar]
interface TestNamedConstructorNoInterfaceObject {
};
""")

View file

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

View file

@ -0,0 +1,15 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface Foo;
interface Bar;
interface Foo;
""");
results = parser.finish()
# There should be no duplicate interfaces in the result.
expectedNames = sorted(['Foo', 'Bar'])
actualNames = sorted(map(lambda iface: iface.identifier.name, results))
harness.check(actualNames, expectedNames, "Parser shouldn't output duplicate names.")

View file

@ -0,0 +1,555 @@
def WebIDLTest(parser, harness):
parser.parse("""
dictionary Dict2 : Dict1 {
long child = 5;
Dict1 aaandAnother;
};
dictionary Dict1 {
long parent;
double otherParent;
};
""")
results = parser.finish()
dict1 = results[1];
dict2 = results[0];
harness.check(len(dict1.members), 2, "Dict1 has two members")
harness.check(len(dict2.members), 2, "Dict2 has four members")
harness.check(dict1.members[0].identifier.name, "otherParent",
"'o' comes before 'p'")
harness.check(dict1.members[1].identifier.name, "parent",
"'o' really comes before 'p'")
harness.check(dict2.members[0].identifier.name, "aaandAnother",
"'a' comes before 'c'")
harness.check(dict2.members[1].identifier.name, "child",
"'a' really comes before 'c'")
# Now reset our parser
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary Dict {
long prop = 5;
long prop;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow name duplication in a dictionary")
# Now reset our parser again
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary Dict1 : Dict2 {
long prop = 5;
};
dictionary Dict2 : Dict3 {
long prop2;
};
dictionary Dict3 {
double prop;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow name duplication in a dictionary and "
"its ancestor")
# More reset
parser = parser.reset()
threw = False
try:
parser.parse("""
interface Iface {};
dictionary Dict : Iface {
long prop;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow non-dictionary parents for dictionaries")
# Even more reset
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary A : B {};
dictionary B : A {};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow cycles in dictionary inheritance chains")
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary A {
[TreatNullAs=EmptyString] DOMString foo;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow [TreatNullAs] on dictionary members");
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary A {
};
interface X {
void doFoo(A arg);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Trailing dictionary arg must be optional")
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary A {
};
interface X {
void doFoo((A or DOMString) arg);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Trailing union arg containing a dictionary must be optional")
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary A {
};
interface X {
void doFoo(A arg1, optional long arg2);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Dictionary arg followed by optional arg must be optional")
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary A {
};
interface X {
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 {
};
interface X {
void doFoo(A arg1, long arg2);
};
""")
results = parser.finish()
harness.ok(True, "Dictionary arg followed by required arg can be required")
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary A {
};
interface X {
void doFoo(optional A? arg1);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Dictionary arg must not be nullable")
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 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")

View file

@ -0,0 +1,293 @@
def firstArgType(method):
return method.signatures()[0][1][0].type
def WebIDLTest(parser, harness):
parser.parse("""
dictionary Dict {
};
callback interface Foo {
};
interface Bar {
// Bit of a pain to get things that have dictionary types
void passDict(optional Dict arg);
void passFoo(Foo arg);
void passNullableUnion((object? or DOMString) arg);
void passNullable(Foo? arg);
};
""")
results = parser.finish()
iface = results[2]
harness.ok(iface.isInterface(), "Should have interface")
dictMethod = iface.members[0]
ifaceMethod = iface.members[1]
nullableUnionMethod = iface.members[2]
nullableIfaceMethod = iface.members[3]
dictType = firstArgType(dictMethod)
ifaceType = firstArgType(ifaceMethod)
harness.ok(dictType.isDictionary(), "Should have dictionary type");
harness.ok(ifaceType.isInterface(), "Should have interface type");
harness.ok(ifaceType.isCallbackInterface(), "Should have callback interface type");
harness.ok(not dictType.isDistinguishableFrom(ifaceType),
"Dictionary not distinguishable from callback interface")
harness.ok(not ifaceType.isDistinguishableFrom(dictType),
"Callback interface not distinguishable from dictionary")
nullableUnionType = firstArgType(nullableUnionMethod)
nullableIfaceType = firstArgType(nullableIfaceMethod)
harness.ok(nullableUnionType.isUnion(), "Should have union type");
harness.ok(nullableIfaceType.isInterface(), "Should have interface type");
harness.ok(nullableIfaceType.nullable(), "Should have nullable type");
harness.ok(not nullableUnionType.isDistinguishableFrom(nullableIfaceType),
"Nullable type not distinguishable from union with nullable "
"member type")
harness.ok(not nullableIfaceType.isDistinguishableFrom(nullableUnionType),
"Union with nullable member type not distinguishable from "
"nullable type")
parser = parser.reset()
parser.parse("""
interface TestIface {
void passKid(Kid arg);
void passParent(Parent arg);
void passGrandparent(Grandparent arg);
void passImplemented(Implemented arg);
void passImplementedParent(ImplementedParent arg);
void passUnrelated1(Unrelated1 arg);
void passUnrelated2(Unrelated2 arg);
void passArrayBuffer(ArrayBuffer arg);
void passArrayBuffer(ArrayBufferView arg);
};
interface Kid : Parent {};
interface Parent : Grandparent {};
interface Grandparent {};
interface Implemented : ImplementedParent {};
Parent implements Implemented;
interface ImplementedParent {};
interface Unrelated1 {};
interface Unrelated2 {};
""")
results = parser.finish()
iface = results[0]
harness.ok(iface.isInterface(), "Should have interface")
argTypes = [firstArgType(method) for method in iface.members]
unrelatedTypes = [firstArgType(method) for method in iface.members[-3:]]
for type1 in argTypes:
for type2 in argTypes:
distinguishable = (type1 is not type2 and
(type1 in unrelatedTypes or
type2 in unrelatedTypes))
harness.check(type1.isDistinguishableFrom(type2),
distinguishable,
"Type %s should %sbe distinguishable from type %s" %
(type1, "" if distinguishable else "not ", type2))
harness.check(type2.isDistinguishableFrom(type1),
distinguishable,
"Type %s should %sbe distinguishable from type %s" %
(type2, "" if distinguishable else "not ", type1))
parser = parser.reset()
parser.parse("""
interface Dummy {};
interface TestIface {
void method(long arg1, TestIface arg2);
void method(long arg1, long arg2);
void method(long arg1, Dummy arg2);
void method(DOMString arg1, DOMString arg2, DOMString arg3);
};
""")
results = parser.finish()
harness.check(len(results[1].members), 1,
"Should look like we have one method")
harness.check(len(results[1].members[0].signatures()), 4,
"Should have four signatures")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface Dummy {};
interface TestIface {
void method(long arg1, TestIface arg2);
void method(long arg1, long arg2);
void method(any arg1, Dummy arg2);
void method(DOMString arg1, DOMString arg2, DOMString arg3);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should throw when args before the distinguishing arg are not "
"all the same type")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface Dummy {};
interface TestIface {
void method(long arg1, TestIface arg2);
void method(long arg1, long arg2);
void method(any arg1, DOMString arg2);
void method(DOMString arg1, DOMString arg2, DOMString arg3);
};
""")
results = parser.finish()
except:
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>",
"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>" ]
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 + ["object"]))
setDistinguishable("sequence<short>",
allBut(argTypes, sequences + ["object"]))
setDistinguishable("MozMap<object>", nonUserObjects)
setDistinguishable("MozMap<Dict>", nonUserObjects)
setDistinguishable("MozMap<long>", nonUserObjects)
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)

View file

@ -0,0 +1,14 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface DoubleNull {
attribute byte?? foo;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View file

@ -0,0 +1,84 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface DuplicateQualifiers1 {
getter getter byte foo(unsigned long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface DuplicateQualifiers2 {
setter setter byte foo(unsigned long index, byte value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface DuplicateQualifiers3 {
creator creator byte foo(unsigned long index, byte value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface DuplicateQualifiers4 {
deleter deleter byte foo(unsigned long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface DuplicateQualifiers5 {
getter deleter getter byte foo(unsigned long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
results = parser.parse("""
interface DuplicateQualifiers6 {
creator setter creator byte foo(unsigned long index, byte value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View file

@ -0,0 +1,14 @@
import WebIDL
def WebIDLTest(parser, harness):
try:
parser.parse("""
enum TestEmptyEnum {
};
""")
harness.ok(False, "Should have thrown!")
except:
harness.ok(True, "Parsing TestEmptyEnum enum should fail")
results = parser.finish()

View file

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

View file

@ -0,0 +1,93 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
enum TestEnum {
"",
"foo",
"bar"
};
interface TestEnumInterface {
TestEnum doFoo(boolean arg);
readonly attribute TestEnum foo;
};
""")
results = parser.finish()
harness.ok(True, "TestEnumInterfaces interface parsed without error.")
harness.check(len(results), 2, "Should be one production")
harness.ok(isinstance(results[0], WebIDL.IDLEnum),
"Should be an IDLEnum")
harness.ok(isinstance(results[1], WebIDL.IDLInterface),
"Should be an IDLInterface")
enum = results[0]
harness.check(enum.identifier.QName(), "::TestEnum", "Enum has the right QName")
harness.check(enum.identifier.name, "TestEnum", "Enum has the right name")
harness.check(enum.values(), ["", "foo", "bar"], "Enum has the right values")
iface = results[1]
harness.check(iface.identifier.QName(), "::TestEnumInterface", "Interface has the right QName")
harness.check(iface.identifier.name, "TestEnumInterface", "Interface has the right name")
harness.check(iface.parent, None, "Interface has no parent")
members = iface.members
harness.check(len(members), 2, "Should be one production")
harness.ok(isinstance(members[0], WebIDL.IDLMethod),
"Should be an IDLMethod")
method = members[0]
harness.check(method.identifier.QName(), "::TestEnumInterface::doFoo",
"Method has correct QName")
harness.check(method.identifier.name, "doFoo", "Method has correct name")
signatures = method.signatures()
harness.check(len(signatures), 1, "Expect one signature")
(returnType, arguments) = signatures[0]
harness.check(str(returnType), "TestEnum (Wrapper)", "Method type is the correct name")
harness.check(len(arguments), 1, "Method has the right number of arguments")
arg = arguments[0]
harness.ok(isinstance(arg, WebIDL.IDLArgument), "Should be an IDLArgument")
harness.check(str(arg.type), "Boolean", "Argument has the right type")
attr = members[1]
harness.check(attr.identifier.QName(), "::TestEnumInterface::foo",
"Attr has correct QName")
harness.check(attr.identifier.name, "foo", "Attr has correct name")
harness.check(str(attr.type), "TestEnum (Wrapper)", "Attr type is the correct name")
# Now reset our parser
parser = parser.reset()
threw = False
try:
parser.parse("""
enum Enum {
"a",
"b",
"c"
};
interface TestInterface {
void foo(optional Enum e = "d");
};
""")
results = parser.finish()
except:
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")

View file

@ -0,0 +1,13 @@
import WebIDL
def WebIDLTest(parser, harness):
try:
parser.parse("""
enum TestEnumDuplicateValue {
"",
""
};
""")
harness.ok(False, "Should have thrown!")
except:
harness.ok(True, "Enum TestEnumDuplicateValue should throw")

View file

@ -0,0 +1,20 @@
import WebIDL
def WebIDLTest(parser, harness):
# Check that error messages put the '^' in the right place.
threw = False
input = 'interface ?'
try:
parser.parse(input)
results = parser.finish()
except WebIDL.WebIDLError, e:
threw = True
lines = str(e).split('\n')
harness.check(len(lines), 3, 'Expected number of lines in error message')
harness.check(lines[1], input, 'Second line shows error')
harness.check(lines[2], ' ' * (len(input) - 1) + '^',
'Correct column pointer in error message')
harness.ok(threw, "Should have thrown.")

View file

@ -0,0 +1,28 @@
import WebIDL
def WebIDLTest(parser, harness):
# Check that error messages put the '^' in the right place.
threw = False
input = """\
// This is a comment.
interface Foo {
};
/* This is also a comment. */
interface ?"""
try:
parser.parse(input)
results = parser.finish()
except WebIDL.WebIDLError, e:
threw = True
lines = str(e).split('\n')
harness.check(len(lines), 3, 'Expected number of lines in error message')
harness.ok(lines[0].endswith('line 6:10'), 'First line of error should end with "line 6:10", but was "%s".' % lines[0])
harness.check(lines[1], 'interface ?', 'Second line of error message is the line which caused the error.')
harness.check(lines[2], ' ' * (len('interface ?') - 1) + '^',
'Correct column pointer in error message.')
harness.ok(threw, "Should have thrown.")

View file

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

View file

@ -0,0 +1,107 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
[NoInterfaceObject]
interface TestExtendedAttr {
[Unforgeable] readonly attribute byte b;
};
""")
results = parser.finish()
parser = parser.reset()
parser.parse("""
[Pref="foo.bar",Pref=flop]
interface TestExtendedAttr {
[Pref="foo.bar"] attribute byte b;
};
""")
results = parser.finish()
parser = parser.reset()
parser.parse("""
interface TestLenientThis {
[LenientThis] attribute byte b;
};
""")
results = parser.finish()
harness.ok(results[0].members[0].hasLenientThis(),
"Should have a lenient this")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface TestLenientThis2 {
[LenientThis=something] attribute byte b;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "[LenientThis] must take no arguments")
parser = parser.reset()
parser.parse("""
interface TestClamp {
void testClamp([Clamp] long foo);
void testNotClamp(long foo);
};
""")
results = parser.finish()
# Pull out the first argument out of the arglist of the first (and
# only) signature.
harness.ok(results[0].members[0].signatures()[0][1][0].clamp,
"Should be clamped")
harness.ok(not results[0].members[1].signatures()[0][1][0].clamp,
"Should not be clamped")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface TestClamp2 {
void testClamp([Clamp=something] long foo);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "[Clamp] must take no arguments")
parser = parser.reset()
parser.parse("""
interface TestEnforceRange {
void testEnforceRange([EnforceRange] long foo);
void testNotEnforceRange(long foo);
};
""")
results = parser.finish()
# Pull out the first argument out of the arglist of the first (and
# only) signature.
harness.ok(results[0].members[0].signatures()[0][1][0].enforceRange,
"Should be enforceRange")
harness.ok(not results[0].members[1].signatures()[0][1][0].enforceRange,
"Should not be enforceRange")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface TestEnforceRange2 {
void testEnforceRange([EnforceRange=something] long foo);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "[EnforceRange] must take no arguments")

View file

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

View file

@ -0,0 +1,15 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface ForwardDeclared;
interface ForwardDeclared;
interface TestForwardDecl {
attribute ForwardDeclared foo;
};
""")
results = parser.finish()
harness.ok(True, "TestForwardDeclared interface parsed without error.")

View file

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

View file

@ -0,0 +1,39 @@
# Import the WebIDL module, so we can do isinstance checks and whatnot
import WebIDL
def WebIDLTest(parser, harness):
try:
parser.parse("""
enum Foo { "a" };
interface Foo;
""")
results = parser.finish()
harness.ok(False, "Should fail to parse")
except Exception, e:
harness.ok("Name collision" in e.message,
"Should have name collision for interface")
parser = parser.reset()
try:
parser.parse("""
dictionary Foo { long x; };
enum Foo { "a" };
""")
results = parser.finish()
harness.ok(False, "Should fail to parse")
except Exception, e:
harness.ok("Name collision" in e.message,
"Should have name collision for dictionary")
parser = parser.reset()
try:
parser.parse("""
enum Foo { "a" };
enum Foo { "b" };
""")
results = parser.finish()
harness.ok(False, "Should fail to parse")
except Exception, e:
harness.ok("Multiple unresolvable definitions" in e.message,
"Should have name collision for dictionary")

View file

@ -0,0 +1,216 @@
# Import the WebIDL module, so we can do isinstance checks and whatnot
import WebIDL
def WebIDLTest(parser, harness):
# Basic functionality
threw = False
try:
parser.parse("""
A implements B;
interface B {
attribute long x;
};
interface A {
attribute long y;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(not threw, "Should not have thrown on implements statement "
"before interfaces")
harness.check(len(results), 3, "We have three statements")
harness.ok(isinstance(results[1], WebIDL.IDLInterface), "B is an interface")
harness.check(len(results[1].members), 1, "B has one member")
A = results[2]
harness.ok(isinstance(A, WebIDL.IDLInterface), "A is an interface")
harness.check(len(A.members), 2, "A has two members")
harness.check(A.members[0].identifier.name, "y", "First member is 'y'")
harness.check(A.members[1].identifier.name, "x", "Second member is 'x'")
# Duplicated member names not allowed
threw = False
try:
parser.parse("""
C implements D;
interface D {
attribute long x;
};
interface C {
attribute long x;
};
""")
parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown on implemented interface duplicating "
"a name on base interface")
# Same, but duplicated across implemented interfaces
threw = False
try:
parser.parse("""
E implements F;
E implements G;
interface F {
attribute long x;
};
interface G {
attribute long x;
};
interface E {};
""")
parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown on implemented interfaces "
"duplicating each other's member names")
# Same, but duplicated across indirectly implemented interfaces
threw = False
try:
parser.parse("""
H implements I;
H implements J;
I implements K;
interface K {
attribute long x;
};
interface L {
attribute long x;
};
interface I {};
interface J : L {};
interface H {};
""")
parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown on indirectly implemented interfaces "
"duplicating each other's member names")
# Same, but duplicated across an implemented interface and its parent
threw = False
try:
parser.parse("""
M implements N;
interface O {
attribute long x;
};
interface N : O {
attribute long x;
};
interface M {};
""")
parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown on implemented interface and its "
"ancestor duplicating member names")
# Reset the parser so we can actually find things where we expect
# them in the list
parser = parser.reset()
# Diamonds should be allowed
threw = False
try:
parser.parse("""
P implements Q;
P implements R;
Q implements S;
R implements S;
interface Q {};
interface R {};
interface S {
attribute long x;
};
interface P {};
""")
results = parser.finish()
except:
threw = True
harness.ok(not threw, "Diamond inheritance is fine")
harness.check(results[6].identifier.name, "S", "We should be looking at 'S'")
harness.check(len(results[6].members), 1, "S should have one member")
harness.check(results[6].members[0].identifier.name, "x",
"S's member should be 'x'")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface TestInterface {
};
callback interface TestCallbackInterface {
};
TestInterface implements TestCallbackInterface;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should not allow callback interfaces on the right-hand side "
"of 'implements'")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface TestInterface {
};
callback interface TestCallbackInterface {
};
TestCallbackInterface implements TestInterface;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should not allow callback interfaces on the left-hand side of "
"'implements'")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface TestInterface {
};
dictionary Dict {
};
Dict implements TestInterface;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should not allow non-interfaces on the left-hand side "
"of 'implements'")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface TestInterface {
};
dictionary Dict {
};
TestInterface implements Dict;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should not allow non-interfaces on the right-hand side "
"of 'implements'")

View file

@ -0,0 +1,18 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestIncompleteParent : NotYetDefined {
void foo();
};
interface NotYetDefined : EvenHigherOnTheChain {
};
interface EvenHigherOnTheChain {
};
""")
parser.finish()
harness.ok(True, "TestIncompleteParent interface parsed without error.")

View file

@ -0,0 +1,44 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestIncompleteTypes {
attribute FooInterface attr1;
FooInterface method1(FooInterface arg);
};
interface FooInterface {
};
""")
results = parser.finish()
harness.ok(True, "TestIncompleteTypes interface parsed without error.")
harness.check(len(results), 2, "Should be two productions.")
iface = results[0]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestIncompleteTypes", "Interface has the right QName")
harness.check(iface.identifier.name, "TestIncompleteTypes", "Interface has the right name")
harness.check(len(iface.members), 2, "Expect 2 members")
attr = iface.members[0]
harness.ok(isinstance(attr, WebIDL.IDLAttribute),
"Should be an IDLAttribute")
method = iface.members[1]
harness.ok(isinstance(method, WebIDL.IDLMethod),
"Should be an IDLMethod")
harness.check(attr.identifier.QName(), "::TestIncompleteTypes::attr1",
"Attribute has the right QName")
harness.check(attr.type.name, "FooInterface",
"Previously unresolved type has the right name")
harness.check(method.identifier.QName(), "::TestIncompleteTypes::method1",
"Attribute has the right QName")
(returnType, args) = method.signatures()[0]
harness.check(returnType.name, "FooInterface",
"Previously unresolved type has the right name")
harness.check(args[0].type.name, "FooInterface",
"Previously unresolved type has the right name")

View file

@ -0,0 +1,405 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("interface Foo { };")
results = parser.finish()
harness.ok(True, "Empty interface parsed without error.")
harness.check(len(results), 1, "Should be one production")
harness.ok(isinstance(results[0], WebIDL.IDLInterface),
"Should be an IDLInterface")
iface = results[0]
harness.check(iface.identifier.QName(), "::Foo", "Interface has the right QName")
harness.check(iface.identifier.name, "Foo", "Interface has the right name")
harness.check(iface.parent, None, "Interface has no parent")
parser.parse("interface Bar : Foo { };")
results = parser.finish()
harness.ok(True, "Empty interface parsed without error.")
harness.check(len(results), 2, "Should be two productions")
harness.ok(isinstance(results[1], WebIDL.IDLInterface),
"Should be an IDLInterface")
iface = results[1]
harness.check(iface.identifier.QName(), "::Bar", "Interface has the right QName")
harness.check(iface.identifier.name, "Bar", "Interface has the right name")
harness.ok(isinstance(iface.parent, WebIDL.IDLInterface),
"Interface has a parent")
parser = parser.reset()
parser.parse("""
interface QNameBase {
attribute long foo;
};
interface QNameDerived : QNameBase {
attribute long long foo;
attribute byte bar;
};
""")
results = parser.finish()
harness.check(len(results), 2, "Should be two productions")
harness.ok(isinstance(results[0], WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.ok(isinstance(results[1], WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(results[1].parent, results[0], "Inheritance chain is right")
harness.check(len(results[0].members), 1, "Expect 1 productions")
harness.check(len(results[1].members), 2, "Expect 2 productions")
base = results[0]
derived = results[1]
harness.check(base.members[0].identifier.QName(), "::QNameBase::foo",
"Member has the right QName")
harness.check(derived.members[0].identifier.QName(), "::QNameDerived::foo",
"Member has the right QName")
harness.check(derived.members[1].identifier.QName(), "::QNameDerived::bar",
"Member has the right QName")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A : B {};
interface B : A {};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow cycles in interface inheritance chains")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A : C {};
interface C : B {};
interface B : A {};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow indirect cycles in interface inheritance chains")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A {};
interface B {};
A implements B;
B implements A;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow cycles via implements")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A {};
interface C {};
interface B {};
A implements C;
C implements B;
B implements A;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow indirect cycles via implements")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A : B {};
interface B {};
B implements A;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow inheriting from an interface that implements us")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A : B {};
interface B {};
interface C {};
B implements C;
C implements A;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow inheriting from an interface that indirectly implements us")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A : B {};
interface B : C {};
interface C {};
C implements A;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow indirectly inheriting from an interface that implements us")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A : B {};
interface B : C {};
interface C {};
interface D {};
C implements D;
D implements A;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow indirectly inheriting from an interface that indirectly implements us")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A;
interface B : A {};
""")
results = parser.finish()
except:
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")

View file

@ -0,0 +1,15 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface IdentifierConflict {
const byte thing1 = 1;
const unsigned long thing1 = 1;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View file

@ -0,0 +1,60 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface IdentifierConflictAcrossMembers1 {
const byte thing1 = 1;
readonly attribute long thing1;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface IdentifierConflictAcrossMembers2 {
readonly attribute long thing1;
const byte thing1 = 1;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface IdentifierConflictAcrossMembers3 {
getter boolean thing1(DOMString name);
readonly attribute long thing1;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface IdentifierConflictAcrossMembers1 {
const byte thing1 = 1;
long thing1();
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View file

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

View file

@ -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 [LenientSetter] extended attribute MUST take no arguments.
should_throw(parser, harness, "no arguments", """
interface I {
[LenientSetter=X] readonly attribute long A;
};
""")
# An attribute with the [LenientSetter] extended attribute MUST NOT
# also be declared with the [PutForwards] extended attribute.
should_throw(parser, harness, "PutForwards", """
interface I {
[PutForwards=B, LenientSetter] readonly attribute J A;
};
interface J {
attribute long B;
};
""")
# An attribute with the [LenientSetter] extended attribute MUST NOT
# also be declared with the [Replaceable] extended attribute.
should_throw(parser, harness, "Replaceable", """
interface I {
[Replaceable, LenientSetter] readonly attribute J A;
};
""")
# The [LenientSetter] extended attribute MUST NOT be used on an
# attribute that is not read only.
should_throw(parser, harness, "writable attribute", """
interface I {
[LenientSetter] attribute long A;
};
""")
# The [LenientSetter] extended attribute MUST NOT be used on a
# static attribute.
should_throw(parser, harness, "static attribute", """
interface I {
[LenientSetter] static readonly attribute long A;
};
""")

View file

@ -0,0 +1,178 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestMethods {
void basic();
static void basicStatic();
void basicWithSimpleArgs(boolean arg1, byte arg2, unsigned long arg3);
boolean basicBoolean();
static boolean basicStaticBoolean();
boolean basicBooleanWithSimpleArgs(boolean arg1, byte arg2, unsigned long arg3);
void optionalArg(optional byte? arg1, optional sequence<byte> arg2);
void variadicArg(byte?... arg1);
object getObject();
void setObject(object arg1);
void setAny(any arg1);
float doFloats(float arg1);
};
""")
results = parser.finish()
harness.ok(True, "TestMethods interface parsed without error.")
harness.check(len(results), 1, "Should be one production.")
iface = results[0]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestMethods", "Interface has the right QName")
harness.check(iface.identifier.name, "TestMethods", "Interface has the right name")
harness.check(len(iface.members), 12, "Expect 12 members")
methods = iface.members
def checkArgument(argument, QName, name, type, optional, variadic):
harness.ok(isinstance(argument, WebIDL.IDLArgument),
"Should be an IDLArgument")
harness.check(argument.identifier.QName(), QName, "Argument has the right QName")
harness.check(argument.identifier.name, name, "Argument has the right name")
harness.check(str(argument.type), type, "Argument has the right return type")
harness.check(argument.optional, optional, "Argument has the right optional value")
harness.check(argument.variadic, variadic, "Argument has the right variadic value")
def checkMethod(method, QName, name, signatures,
static=False, getter=False, setter=False, creator=False,
deleter=False, legacycaller=False, stringifier=False):
harness.ok(isinstance(method, WebIDL.IDLMethod),
"Should be an IDLMethod")
harness.ok(method.isMethod(), "Method is a method")
harness.ok(not method.isAttr(), "Method is not an attr")
harness.ok(not method.isConst(), "Method is not a const")
harness.check(method.identifier.QName(), QName, "Method has the right QName")
harness.check(method.identifier.name, name, "Method has the right name")
harness.check(method.isStatic(), static, "Method has the correct static value")
harness.check(method.isGetter(), getter, "Method has the correct getter value")
harness.check(method.isSetter(), setter, "Method has the correct setter value")
harness.check(method.isCreator(), creator, "Method has the correct creator value")
harness.check(method.isDeleter(), deleter, "Method has the correct deleter value")
harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value")
harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value")
harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures")
sigpairs = zip(method.signatures(), signatures)
for (gotSignature, expectedSignature) in sigpairs:
(gotRetType, gotArgs) = gotSignature
(expectedRetType, expectedArgs) = expectedSignature
harness.check(str(gotRetType), expectedRetType,
"Method has the expected return type.")
for i in range(0, len(gotArgs)):
(QName, name, type, optional, variadic) = expectedArgs[i]
checkArgument(gotArgs[i], QName, name, type, optional, variadic)
checkMethod(methods[0], "::TestMethods::basic", "basic", [("Void", [])])
checkMethod(methods[1], "::TestMethods::basicStatic", "basicStatic",
[("Void", [])], static=True)
checkMethod(methods[2], "::TestMethods::basicWithSimpleArgs",
"basicWithSimpleArgs",
[("Void",
[("::TestMethods::basicWithSimpleArgs::arg1", "arg1", "Boolean", False, False),
("::TestMethods::basicWithSimpleArgs::arg2", "arg2", "Byte", False, False),
("::TestMethods::basicWithSimpleArgs::arg3", "arg3", "UnsignedLong", False, False)])])
checkMethod(methods[3], "::TestMethods::basicBoolean", "basicBoolean", [("Boolean", [])])
checkMethod(methods[4], "::TestMethods::basicStaticBoolean", "basicStaticBoolean", [("Boolean", [])], static=True)
checkMethod(methods[5], "::TestMethods::basicBooleanWithSimpleArgs",
"basicBooleanWithSimpleArgs",
[("Boolean",
[("::TestMethods::basicBooleanWithSimpleArgs::arg1", "arg1", "Boolean", False, False),
("::TestMethods::basicBooleanWithSimpleArgs::arg2", "arg2", "Byte", False, False),
("::TestMethods::basicBooleanWithSimpleArgs::arg3", "arg3", "UnsignedLong", False, False)])])
checkMethod(methods[6], "::TestMethods::optionalArg",
"optionalArg",
[("Void",
[("::TestMethods::optionalArg::arg1", "arg1", "ByteOrNull", True, False),
("::TestMethods::optionalArg::arg2", "arg2", "ByteSequence", True, False)])])
checkMethod(methods[7], "::TestMethods::variadicArg",
"variadicArg",
[("Void",
[("::TestMethods::variadicArg::arg1", "arg1", "ByteOrNull", True, True)])])
checkMethod(methods[8], "::TestMethods::getObject",
"getObject", [("Object", [])])
checkMethod(methods[9], "::TestMethods::setObject",
"setObject",
[("Void",
[("::TestMethods::setObject::arg1", "arg1", "Object", False, False)])])
checkMethod(methods[10], "::TestMethods::setAny",
"setAny",
[("Void",
[("::TestMethods::setAny::arg1", "arg1", "Any", False, False)])])
checkMethod(methods[11], "::TestMethods::doFloats",
"doFloats",
[("Float",
[("::TestMethods::doFloats::arg1", "arg1", "Float", False, False)])])
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A {
void foo(optional float bar = 1);
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(not threw, "Should allow integer to float type corecion")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface A {
[GetterThrows] void foo();
};
""")
results = parser.finish()
except Exception, x:
threw = True
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")

View file

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

View file

@ -0,0 +1,223 @@
def WebIDLTest(parser, harness):
parser.parse(
"""
namespace MyNamespace {
attribute any foo;
any bar();
};
""")
results = parser.finish()
harness.check(len(results), 1, "Should have a thing.")
harness.ok(results[0].isNamespace(), "Our thing should be a namespace");
harness.check(len(results[0].members), 2,
"Should have two things in our namespace")
harness.ok(results[0].members[0].isAttr(), "First member is attribute")
harness.ok(results[0].members[0].isStatic(), "Attribute should be static")
harness.ok(results[0].members[1].isMethod(), "Second member is method")
harness.ok(results[0].members[1].isStatic(), "Operation should be static")
parser = parser.reset()
parser.parse(
"""
namespace MyNamespace {
attribute any foo;
};
partial namespace MyNamespace {
any bar();
};
""")
results = parser.finish()
harness.check(len(results), 2, "Should have things.")
harness.ok(results[0].isNamespace(), "Our thing should be a namespace");
harness.check(len(results[0].members), 2,
"Should have two things in our namespace")
harness.ok(results[0].members[0].isAttr(), "First member is attribute")
harness.ok(results[0].members[0].isStatic(), "Attribute should be static");
harness.ok(results[0].members[1].isMethod(), "Second member is method")
harness.ok(results[0].members[1].isStatic(), "Operation should be static");
parser = parser.reset()
parser.parse(
"""
partial namespace MyNamespace {
any bar();
};
namespace MyNamespace {
attribute any foo;
};
""")
results = parser.finish()
harness.check(len(results), 2, "Should have things.")
harness.ok(results[1].isNamespace(), "Our thing should be a namespace");
harness.check(len(results[1].members), 2,
"Should have two things in our namespace")
harness.ok(results[1].members[0].isAttr(), "First member is attribute")
harness.ok(results[1].members[0].isStatic(), "Attribute should be static");
harness.ok(results[1].members[1].isMethod(), "Second member is method")
harness.ok(results[1].members[1].isStatic(), "Operation should be static");
parser = parser.reset()
threw = False
try:
parser.parse(
"""
namespace MyNamespace {
static attribute any foo;
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse(
"""
namespace MyNamespace {
static any bar();
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse(
"""
namespace MyNamespace {
any bar();
};
interface MyNamespace {
any baz();
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse(
"""
interface MyNamespace {
any baz();
};
namespace MyNamespace {
any bar();
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse(
"""
namespace MyNamespace {
any baz();
};
namespace MyNamespace {
any bar();
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse(
"""
partial namespace MyNamespace {
any baz();
};
interface MyNamespace {
any bar();
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse(
"""
namespace MyNamespace {
any bar();
};
partial interface MyNamespace {
any baz();
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse(
"""
partial interface MyNamespace {
any baz();
};
namespace MyNamespace {
any bar();
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse(
"""
interface MyNamespace {
any bar();
};
partial namespace MyNamespace {
any baz();
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should have thrown.")

View file

@ -0,0 +1,70 @@
# Import the WebIDL module, so we can do isinstance checks and whatnot
import WebIDL
def WebIDLTest(parser, harness):
# Basic functionality
parser.parse(
"""
interface Iface {
[NewObject] readonly attribute Iface attr;
[NewObject] Iface method();
};
""")
results = parser.finish()
harness.ok(results, "Should not have thrown on basic [NewObject] usage")
parser = parser.reset()
threw = False
try:
parser.parse(
"""
interface Iface {
[Pure, NewObject] readonly attribute Iface attr;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "[NewObject] attributes must depend on something")
parser = parser.reset()
threw = False
try:
parser.parse(
"""
interface Iface {
[Pure, NewObject] Iface method();
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "[NewObject] methods must depend on something")
parser = parser.reset()
threw = False
try:
parser.parse(
"""
interface Iface {
[Cached, NewObject, Affects=Nothing] readonly attribute Iface attr;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "[NewObject] attributes must not be [Cached]")
parser = parser.reset()
threw = False
try:
parser.parse(
"""
interface Iface {
[StoreInSlot, NewObject, Affects=Nothing] readonly attribute Iface attr;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "[NewObject] attributes must not be [StoreInSlot]")

View file

@ -0,0 +1,115 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestNullableEquivalency1 {
attribute long a;
attribute long? b;
};
interface TestNullableEquivalency2 {
attribute ArrayBuffer a;
attribute ArrayBuffer? b;
};
/* Can't have dictionary-valued attributes, so can't test that here */
enum TestNullableEquivalency4Enum {
"Foo",
"Bar"
};
interface TestNullableEquivalency4 {
attribute TestNullableEquivalency4Enum a;
attribute TestNullableEquivalency4Enum? b;
};
interface TestNullableEquivalency5 {
attribute TestNullableEquivalency4 a;
attribute TestNullableEquivalency4? b;
};
interface TestNullableEquivalency6 {
attribute boolean a;
attribute boolean? b;
};
interface TestNullableEquivalency7 {
attribute DOMString a;
attribute DOMString? b;
};
interface TestNullableEquivalency8 {
attribute float a;
attribute float? b;
};
interface TestNullableEquivalency9 {
attribute double a;
attribute double? b;
};
interface TestNullableEquivalency10 {
attribute object a;
attribute object? b;
};
""")
for decl in parser.finish():
if decl.isInterface():
checkEquivalent(decl, harness)
def checkEquivalent(iface, harness):
type1 = iface.members[0].type
type2 = iface.members[1].type
harness.check(type1.nullable(), False, 'attr1 should not be nullable')
harness.check(type2.nullable(), True, 'attr2 should be nullable')
# We don't know about type1, but type2, the nullable type, definitely
# shouldn't be builtin.
harness.check(type2.builtin, False, 'attr2 should not be builtin')
# Ensure that all attributes of type2 match those in type1, except for:
# - names on an ignore list,
# - names beginning with '_',
# - functions which throw when called with no args, and
# - class-level non-callables ("static variables").
#
# Yes, this is an ugly, fragile hack. But it finds bugs...
for attr in dir(type1):
if attr.startswith('_') or \
attr in ['nullable', 'builtin', 'filename', 'location',
'inner', 'QName', 'getDeps', 'name'] or \
(hasattr(type(type1), attr) and not callable(getattr(type1, attr))):
continue
a1 = getattr(type1, attr)
if callable(a1):
try:
v1 = a1()
except:
# Can't call a1 with no args, so skip this attriute.
continue
try:
a2 = getattr(type2, attr)
except:
harness.ok(False, 'Missing %s attribute on type %s in %s' % (attr, type2, iface))
continue
if not callable(a2):
harness.ok(False, "%s attribute on type %s in %s wasn't callable" % (attr, type2, iface))
continue
v2 = a2()
harness.check(v2, v1, '%s method return value' % attr)
else:
try:
a2 = getattr(type2, attr)
except:
harness.ok(False, 'Missing %s attribute on type %s in %s' % (attr, type2, iface))
continue
harness.check(a2, a1, '%s attribute should match' % attr)

View file

@ -0,0 +1,14 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface NullableVoid {
void? foo();
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View file

@ -0,0 +1,30 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface OptionalConstraints1 {
void foo(optional byte arg1, byte arg2);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(not threw,
"Should not have thrown on non-optional argument following "
"optional argument.")
parser = parser.reset()
parser.parse("""
interface OptionalConstraints2 {
void foo(optional byte arg1 = 1, optional byte arg2 = 2,
optional byte arg3, optional byte arg4 = 4,
optional byte arg5, optional byte arg6 = 9);
};
""")
results = parser.finish()
args = results[0].members[0].signatures()[0][1]
harness.check(len(args), 6, "Should have 6 arguments")
harness.check(args[5].defaultValue.value, 9,
"Should have correct default value")

View file

@ -0,0 +1,60 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestOverloads {
void basic();
void basic(long arg1);
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);
};
""")
results = parser.finish()
harness.ok(True, "TestOverloads interface parsed without error.")
harness.check(len(results), 1, "Should be one production.")
iface = results[0]
harness.ok(isinstance(iface, WebIDL.IDLInterface),
"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), 4, "Expect %s members" % 4)
member = iface.members[0]
harness.check(member.identifier.QName(), "::TestOverloads::basic", "Method has the right QName")
harness.check(member.identifier.name, "basic", "Method has the right name")
harness.check(member.hasOverloads(), True, "Method has overloads")
signatures = member.signatures()
harness.check(len(signatures), 2, "Method should have 2 signatures")
(retval, argumentSet) = signatures[0]
harness.check(str(retval), "Void", "Expect a void retval")
harness.check(len(argumentSet), 0, "Expect an empty argument set")
(retval, argumentSet) = signatures[1]
harness.check(str(retval), "Void", "Expect a void retval")
harness.check(len(argumentSet), 1, "Expect an argument set with one argument")
argument = argumentSet[0]
harness.ok(isinstance(argument, WebIDL.IDLArgument),
"Should be an IDLArgument")
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")

View file

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

View file

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

View file

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

View file

@ -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;
};
""")

View file

@ -0,0 +1,7 @@
def WebIDLTest(parser, harness):
parser.parse("")
parser.finish()
harness.ok(True, "Parsing nothing doesn't throw.")
parser.parse("interface Foo {};")
parser.finish()
harness.ok(True, "Parsing a silly interface doesn't throw.")

View file

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

View file

@ -0,0 +1,294 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch1 {
getter long long foo(long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch2 {
getter void foo(unsigned long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch3 {
getter boolean foo(unsigned long index, boolean extraArg);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch4 {
getter boolean foo(unsigned long... index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch5 {
getter boolean foo(optional unsigned long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch6 {
getter boolean foo();
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch7 {
deleter long long foo(long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch9 {
deleter boolean foo(unsigned long index, boolean extraArg);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch10 {
deleter boolean foo(unsigned long... index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch11 {
deleter boolean foo(optional unsigned long index);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch12 {
deleter boolean foo();
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch13 {
setter long long foo(long index, long long value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch15 {
setter boolean foo(unsigned long index, boolean value, long long extraArg);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch16 {
setter boolean foo(unsigned long index, boolean... value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch17 {
setter boolean foo(unsigned long index, optional boolean value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch18 {
setter boolean foo();
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch20 {
creator long long foo(long index, long long value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch22 {
creator boolean foo(unsigned long index, boolean value, long long extraArg);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch23 {
creator boolean foo(unsigned long index, boolean... value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch24 {
creator boolean foo(unsigned long index, optional boolean value);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodSignatureMismatch25 {
creator boolean foo();
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View file

@ -0,0 +1,85 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface SpecialMethods {
getter long long (unsigned long index);
setter long long (unsigned long index, long long value);
creator long long (unsigned long index, long long value);
getter boolean (DOMString name);
setter boolean (DOMString name, boolean value);
creator boolean (DOMString name, boolean value);
deleter boolean (DOMString name);
};
interface SpecialMethodsCombination {
setter creator long long (unsigned long index, long long value);
getter deleter boolean (DOMString name);
setter creator boolean (DOMString name, boolean value);
};
""")
results = parser.finish()
def checkMethod(method, QName, name,
static=False, getter=False, setter=False, creator=False,
deleter=False, legacycaller=False, stringifier=False):
harness.ok(isinstance(method, WebIDL.IDLMethod),
"Should be an IDLMethod")
harness.check(method.identifier.QName(), QName, "Method has the right QName")
harness.check(method.identifier.name, name, "Method has the right name")
harness.check(method.isStatic(), static, "Method has the correct static value")
harness.check(method.isGetter(), getter, "Method has the correct getter value")
harness.check(method.isSetter(), setter, "Method has the correct setter value")
harness.check(method.isCreator(), creator, "Method has the correct creator value")
harness.check(method.isDeleter(), deleter, "Method has the correct deleter value")
harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value")
harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value")
harness.check(len(results), 2, "Expect 2 interfaces")
iface = results[0]
harness.check(len(iface.members), 7, "Expect 7 members")
checkMethod(iface.members[0], "::SpecialMethods::__indexedgetter", "__indexedgetter",
getter=True)
checkMethod(iface.members[1], "::SpecialMethods::__indexedsetter", "__indexedsetter",
setter=True)
checkMethod(iface.members[2], "::SpecialMethods::__indexedcreator", "__indexedcreator",
creator=True)
checkMethod(iface.members[3], "::SpecialMethods::__namedgetter", "__namedgetter",
getter=True)
checkMethod(iface.members[4], "::SpecialMethods::__namedsetter", "__namedsetter",
setter=True)
checkMethod(iface.members[5], "::SpecialMethods::__namedcreator", "__namedcreator",
creator=True)
checkMethod(iface.members[6], "::SpecialMethods::__nameddeleter", "__nameddeleter",
deleter=True)
iface = results[1]
harness.check(len(iface.members), 3, "Expect 3 members")
checkMethod(iface.members[0], "::SpecialMethodsCombination::__indexedsettercreator",
"__indexedsettercreator", setter=True, creator=True)
checkMethod(iface.members[1], "::SpecialMethodsCombination::__namedgetterdeleter",
"__namedgetterdeleter", getter=True, deleter=True)
checkMethod(iface.members[2], "::SpecialMethodsCombination::__namedsettercreator",
"__namedsettercreator", setter=True, creator=True)
parser = parser.reset();
threw = False
try:
parser.parse(
"""
interface IndexedDeleter {
deleter void(unsigned long index);
};
""")
parser.finish()
except:
threw = True
harness.ok(threw, "There are no indexed deleters")

View file

@ -0,0 +1,62 @@
import WebIDL
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface SpecialMethodUniqueness1 {
getter deleter boolean (DOMString name);
getter boolean (DOMString name);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodUniqueness1 {
deleter boolean (DOMString name);
getter deleter boolean (DOMString name);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodUniqueness1 {
setter creator boolean (DOMString name);
creator boolean (DOMString name);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
threw = False
try:
parser.parse("""
interface SpecialMethodUniqueness1 {
setter boolean (DOMString name);
creator setter boolean (DOMString name);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View file

@ -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()'")

View file

@ -0,0 +1,71 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
[TreatNonCallableAsNull] callback Function = any(any... arguments);
interface TestTreatNonCallableAsNull1 {
attribute Function? onfoo;
attribute Function onbar;
};
""")
results = parser.finish()
iface = results[1]
attr = iface.members[0]
harness.check(attr.type.treatNonCallableAsNull(), True, "Got the expected value")
attr = iface.members[1]
harness.check(attr.type.treatNonCallableAsNull(), False, "Got the expected value")
parser = parser.reset()
threw = False
try:
parser.parse("""
callback Function = any(any... arguments);
interface TestTreatNonCallableAsNull2 {
[TreatNonCallableAsNull] attribute Function onfoo;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
callback Function = any(any... arguments);
[TreatNonCallableAsNull]
interface TestTreatNonCallableAsNull3 {
attribute Function onfoo;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
[TreatNonCallableAsNull, TreatNonObjectAsNull]
callback Function = any(any... arguments);
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View file

@ -0,0 +1,76 @@
def WebIDLTest(parser, harness):
parser.parse("""
typedef long mylong;
typedef long? mynullablelong;
interface Foo {
const mylong X = 5;
const mynullablelong Y = 7;
const mynullablelong Z = null;
void foo(mylong arg);
};
""")
results = parser.finish()
harness.check(results[2].members[1].type.name, "LongOrNull",
"Should expand typedefs")
parser = parser.reset()
threw = False
try:
parser.parse("""
typedef long? mynullablelong;
interface Foo {
void foo(mynullablelong? Y);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown on nullable inside nullable arg.")
parser = parser.reset()
threw = False
try:
parser.parse("""
typedef long? mynullablelong;
interface Foo {
const mynullablelong? X = 5;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown on nullable inside nullable const.")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface Foo {
const mynullablelong? X = 5;
};
typedef long? mynullablelong;
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should have thrown on nullable inside nullable const typedef "
"after interface.")
parser = parser.reset()
parser.parse("""
interface Foo {
const mylong X = 5;
};
typedef long mylong;
""")
results = parser.finish()
harness.check(results[0].members[0].type.name, "Long",
"Should expand typedefs that come before interface")

View file

@ -0,0 +1,64 @@
def WebIDLTest(parser, harness):
parser.parse(
"""
interface Foo {};
[LegacyUnenumerableNamedProperties]
interface Bar : Foo {
getter long(DOMString name);
};
interface Baz : Bar {
getter long(DOMString name);
};
""");
results = parser.finish();
harness.check(len(results), 3, "Should have three interfaces")
parser = parser.reset()
threw = False
try:
parser.parse("""
[LegacyUnenumerableNamedProperties]
interface NoNamedGetter {
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
[LegacyUnenumerableNamedProperties=Foo]
interface ShouldNotHaveArg {
getter long(DOMString name);
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
[LegacyUnenumerableNamedProperties]
interface Foo {
getter long(DOMString name);
};
interface Bar : Foo {};
[LegacyUnenumerableNamedProperties]
interface Baz : Bar {
getter long(DOMString name);
};
""")
results = parser.finish()
except Exception, x:
threw = True
harness.ok(threw, "Should have thrown.")

View file

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

View file

@ -0,0 +1,168 @@
import WebIDL
import itertools
import string
# We'd like to use itertools.chain but it's 2.6 or higher.
def chain(*iterables):
# chain('ABC', 'DEF') --> A B C D E F
for it in iterables:
for element in it:
yield element
# We'd like to use itertools.combinations but it's 2.6 or higher.
def combinations(iterable, r):
# combinations('ABCD', 2) --> AB AC AD BC BD CD
# combinations(range(4), 3) --> 012 013 023 123
pool = tuple(iterable)
n = len(pool)
if r > n:
return
indices = range(r)
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
if indices[i] != i + n - r:
break
else:
return
indices[i] += 1
for j in range(i+1, r):
indices[j] = indices[j-1] + 1
yield tuple(pool[i] for i in indices)
# We'd like to use itertools.combinations_with_replacement but it's 2.7 or
# higher.
def combinations_with_replacement(iterable, r):
# combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
pool = tuple(iterable)
n = len(pool)
if not n and r:
return
indices = [0] * r
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(range(r)):
if indices[i] != n - 1:
break
else:
return
indices[i:] = [indices[i] + 1] * (r - i)
yield tuple(pool[i] for i in indices)
def WebIDLTest(parser, harness):
types = ["float",
"double",
"short",
"unsigned short",
"long",
"unsigned long",
"long long",
"unsigned long long",
"boolean",
"byte",
"octet",
"DOMString",
"ByteString",
"USVString",
#"sequence<float>",
"object",
"ArrayBuffer",
#"Date",
"TestInterface1",
"TestInterface2"]
testPre = """
interface TestInterface1 {
};
interface TestInterface2 {
};
"""
interface = testPre + """
interface PrepareForTest {
"""
for (i, type) in enumerate(types):
interface += string.Template("""
readonly attribute ${type} attr${i};
""").substitute(i=i, type=type)
interface += """
};
"""
parser.parse(interface)
results = parser.finish()
iface = results[2]
parser = parser.reset()
def typesAreDistinguishable(t):
return all(u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2))
def typesAreNotDistinguishable(t):
return any(not u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2))
def unionTypeName(t):
if len(t) > 2:
t[0:2] = [unionTypeName(t[0:2])]
return "(" + " or ".join(t) + ")"
# typeCombinations is an iterable of tuples containing the name of the type
# as a string and the parsed IDL type.
def unionTypes(typeCombinations, predicate):
for c in typeCombinations:
if predicate(t[1] for t in c):
yield unionTypeName([t[0] for t in c])
# We limit invalid union types with a union member type to the subset of 3
# types with one invalid combination.
# typeCombinations is an iterable of tuples containing the name of the type
# as a string and the parsed IDL type.
def invalidUnionWithUnion(typeCombinations):
for c in typeCombinations:
if (typesAreNotDistinguishable((c[0][1], c[1][1])) and
typesAreDistinguishable((c[1][1], c[2][1])) and
typesAreDistinguishable((c[0][1], c[2][1]))):
yield unionTypeName([t[0] for t in c])
# Create a list of tuples containing the name of the type as a string and
# the parsed IDL type.
types = zip(types, (a.type for a in iface.members))
validUnionTypes = chain(unionTypes(combinations(types, 2), typesAreDistinguishable),
unionTypes(combinations(types, 3), typesAreDistinguishable))
invalidUnionTypes = chain(unionTypes(combinations_with_replacement(types, 2), typesAreNotDistinguishable),
invalidUnionWithUnion(combinations(types, 3)))
interface = testPre + """
interface TestUnion {
"""
for (i, type) in enumerate(validUnionTypes):
interface += string.Template("""
void method${i}(${type} arg);
${type} returnMethod${i}();
attribute ${type} attr${i};
void optionalMethod${i}(${type}? arg);
""").substitute(i=i, type=type)
interface += """
};
"""
parser.parse(interface)
results = parser.finish()
parser = parser.reset()
for invalid in invalidUnionTypes:
interface = testPre + string.Template("""
interface TestUnion {
void method(${type} arg);
};
""").substitute(type=invalid)
threw = False
try:
parser.parse(interface)
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")
parser = parser.reset()

View file

@ -0,0 +1,14 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface AnyNotInUnion {
void foo((any or DOMString) arg);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown.")

View file

@ -0,0 +1,53 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface OneNullableInUnion {
void foo((object? or DOMString?) arg);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Two nullable member types of a union should have thrown.")
parser.reset()
threw = False
try:
parser.parse("""
interface NullableInNullableUnion {
void foo((object? or DOMString)? arg);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"A nullable union type with a nullable member type should have "
"thrown.")
parser.reset()
threw = False
try:
parser.parse("""
interface NullableInUnionNullableUnionHelper {
};
interface NullableInUnionNullableUnion {
void foo(((object? or DOMString) or NullableInUnionNullableUnionHelper)? arg);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"A nullable union type with a nullable member type should have "
"thrown.")

View file

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

View file

@ -0,0 +1,10 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
callback TestVariadicCallback = any(any... arguments);
""")
results = parser.finish()
harness.ok(True, "TestVariadicCallback callback parsed without error.")

View file

@ -0,0 +1,63 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
interface VariadicConstraints1 {
void foo(byte... arg1, byte arg2);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should have thrown on variadic argument followed by required "
"argument.")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface VariadicConstraints2 {
void foo(byte... arg1, optional byte arg2);
};
""")
results = parser.finish();
except:
threw = True
harness.ok(threw,
"Should have thrown on variadic argument followed by optional "
"argument.")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface VariadicConstraints3 {
void foo(optional byte... arg1);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should have thrown on variadic argument explicitly flagged as "
"optional.")
parser = parser.reset()
threw = False
try:
parser.parse("""
interface VariadicConstraints4 {
void foo(byte... arg1 = 0);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should have thrown on variadic argument with default value.")