1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
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)
|