Bug 1915045 Ensure decode tasks are scheduled on BufferingState::Enter() r=media...
[gecko.git] / dom / bindings / parser / tests / test_union.py
blob71791207babc6720840d6d1a99ef87caf4425501
1 import string
3 import WebIDL
5 # We'd like to use itertools.chain but it's 2.6 or higher.
8 def chain(*iterables):
9 # chain('ABC', 'DEF') --> A B C D E F
10 for it in iterables:
11 for element in it:
12 yield element
15 # We'd like to use itertools.combinations but it's 2.6 or higher.
16 def combinations(iterable, r):
17 # combinations('ABCD', 2) --> AB AC AD BC BD CD
18 # combinations(range(4), 3) --> 012 013 023 123
19 pool = tuple(iterable)
20 n = len(pool)
21 if r > n:
22 return
23 indices = list(range(r))
24 yield tuple(pool[i] for i in indices)
25 while True:
26 for i in reversed(range(r)):
27 if indices[i] != i + n - r:
28 break
29 else:
30 return
31 indices[i] += 1
32 for j in range(i + 1, r):
33 indices[j] = indices[j - 1] + 1
34 yield tuple(pool[i] for i in indices)
37 # We'd like to use itertools.combinations_with_replacement but it's 2.7 or
38 # higher.
39 def combinations_with_replacement(iterable, r):
40 # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
41 pool = tuple(iterable)
42 n = len(pool)
43 if not n and r:
44 return
45 indices = [0] * r
46 yield tuple(pool[i] for i in indices)
47 while True:
48 for i in reversed(range(r)):
49 if indices[i] != n - 1:
50 break
51 else:
52 return
53 indices[i:] = [indices[i] + 1] * (r - i)
54 yield tuple(pool[i] for i in indices)
57 def WebIDLTest(parser, harness):
58 types = [
59 "float",
60 "double",
61 "short",
62 "unsigned short",
63 "long",
64 "unsigned long",
65 "long long",
66 "unsigned long long",
67 "boolean",
68 "byte",
69 "octet",
70 "DOMString",
71 "ByteString",
72 "USVString",
73 # "sequence<float>",
74 "object",
75 "ArrayBuffer",
76 # "Date",
77 "TestInterface1",
78 "TestInterface2",
81 testPre = """
82 interface TestInterface1 {
84 interface TestInterface2 {
86 """
88 interface = (
89 testPre
90 + """
91 interface PrepareForTest {
92 """
94 for i, type in enumerate(types):
95 interface += string.Template(
96 """
97 readonly attribute ${type} attr${i};
98 """
99 ).substitute(i=i, type=type)
100 interface += """
104 parser.parse(interface)
105 results = parser.finish()
107 iface = results[2]
109 parser = parser.reset()
111 def typesAreDistinguishable(t):
112 return all(u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2))
114 def typesAreNotDistinguishable(t):
115 return any(not u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2))
117 def unionTypeName(t):
118 if len(t) > 2:
119 t[0:2] = [unionTypeName(t[0:2])]
120 return "(" + " or ".join(t) + ")"
122 # typeCombinations is an iterable of tuples containing the name of the type
123 # as a string and the parsed IDL type.
124 def unionTypes(typeCombinations, predicate):
125 for c in typeCombinations:
126 if predicate(t[1] for t in c):
127 yield unionTypeName([t[0] for t in c])
129 # We limit invalid union types with a union member type to the subset of 3
130 # types with one invalid combination.
131 # typeCombinations is an iterable of tuples containing the name of the type
132 # as a string and the parsed IDL type.
133 def invalidUnionWithUnion(typeCombinations):
134 for c in typeCombinations:
135 if (
136 typesAreNotDistinguishable((c[0][1], c[1][1]))
137 and typesAreDistinguishable((c[1][1], c[2][1]))
138 and typesAreDistinguishable((c[0][1], c[2][1]))
140 yield unionTypeName([t[0] for t in c])
142 # Create a list of tuples containing the name of the type as a string and
143 # the parsed IDL type.
144 types = zip(types, (a.type for a in iface.members))
146 validUnionTypes = chain(
147 unionTypes(combinations(types, 2), typesAreDistinguishable),
148 unionTypes(combinations(types, 3), typesAreDistinguishable),
150 invalidUnionTypes = chain(
151 unionTypes(combinations_with_replacement(types, 2), typesAreNotDistinguishable),
152 invalidUnionWithUnion(combinations(types, 3)),
154 interface = (
155 testPre
156 + """
157 interface TestUnion {
160 for i, type in enumerate(validUnionTypes):
161 interface += string.Template(
163 undefined method${i}(${type} arg);
164 ${type} returnMethod${i}();
165 attribute ${type} attr${i};
166 undefined optionalMethod${i}(${type}? arg);
168 ).substitute(i=i, type=type)
169 interface += """
172 parser.parse(interface)
173 results = parser.finish()
175 parser = parser.reset()
177 for invalid in invalidUnionTypes:
178 interface = (
179 testPre
180 + string.Template(
182 interface TestUnion {
183 undefined method(${type} arg);
186 ).substitute(type=invalid)
189 threw = False
190 try:
191 parser.parse(interface)
192 results = parser.finish()
193 except WebIDL.WebIDLError:
194 threw = True
196 harness.ok(threw, "Should have thrown.")
198 parser = parser.reset()