mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-06 07:17:30 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
1
dom/bindings/parser/README
Normal file
1
dom/bindings/parser/README
Normal file
|
|
@ -0,0 +1 @@
|
|||
A WebIDL parser written in Python to be used in Mozilla.
|
||||
1
dom/bindings/parser/UPSTREAM
Normal file
1
dom/bindings/parser/UPSTREAM
Normal 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
|
||||
6874
dom/bindings/parser/WebIDL.py
Normal file
6874
dom/bindings/parser/WebIDL.py
Normal file
File diff suppressed because it is too large
Load diff
108
dom/bindings/parser/runtests.py
Normal file
108
dom/bindings/parser/runtests.py
Normal 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)
|
||||
14
dom/bindings/parser/tests/test_any_null.py
Normal file
14
dom/bindings/parser/tests/test_any_null.py
Normal 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.")
|
||||
|
|
@ -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.")
|
||||
14
dom/bindings/parser/tests/test_argument_novoid.py
Normal file
14
dom/bindings/parser/tests/test_argument_novoid.py
Normal 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.")
|
||||
81
dom/bindings/parser/tests/test_arraybuffer.py
Normal file
81
dom/bindings/parser/tests/test_arraybuffer.py
Normal 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")
|
||||
177
dom/bindings/parser/tests/test_attr.py
Normal file
177
dom/bindings/parser/tests/test_attr.py
Normal 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")
|
||||
67
dom/bindings/parser/tests/test_attr_sequence_type.py
Normal file
67
dom/bindings/parser/tests/test_attr_sequence_type.py
Normal 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")
|
||||
11
dom/bindings/parser/tests/test_builtin_filename.py
Normal file
11
dom/bindings/parser/tests/test_builtin_filename.py
Normal 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')
|
||||
41
dom/bindings/parser/tests/test_builtins.py
Normal file
41
dom/bindings/parser/tests/test_builtins.py
Normal 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")
|
||||
99
dom/bindings/parser/tests/test_bytestring.py
Normal file
99
dom/bindings/parser/tests/test_bytestring.py
Normal 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")
|
||||
34
dom/bindings/parser/tests/test_callback.py
Normal file
34
dom/bindings/parser/tests/test_callback.py
Normal 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")
|
||||
94
dom/bindings/parser/tests/test_callback_interface.py
Normal file
94
dom/bindings/parser/tests/test_callback_interface.py
Normal 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)
|
||||
110
dom/bindings/parser/tests/test_conditional_dictionary_member.py
Normal file
110
dom/bindings/parser/tests/test_conditional_dictionary_member.py
Normal 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)")
|
||||
80
dom/bindings/parser/tests/test_const.py
Normal file
80
dom/bindings/parser/tests/test_const.py
Normal 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.")
|
||||
|
||||
109
dom/bindings/parser/tests/test_constructor.py
Normal file
109
dom/bindings/parser/tests/test_constructor.py
Normal 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")
|
||||
|
|
@ -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 {
|
||||
};
|
||||
""")
|
||||
15
dom/bindings/parser/tests/test_date.py
Normal file
15
dom/bindings/parser/tests/test_date.py
Normal 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")
|
||||
15
dom/bindings/parser/tests/test_deduplicate.py
Normal file
15
dom/bindings/parser/tests/test_deduplicate.py
Normal 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.")
|
||||
555
dom/bindings/parser/tests/test_dictionary.py
Normal file
555
dom/bindings/parser/tests/test_dictionary.py
Normal 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")
|
||||
293
dom/bindings/parser/tests/test_distinguishability.py
Normal file
293
dom/bindings/parser/tests/test_distinguishability.py
Normal 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)
|
||||
14
dom/bindings/parser/tests/test_double_null.py
Normal file
14
dom/bindings/parser/tests/test_double_null.py
Normal 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.")
|
||||
84
dom/bindings/parser/tests/test_duplicate_qualifiers.py
Normal file
84
dom/bindings/parser/tests/test_duplicate_qualifiers.py
Normal 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.")
|
||||
14
dom/bindings/parser/tests/test_empty_enum.py
Normal file
14
dom/bindings/parser/tests/test_empty_enum.py
Normal 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()
|
||||
|
|
@ -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")
|
||||
|
||||
93
dom/bindings/parser/tests/test_enum.py
Normal file
93
dom/bindings/parser/tests/test_enum.py
Normal 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")
|
||||
13
dom/bindings/parser/tests/test_enum_duplicate_values.py
Normal file
13
dom/bindings/parser/tests/test_enum_duplicate_values.py
Normal 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")
|
||||
20
dom/bindings/parser/tests/test_error_colno.py
Normal file
20
dom/bindings/parser/tests/test_error_colno.py
Normal 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.")
|
||||
28
dom/bindings/parser/tests/test_error_lineno.py
Normal file
28
dom/bindings/parser/tests/test_error_lineno.py
Normal 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.")
|
||||
|
||||
222
dom/bindings/parser/tests/test_exposed_extended_attribute.py
Normal file
222
dom/bindings/parser/tests/test_exposed_extended_attribute.py
Normal 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.")
|
||||
107
dom/bindings/parser/tests/test_extended_attributes.py
Normal file
107
dom/bindings/parser/tests/test_extended_attributes.py
Normal 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")
|
||||
|
||||
125
dom/bindings/parser/tests/test_float_types.py
Normal file
125
dom/bindings/parser/tests/test_float_types.py
Normal 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")
|
||||
15
dom/bindings/parser/tests/test_forward_decl.py
Normal file
15
dom/bindings/parser/tests/test_forward_decl.py
Normal 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.")
|
||||
122
dom/bindings/parser/tests/test_global_extended_attr.py
Normal file
122
dom/bindings/parser/tests/test_global_extended_attr.py
Normal 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")
|
||||
39
dom/bindings/parser/tests/test_identifier_conflict.py
Normal file
39
dom/bindings/parser/tests/test_identifier_conflict.py
Normal 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")
|
||||
|
||||
216
dom/bindings/parser/tests/test_implements.py
Normal file
216
dom/bindings/parser/tests/test_implements.py
Normal 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'")
|
||||
|
||||
18
dom/bindings/parser/tests/test_incomplete_parent.py
Normal file
18
dom/bindings/parser/tests/test_incomplete_parent.py
Normal 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.")
|
||||
44
dom/bindings/parser/tests/test_incomplete_types.py
Normal file
44
dom/bindings/parser/tests/test_incomplete_types.py
Normal 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")
|
||||
405
dom/bindings/parser/tests/test_interface.py
Normal file
405
dom/bindings/parser/tests/test_interface.py
Normal 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")
|
||||
|
|
@ -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.")
|
||||
|
|
@ -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.")
|
||||
|
|
@ -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)
|
||||
58
dom/bindings/parser/tests/test_lenientSetter.py
Normal file
58
dom/bindings/parser/tests/test_lenientSetter.py
Normal 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;
|
||||
};
|
||||
""")
|
||||
178
dom/bindings/parser/tests/test_method.py
Normal file
178
dom/bindings/parser/tests/test_method.py
Normal 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")
|
||||
39
dom/bindings/parser/tests/test_mozmap.py
Normal file
39
dom/bindings/parser/tests/test_mozmap.py
Normal 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.")
|
||||
223
dom/bindings/parser/tests/test_namespace.py
Normal file
223
dom/bindings/parser/tests/test_namespace.py
Normal 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.")
|
||||
70
dom/bindings/parser/tests/test_newobject.py
Normal file
70
dom/bindings/parser/tests/test_newobject.py
Normal 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]")
|
||||
115
dom/bindings/parser/tests/test_nullable_equivalency.py
Normal file
115
dom/bindings/parser/tests/test_nullable_equivalency.py
Normal 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)
|
||||
14
dom/bindings/parser/tests/test_nullable_void.py
Normal file
14
dom/bindings/parser/tests/test_nullable_void.py
Normal 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.")
|
||||
30
dom/bindings/parser/tests/test_optional_constraints.py
Normal file
30
dom/bindings/parser/tests/test_optional_constraints.py
Normal 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")
|
||||
60
dom/bindings/parser/tests/test_overload.py
Normal file
60
dom/bindings/parser/tests/test_overload.py
Normal 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")
|
||||
63
dom/bindings/parser/tests/test_promise.py
Normal file
63
dom/bindings/parser/tests/test_promise.py
Normal 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.")
|
||||
80
dom/bindings/parser/tests/test_prototype_ident.py
Normal file
80
dom/bindings/parser/tests/test_prototype_ident.py
Normal 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'")
|
||||
|
||||
107
dom/bindings/parser/tests/test_putForwards.py
Normal file
107
dom/bindings/parser/tests/test_putForwards.py
Normal 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.")
|
||||
58
dom/bindings/parser/tests/test_replaceable.py
Normal file
58
dom/bindings/parser/tests/test_replaceable.py
Normal 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;
|
||||
};
|
||||
""")
|
||||
7
dom/bindings/parser/tests/test_sanity.py
Normal file
7
dom/bindings/parser/tests/test_sanity.py
Normal 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.")
|
||||
|
|
@ -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")
|
||||
|
|
@ -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.")
|
||||
85
dom/bindings/parser/tests/test_special_methods.py
Normal file
85
dom/bindings/parser/tests/test_special_methods.py
Normal 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")
|
||||
|
||||
|
||||
62
dom/bindings/parser/tests/test_special_methods_uniqueness.py
Normal file
62
dom/bindings/parser/tests/test_special_methods_uniqueness.py
Normal 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.")
|
||||
46
dom/bindings/parser/tests/test_stringifier.py
Normal file
46
dom/bindings/parser/tests/test_stringifier.py
Normal 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()'")
|
||||
|
||||
71
dom/bindings/parser/tests/test_treatNonCallableAsNull.py
Normal file
71
dom/bindings/parser/tests/test_treatNonCallableAsNull.py
Normal 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.")
|
||||
76
dom/bindings/parser/tests/test_typedef.py
Normal file
76
dom/bindings/parser/tests/test_typedef.py
Normal 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")
|
||||
|
|
@ -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.")
|
||||
253
dom/bindings/parser/tests/test_unforgeable.py
Normal file
253
dom/bindings/parser/tests/test_unforgeable.py
Normal 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.")
|
||||
168
dom/bindings/parser/tests/test_union.py
Normal file
168
dom/bindings/parser/tests/test_union.py
Normal 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()
|
||||
14
dom/bindings/parser/tests/test_union_any.py
Normal file
14
dom/bindings/parser/tests/test_union_any.py
Normal 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.")
|
||||
53
dom/bindings/parser/tests/test_union_nullable.py
Normal file
53
dom/bindings/parser/tests/test_union_nullable.py
Normal 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.")
|
||||
36
dom/bindings/parser/tests/test_usvstring.py
Normal file
36
dom/bindings/parser/tests/test_usvstring.py
Normal 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")
|
||||
10
dom/bindings/parser/tests/test_variadic_callback.py
Normal file
10
dom/bindings/parser/tests/test_variadic_callback.py
Normal 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.")
|
||||
63
dom/bindings/parser/tests/test_variadic_constraints.py
Normal file
63
dom/bindings/parser/tests/test_variadic_constraints.py
Normal 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.")
|
||||
Loading…
Add table
Add a link
Reference in a new issue