Source code

Revision control

Copy as Markdown

Other Tools

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",
"prettyName",
]
or (hasattr(type(type1), attr) and not callable(getattr(type1, attr)))
):
continue
a1 = getattr(type1, attr)
if callable(a1):
try:
v1 = a1()
except AssertionError:
# Various methods assert that they're called on objects of
# the right type, skip them if the assert fails.
continue
except TypeError:
# a1 requires positional arguments, so skip this attribute.
continue
try:
a2 = getattr(type2, attr)
except WebIDL.WebIDLError:
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 WebIDL.WebIDLError:
harness.ok(
False,
"Missing %s attribute on type %s in %s" % (attr, type2, iface),
)
continue
harness.check(a2, a1, "%s attribute should match" % attr)