dom/bindings/parser/tests/test_distinguishability.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 def firstArgType(method):
michael@0 2 return method.signatures()[0][1][0].type
michael@0 3
michael@0 4 def WebIDLTest(parser, harness):
michael@0 5 parser.parse("""
michael@0 6 dictionary Dict {
michael@0 7 };
michael@0 8 callback interface Foo {
michael@0 9 };
michael@0 10 interface Bar {
michael@0 11 // Bit of a pain to get things that have dictionary types
michael@0 12 void passDict(optional Dict arg);
michael@0 13 void passFoo(Foo arg);
michael@0 14 void passNullableUnion((object? or DOMString) arg);
michael@0 15 void passNullable(Foo? arg);
michael@0 16 };
michael@0 17 """)
michael@0 18 results = parser.finish()
michael@0 19
michael@0 20 iface = results[2]
michael@0 21 harness.ok(iface.isInterface(), "Should have interface")
michael@0 22 dictMethod = iface.members[0]
michael@0 23 ifaceMethod = iface.members[1]
michael@0 24 nullableUnionMethod = iface.members[2]
michael@0 25 nullableIfaceMethod = iface.members[3]
michael@0 26
michael@0 27 dictType = firstArgType(dictMethod)
michael@0 28 ifaceType = firstArgType(ifaceMethod)
michael@0 29
michael@0 30 harness.ok(dictType.isDictionary(), "Should have dictionary type");
michael@0 31 harness.ok(ifaceType.isInterface(), "Should have interface type");
michael@0 32 harness.ok(ifaceType.isCallbackInterface(), "Should have callback interface type");
michael@0 33
michael@0 34 harness.ok(not dictType.isDistinguishableFrom(ifaceType),
michael@0 35 "Dictionary not distinguishable from callback interface")
michael@0 36 harness.ok(not ifaceType.isDistinguishableFrom(dictType),
michael@0 37 "Callback interface not distinguishable from dictionary")
michael@0 38
michael@0 39 nullableUnionType = firstArgType(nullableUnionMethod)
michael@0 40 nullableIfaceType = firstArgType(nullableIfaceMethod)
michael@0 41
michael@0 42 harness.ok(nullableUnionType.isUnion(), "Should have union type");
michael@0 43 harness.ok(nullableIfaceType.isInterface(), "Should have interface type");
michael@0 44 harness.ok(nullableIfaceType.nullable(), "Should have nullable type");
michael@0 45
michael@0 46 harness.ok(not nullableUnionType.isDistinguishableFrom(nullableIfaceType),
michael@0 47 "Nullable type not distinguishable from union with nullable "
michael@0 48 "member type")
michael@0 49 harness.ok(not nullableIfaceType.isDistinguishableFrom(nullableUnionType),
michael@0 50 "Union with nullable member type not distinguishable from "
michael@0 51 "nullable type")
michael@0 52
michael@0 53 parser = parser.reset()
michael@0 54 parser.parse("""
michael@0 55 interface TestIface {
michael@0 56 void passKid(Kid arg);
michael@0 57 void passParent(Parent arg);
michael@0 58 void passGrandparent(Grandparent arg);
michael@0 59 void passImplemented(Implemented arg);
michael@0 60 void passImplementedParent(ImplementedParent arg);
michael@0 61 void passUnrelated1(Unrelated1 arg);
michael@0 62 void passUnrelated2(Unrelated2 arg);
michael@0 63 void passArrayBuffer(ArrayBuffer arg);
michael@0 64 void passArrayBuffer(ArrayBufferView arg);
michael@0 65 };
michael@0 66
michael@0 67 interface Kid : Parent {};
michael@0 68 interface Parent : Grandparent {};
michael@0 69 interface Grandparent {};
michael@0 70 interface Implemented : ImplementedParent {};
michael@0 71 Parent implements Implemented;
michael@0 72 interface ImplementedParent {};
michael@0 73 interface Unrelated1 {};
michael@0 74 interface Unrelated2 {};
michael@0 75 """)
michael@0 76 results = parser.finish()
michael@0 77
michael@0 78 iface = results[0]
michael@0 79 harness.ok(iface.isInterface(), "Should have interface")
michael@0 80 argTypes = [firstArgType(method) for method in iface.members]
michael@0 81 unrelatedTypes = [firstArgType(method) for method in iface.members[-3:]]
michael@0 82
michael@0 83 for type1 in argTypes:
michael@0 84 for type2 in argTypes:
michael@0 85 distinguishable = (type1 is not type2 and
michael@0 86 (type1 in unrelatedTypes or
michael@0 87 type2 in unrelatedTypes))
michael@0 88
michael@0 89 harness.check(type1.isDistinguishableFrom(type2),
michael@0 90 distinguishable,
michael@0 91 "Type %s should %sbe distinguishable from type %s" %
michael@0 92 (type1, "" if distinguishable else "not ", type2))
michael@0 93 harness.check(type2.isDistinguishableFrom(type1),
michael@0 94 distinguishable,
michael@0 95 "Type %s should %sbe distinguishable from type %s" %
michael@0 96 (type2, "" if distinguishable else "not ", type1))
michael@0 97
michael@0 98 parser = parser.reset()
michael@0 99 parser.parse("""
michael@0 100 interface Dummy {};
michael@0 101 interface TestIface {
michael@0 102 void method(long arg1, TestIface arg2);
michael@0 103 void method(long arg1, long arg2);
michael@0 104 void method(long arg1, Dummy arg2);
michael@0 105 void method(DOMString arg1, DOMString arg2, DOMString arg3);
michael@0 106 };
michael@0 107 """)
michael@0 108 results = parser.finish()
michael@0 109 harness.check(len(results[1].members), 1,
michael@0 110 "Should look like we have one method")
michael@0 111 harness.check(len(results[1].members[0].signatures()), 4,
michael@0 112 "Should have four signatures")
michael@0 113
michael@0 114 parser = parser.reset()
michael@0 115 threw = False
michael@0 116 try:
michael@0 117 parser.parse("""
michael@0 118 interface Dummy {};
michael@0 119 interface TestIface {
michael@0 120 void method(long arg1, TestIface arg2);
michael@0 121 void method(long arg1, long arg2);
michael@0 122 void method(any arg1, Dummy arg2);
michael@0 123 void method(DOMString arg1, DOMString arg2, DOMString arg3);
michael@0 124 };
michael@0 125 """)
michael@0 126 results = parser.finish()
michael@0 127 except:
michael@0 128 threw = True
michael@0 129
michael@0 130 harness.ok(threw,
michael@0 131 "Should throw when args before the distinguishing arg are not "
michael@0 132 "all the same type")
michael@0 133
michael@0 134 parser = parser.reset()
michael@0 135 threw = False
michael@0 136 try:
michael@0 137 parser.parse("""
michael@0 138 interface Dummy {};
michael@0 139 interface TestIface {
michael@0 140 void method(long arg1, TestIface arg2);
michael@0 141 void method(long arg1, long arg2);
michael@0 142 void method(any arg1, DOMString arg2);
michael@0 143 void method(DOMString arg1, DOMString arg2, DOMString arg3);
michael@0 144 };
michael@0 145 """)
michael@0 146 results = parser.finish()
michael@0 147 except:
michael@0 148 threw = True
michael@0 149
michael@0 150 harness.ok(threw, "Should throw when there is no distinguishing index")
michael@0 151
michael@0 152 # Now let's test our whole distinguishability table
michael@0 153 argTypes = [ "long", "short", "long?", "short?", "boolean",
michael@0 154 "boolean?", "DOMString", "ByteString", "Enum", "Enum2",
michael@0 155 "Interface", "Interface?",
michael@0 156 "AncestorInterface", "UnrelatedInterface",
michael@0 157 "ImplementedInterface", "CallbackInterface",
michael@0 158 "CallbackInterface?", "CallbackInterface2",
michael@0 159 "object", "Callback", "Callback2", "optional Dict",
michael@0 160 "optional Dict2", "sequence<long>", "sequence<short>",
michael@0 161 "MozMap<object>", "MozMap<Dict>", "MozMap<long>",
michael@0 162 "long[]", "short[]", "Date", "Date?", "any" ]
michael@0 163 # When we can parse Date and RegExp, we need to add them here.
michael@0 164
michael@0 165 # Try to categorize things a bit to keep list lengths down
michael@0 166 def allBut(list1, list2):
michael@0 167 return [a for a in list1 if a not in list2 and a != "any"]
michael@0 168 numerics = [ "long", "short", "long?", "short?" ]
michael@0 169 booleans = [ "boolean", "boolean?" ]
michael@0 170 primitives = numerics + booleans
michael@0 171 nonNumerics = allBut(argTypes, numerics)
michael@0 172 nonBooleans = allBut(argTypes, booleans)
michael@0 173 strings = [ "DOMString", "ByteString", "Enum", "Enum2" ]
michael@0 174 nonStrings = allBut(argTypes, strings)
michael@0 175 nonObjects = primitives + strings
michael@0 176 objects = allBut(argTypes, nonObjects )
michael@0 177 interfaces = [ "Interface", "Interface?", "AncestorInterface",
michael@0 178 "UnrelatedInterface", "ImplementedInterface" ]
michael@0 179 nullables = ["long?", "short?", "boolean?", "Interface?",
michael@0 180 "CallbackInterface?", "optional Dict", "optional Dict2",
michael@0 181 "Date?", "any"]
michael@0 182 dates = [ "Date", "Date?" ]
michael@0 183 nonUserObjects = nonObjects + interfaces + dates
michael@0 184 otherObjects = allBut(argTypes, nonUserObjects + ["object"])
michael@0 185 notRelatedInterfaces = (nonObjects + ["UnrelatedInterface"] +
michael@0 186 otherObjects + dates)
michael@0 187
michael@0 188 # Build a representation of the distinguishability table as a dict
michael@0 189 # of dicts, holding True values where needed, holes elsewhere.
michael@0 190 data = dict();
michael@0 191 for type in argTypes:
michael@0 192 data[type] = dict()
michael@0 193 def setDistinguishable(type, types):
michael@0 194 for other in types:
michael@0 195 data[type][other] = True
michael@0 196
michael@0 197 setDistinguishable("long", nonNumerics)
michael@0 198 setDistinguishable("short", nonNumerics)
michael@0 199 setDistinguishable("long?", allBut(nonNumerics, nullables))
michael@0 200 setDistinguishable("short?", allBut(nonNumerics, nullables))
michael@0 201 setDistinguishable("boolean", nonBooleans)
michael@0 202 setDistinguishable("boolean?", allBut(nonBooleans, nullables))
michael@0 203 setDistinguishable("DOMString", nonStrings)
michael@0 204 setDistinguishable("ByteString", nonStrings)
michael@0 205 setDistinguishable("Enum", nonStrings)
michael@0 206 setDistinguishable("Enum2", nonStrings)
michael@0 207 setDistinguishable("Interface", notRelatedInterfaces)
michael@0 208 setDistinguishable("Interface?", allBut(notRelatedInterfaces, nullables))
michael@0 209 setDistinguishable("AncestorInterface", notRelatedInterfaces)
michael@0 210 setDistinguishable("UnrelatedInterface",
michael@0 211 allBut(argTypes, ["object", "UnrelatedInterface"]))
michael@0 212 setDistinguishable("ImplementedInterface", notRelatedInterfaces)
michael@0 213 setDistinguishable("CallbackInterface", nonUserObjects)
michael@0 214 setDistinguishable("CallbackInterface?", allBut(nonUserObjects, nullables))
michael@0 215 setDistinguishable("CallbackInterface2", nonUserObjects)
michael@0 216 setDistinguishable("object", nonObjects)
michael@0 217 setDistinguishable("Callback", nonUserObjects)
michael@0 218 setDistinguishable("Callback2", nonUserObjects)
michael@0 219 setDistinguishable("optional Dict", allBut(nonUserObjects, nullables))
michael@0 220 setDistinguishable("optional Dict2", allBut(nonUserObjects, nullables))
michael@0 221 setDistinguishable("sequence<long>", nonUserObjects)
michael@0 222 setDistinguishable("sequence<short>", nonUserObjects)
michael@0 223 setDistinguishable("MozMap<object>", nonUserObjects)
michael@0 224 setDistinguishable("MozMap<Dict>", nonUserObjects)
michael@0 225 setDistinguishable("MozMap<long>", nonUserObjects)
michael@0 226 setDistinguishable("long[]", nonUserObjects)
michael@0 227 setDistinguishable("short[]", nonUserObjects)
michael@0 228 setDistinguishable("Date", allBut(argTypes, dates + ["object"]))
michael@0 229 setDistinguishable("Date?", allBut(argTypes, dates + nullables + ["object"]))
michael@0 230 setDistinguishable("any", [])
michael@0 231
michael@0 232 def areDistinguishable(type1, type2):
michael@0 233 return data[type1].get(type2, False)
michael@0 234
michael@0 235 def checkDistinguishability(parser, type1, type2):
michael@0 236 idlTemplate = """
michael@0 237 enum Enum { "a", "b" };
michael@0 238 enum Enum2 { "c", "d" };
michael@0 239 interface Interface : AncestorInterface {};
michael@0 240 interface AncestorInterface {};
michael@0 241 interface UnrelatedInterface {};
michael@0 242 interface ImplementedInterface {};
michael@0 243 Interface implements ImplementedInterface;
michael@0 244 callback interface CallbackInterface {};
michael@0 245 callback interface CallbackInterface2 {};
michael@0 246 callback Callback = any();
michael@0 247 callback Callback2 = long(short arg);
michael@0 248 dictionary Dict {};
michael@0 249 dictionary Dict2 {};
michael@0 250 interface TestInterface {%s
michael@0 251 };
michael@0 252 """
michael@0 253 methodTemplate = """
michael@0 254 void myMethod(%s arg);"""
michael@0 255 methods = (methodTemplate % type1) + (methodTemplate % type2)
michael@0 256 idl = idlTemplate % methods
michael@0 257 parser = parser.reset()
michael@0 258 threw = False
michael@0 259 try:
michael@0 260 parser.parse(idl)
michael@0 261 results = parser.finish()
michael@0 262 except:
michael@0 263 threw = True
michael@0 264
michael@0 265 if areDistinguishable(type1, type2):
michael@0 266 harness.ok(not threw,
michael@0 267 "Should not throw for '%s' and '%s' because they are distinguishable" % (type1, type2))
michael@0 268 else:
michael@0 269 harness.ok(threw,
michael@0 270 "Should throw for '%s' and '%s' because they are not distinguishable" % (type1, type2))
michael@0 271
michael@0 272 # Enumerate over everything in both orders, since order matters in
michael@0 273 # terms of our implementation of distinguishability checks
michael@0 274 for type1 in argTypes:
michael@0 275 for type2 in argTypes:
michael@0 276 checkDistinguishability(parser, type1, type2)

mercurial