Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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) |