4 def firstArgType(method
):
5 return method
.signatures()[0][1][0].type
8 def WebIDLTest(parser
, harness
):
11 // Give our dictionary a required member so we don't need to
12 // mess with optional and default values.
16 callback interface Foo {
19 // Bit of a pain to get things that have dictionary types
20 undefined passDict(Dict arg);
21 undefined passFoo(Foo arg);
22 undefined passNullableUnion((object? or DOMString) arg);
23 undefined passNullable(Foo? arg);
27 results
= parser
.finish()
30 harness
.ok(iface
.isInterface(), "Should have interface")
31 dictMethod
= iface
.members
[0]
32 ifaceMethod
= iface
.members
[1]
33 nullableUnionMethod
= iface
.members
[2]
34 nullableIfaceMethod
= iface
.members
[3]
36 dictType
= firstArgType(dictMethod
)
37 ifaceType
= firstArgType(ifaceMethod
)
39 harness
.ok(dictType
.isDictionary(), "Should have dictionary type")
40 harness
.ok(ifaceType
.isInterface(), "Should have interface type")
41 harness
.ok(ifaceType
.isCallbackInterface(), "Should have callback interface type")
44 not dictType
.isDistinguishableFrom(ifaceType
),
45 "Dictionary not distinguishable from callback interface",
48 not ifaceType
.isDistinguishableFrom(dictType
),
49 "Callback interface not distinguishable from dictionary",
52 nullableUnionType
= firstArgType(nullableUnionMethod
)
53 nullableIfaceType
= firstArgType(nullableIfaceMethod
)
55 harness
.ok(nullableUnionType
.isUnion(), "Should have union type")
56 harness
.ok(nullableIfaceType
.isInterface(), "Should have interface type")
57 harness
.ok(nullableIfaceType
.nullable(), "Should have nullable type")
60 not nullableUnionType
.isDistinguishableFrom(nullableIfaceType
),
61 "Nullable type not distinguishable from union with nullable " "member type",
64 not nullableIfaceType
.isDistinguishableFrom(nullableUnionType
),
65 "Union with nullable member type not distinguishable from " "nullable type",
68 parser
= parser
.reset()
72 undefined passKid(Kid arg);
73 undefined passParent(Parent arg);
74 undefined passGrandparent(Grandparent arg);
75 undefined passUnrelated1(Unrelated1 arg);
76 undefined passUnrelated2(Unrelated2 arg);
77 undefined passArrayBuffer(ArrayBuffer arg);
78 undefined passArrayBuffer(ArrayBufferView arg);
81 interface Kid : Parent {};
82 interface Parent : Grandparent {};
83 interface Grandparent {};
84 interface Unrelated1 {};
85 interface Unrelated2 {};
88 results
= parser
.finish()
91 harness
.ok(iface
.isInterface(), "Should have interface")
92 argTypes
= [firstArgType(method
) for method
in iface
.members
]
93 unrelatedTypes
= [firstArgType(method
) for method
in iface
.members
[-3:]]
95 for type1
in argTypes
:
96 for type2
in argTypes
:
97 distinguishable
= type1
is not type2
and (
98 type1
in unrelatedTypes
or type2
in unrelatedTypes
102 type1
.isDistinguishableFrom(type2
),
104 "Type %s should %sbe distinguishable from type %s"
105 % (type1
, "" if distinguishable
else "not ", type2
),
108 type2
.isDistinguishableFrom(type1
),
110 "Type %s should %sbe distinguishable from type %s"
111 % (type2
, "" if distinguishable
else "not ", type1
),
114 parser
= parser
.reset()
118 interface TestIface {
119 undefined method(long arg1, TestIface arg2);
120 undefined method(long arg1, long arg2);
121 undefined method(long arg1, Dummy arg2);
122 undefined method(DOMString arg1, DOMString arg2, DOMString arg3);
126 results
= parser
.finish()
127 harness
.check(len(results
[1].members
), 1, "Should look like we have one method")
129 len(results
[1].members
[0].signatures()), 4, "Should have four signatures"
132 parser
= parser
.reset()
138 interface TestIface {
139 undefined method(long arg1, TestIface arg2);
140 undefined method(long arg1, long arg2);
141 undefined method(any arg1, Dummy arg2);
142 undefined method(DOMString arg1, DOMString arg2, DOMString arg3);
147 except WebIDL
.WebIDLError
:
152 "Should throw when args before the distinguishing arg are not "
156 parser
= parser
.reset()
162 interface TestIface {
163 undefined method(long arg1, TestIface arg2);
164 undefined method(long arg1, long arg2);
165 undefined method(any arg1, DOMString arg2);
166 undefined method(DOMString arg1, DOMString arg2, DOMString arg3);
171 except WebIDL
.WebIDLError
:
174 harness
.ok(threw
, "Should throw when there is no distinguishing index")
176 # Now let's test our whole distinguishability table
194 "UnrelatedInterface",
196 "CallbackInterface?",
197 "CallbackInterface2",
205 "record<DOMString, object>",
206 "record<USVString, Dict>",
207 "record<ByteString, long>",
208 "record<UTF8String, long>",
218 "(long or Callback)",
222 # Try to categorize things a bit to keep list lengths down
223 def allBut(list1
, list2
):
228 and (a
!= "any" and a
!= "Promise<any>" and a
!= "Promise<any>?")
231 unionsWithCallback
= ["(long or Callback)"]
232 unionsNoCallback
= ["(long or Dict)"]
233 unions
= unionsWithCallback
+ unionsNoCallback
234 numerics
= ["long", "short", "long?", "short?"]
235 booleans
= ["boolean", "boolean?"]
236 undefineds
= ["undefined", "undefined?"]
237 primitives
= numerics
+ booleans
238 nonNumerics
= allBut(argTypes
, numerics
+ unions
)
239 nonBooleans
= allBut(argTypes
, booleans
)
249 nonStrings
= allBut(argTypes
, strings
)
250 nonObjects
= undefineds
+ primitives
+ strings
251 bufferSourceTypes
= ["ArrayBuffer", "ArrayBufferView", "Uint8Array", "Uint16Array"]
256 "UnrelatedInterface",
257 ] + bufferSourceTypes
264 "CallbackInterface?",
271 sequences
= ["sequence<long>", "sequence<short>"]
272 nonUserObjects
= nonObjects
+ interfaces
+ sequences
273 otherObjects
= allBut(argTypes
, nonUserObjects
+ ["object"])
274 notRelatedInterfaces
= (
276 + ["UnrelatedInterface"]
282 "record<DOMString, object>",
283 "record<USVString, Dict>",
284 "record<ByteString, long>",
285 "record<UTF8String, long>",
286 ] # JSString not supported in records
287 dicts
= ["Dict", "Dict2"]
288 callbacks
= ["Callback", "Callback2"]
289 callbackInterfaces
= [
291 "CallbackInterface?",
292 "CallbackInterface2",
294 dictionaryLike
= dicts
+ callbackInterfaces
+ records
+ unionsNoCallback
296 # Build a representation of the distinguishability table as a dict
297 # of dicts, holding True values where needed, holes elsewhere.
299 for type in argTypes
:
302 def setDistinguishable(type, types
):
304 data
[type][other
] = True
306 setDistinguishable("long", nonNumerics
)
307 setDistinguishable("short", nonNumerics
)
308 setDistinguishable("long?", allBut(nonNumerics
, nullables
))
309 setDistinguishable("short?", allBut(nonNumerics
, nullables
))
310 setDistinguishable("boolean", nonBooleans
)
311 setDistinguishable("boolean?", allBut(nonBooleans
, nullables
))
312 setDistinguishable("undefined", allBut(argTypes
, undefineds
+ dictionaryLike
))
314 "undefined?", allBut(argTypes
, undefineds
+ dictionaryLike
+ nullables
)
316 setDistinguishable("DOMString", nonStrings
)
317 setDistinguishable("ByteString", nonStrings
)
318 setDistinguishable("UTF8String", nonStrings
)
319 setDistinguishable("USVString", nonStrings
)
320 setDistinguishable("JSString", nonStrings
)
321 setDistinguishable("Enum", nonStrings
)
322 setDistinguishable("Enum2", nonStrings
)
323 setDistinguishable("Interface", notRelatedInterfaces
)
324 setDistinguishable("Interface?", allBut(notRelatedInterfaces
, nullables
))
325 setDistinguishable("AncestorInterface", notRelatedInterfaces
)
327 "UnrelatedInterface", allBut(argTypes
, ["object", "UnrelatedInterface"])
331 allBut(nonUserObjects
+ callbacks
+ unionsWithCallback
, undefineds
),
334 "CallbackInterface?",
335 allBut(nonUserObjects
+ callbacks
+ unionsWithCallback
, nullables
+ undefineds
),
338 "CallbackInterface2",
339 allBut(nonUserObjects
+ callbacks
+ unionsWithCallback
, undefineds
),
341 setDistinguishable("object", nonObjects
)
344 nonUserObjects
+ unionsNoCallback
+ dicts
+ records
+ callbackInterfaces
,
348 nonUserObjects
+ unionsNoCallback
+ dicts
+ records
+ callbackInterfaces
,
352 allBut(nonUserObjects
+ unionsWithCallback
+ callbacks
, nullables
+ undefineds
),
356 allBut(nonUserObjects
+ unionsWithCallback
+ callbacks
, nullables
+ undefineds
),
360 allBut(argTypes
, sequences
+ ["object"]),
364 allBut(argTypes
, sequences
+ ["object"]),
367 "record<DOMString, object>",
368 allBut(nonUserObjects
+ unionsWithCallback
+ callbacks
, undefineds
),
371 "record<USVString, Dict>",
372 allBut(nonUserObjects
+ unionsWithCallback
+ callbacks
, undefineds
),
374 # JSString not supported in records
376 "record<ByteString, long>",
377 allBut(nonUserObjects
+ unionsWithCallback
+ callbacks
, undefineds
),
380 "record<UTF8String, long>",
381 allBut(nonUserObjects
+ unionsWithCallback
+ callbacks
, undefineds
),
383 setDistinguishable("any", [])
384 setDistinguishable("Promise<any>", [])
385 setDistinguishable("Promise<any>?", [])
386 setDistinguishable("ArrayBuffer", allBut(argTypes
, ["ArrayBuffer", "object"]))
389 allBut(argTypes
, ["ArrayBufferView", "Uint8Array", "Uint16Array", "object"]),
392 "Uint8Array", allBut(argTypes
, ["ArrayBufferView", "Uint8Array", "object"])
395 "Uint16Array", allBut(argTypes
, ["ArrayBufferView", "Uint16Array", "object"])
398 "(long or Callback)",
399 allBut(nonUserObjects
+ dicts
+ records
+ callbackInterfaces
, numerics
),
403 allBut(nonUserObjects
+ callbacks
, numerics
+ nullables
+ undefineds
),
406 def areDistinguishable(type1
, type2
):
407 return data
[type1
].get(type2
, False)
409 def checkDistinguishability(parser
, type1
, type2
):
411 enum Enum { "a", "b" };
412 enum Enum2 { "c", "d" };
413 interface Interface : AncestorInterface {};
414 interface AncestorInterface {};
415 interface UnrelatedInterface {};
416 callback interface CallbackInterface {};
417 callback interface CallbackInterface2 {};
418 callback Callback = any();
419 callback Callback2 = long(short arg);
420 [LegacyTreatNonObjectAsNull] callback LegacyCallback1 = any();
421 // Give our dictionaries required members so we don't need to
422 // mess with optional and default values.
423 dictionary Dict { required long member; };
424 dictionary Dict2 { required long member; };
425 interface TestInterface {%s
428 if type1
in undefineds
or type2
in undefineds
:
430 (%s or %s) myMethod();""" % (
436 undefined myMethod(%s arg);"""
437 methods
= (methodTemplate
% type1
) + (methodTemplate
% type2
)
438 idl
= idlTemplate
% methods
440 parser
= parser
.reset()
445 except WebIDL
.WebIDLError
:
448 if areDistinguishable(type1
, type2
):
451 "Should not throw for '%s' and '%s' because they are distinguishable"
457 "Should throw for '%s' and '%s' because they are not distinguishable"
461 # Enumerate over everything in both orders, since order matters in
462 # terms of our implementation of distinguishability checks
463 for type1
in argTypes
:
464 for type2
in argTypes
:
465 checkDistinguishability(parser
, type1
, type2
)