Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 import WebIDL
2 import itertools
3 import string
5 # We'd like to use itertools.chain but it's 2.6 or higher.
6 def chain(*iterables):
7 # chain('ABC', 'DEF') --> A B C D E F
8 for it in iterables:
9 for element in it:
10 yield element
12 # We'd like to use itertools.combinations but it's 2.6 or higher.
13 def combinations(iterable, r):
14 # combinations('ABCD', 2) --> AB AC AD BC BD CD
15 # combinations(range(4), 3) --> 012 013 023 123
16 pool = tuple(iterable)
17 n = len(pool)
18 if r > n:
19 return
20 indices = range(r)
21 yield tuple(pool[i] for i in indices)
22 while True:
23 for i in reversed(range(r)):
24 if indices[i] != i + n - r:
25 break
26 else:
27 return
28 indices[i] += 1
29 for j in range(i+1, r):
30 indices[j] = indices[j-1] + 1
31 yield tuple(pool[i] for i in indices)
33 # We'd like to use itertools.combinations_with_replacement but it's 2.7 or
34 # higher.
35 def combinations_with_replacement(iterable, r):
36 # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
37 pool = tuple(iterable)
38 n = len(pool)
39 if not n and r:
40 return
41 indices = [0] * r
42 yield tuple(pool[i] for i in indices)
43 while True:
44 for i in reversed(range(r)):
45 if indices[i] != n - 1:
46 break
47 else:
48 return
49 indices[i:] = [indices[i] + 1] * (r - i)
50 yield tuple(pool[i] for i in indices)
52 def WebIDLTest(parser, harness):
53 types = ["float",
54 "double",
55 "short",
56 "unsigned short",
57 "long",
58 "unsigned long",
59 "long long",
60 "unsigned long long",
61 "boolean",
62 "byte",
63 "octet",
64 "DOMString",
65 "ByteString",
66 #"sequence<float>",
67 "object",
68 "ArrayBuffer",
69 #"Date",
70 "TestInterface1",
71 "TestInterface2"]
73 testPre = """
74 interface TestInterface1 {
75 };
76 interface TestInterface2 {
77 };
78 """
80 interface = testPre + """
81 interface PrepareForTest {
82 """
83 for (i, type) in enumerate(types):
84 interface += string.Template("""
85 readonly attribute ${type} attr${i};
86 """).substitute(i=i, type=type)
87 interface += """
88 };
89 """
91 parser.parse(interface)
92 results = parser.finish()
94 iface = results[2]
96 parser = parser.reset()
98 def typesAreDistinguishable(t):
99 return all(u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2))
100 def typesAreNotDistinguishable(t):
101 return any(not u[0].isDistinguishableFrom(u[1]) for u in combinations(t, 2))
102 def unionTypeName(t):
103 if len(t) > 2:
104 t[0:2] = [unionTypeName(t[0:2])]
105 return "(" + " or ".join(t) + ")"
107 # typeCombinations is an iterable of tuples containing the name of the type
108 # as a string and the parsed IDL type.
109 def unionTypes(typeCombinations, predicate):
110 for c in typeCombinations:
111 if predicate(t[1] for t in c):
112 yield unionTypeName([t[0] for t in c])
114 # We limit invalid union types with a union member type to the subset of 3
115 # types with one invalid combination.
116 # typeCombinations is an iterable of tuples containing the name of the type
117 # as a string and the parsed IDL type.
118 def invalidUnionWithUnion(typeCombinations):
119 for c in typeCombinations:
120 if (typesAreNotDistinguishable((c[0][1], c[1][1])) and
121 typesAreDistinguishable((c[1][1], c[2][1])) and
122 typesAreDistinguishable((c[0][1], c[2][1]))):
123 yield unionTypeName([t[0] for t in c])
125 # Create a list of tuples containing the name of the type as a string and
126 # the parsed IDL type.
127 types = zip(types, (a.type for a in iface.members))
129 validUnionTypes = chain(unionTypes(combinations(types, 2), typesAreDistinguishable),
130 unionTypes(combinations(types, 3), typesAreDistinguishable))
131 invalidUnionTypes = chain(unionTypes(combinations_with_replacement(types, 2), typesAreNotDistinguishable),
132 invalidUnionWithUnion(combinations(types, 3)))
133 interface = testPre + """
134 interface TestUnion {
135 """
136 for (i, type) in enumerate(validUnionTypes):
137 interface += string.Template("""
138 void method${i}(${type} arg);
139 ${type} returnMethod${i}();
140 attribute ${type} attr${i};
141 void arrayMethod${i}(${type}[] arg);
142 ${type}[] arrayReturnMethod${i}();
143 attribute ${type}[] arrayAttr${i};
144 void optionalMethod${i}(${type}? arg);
145 """).substitute(i=i, type=type)
146 interface += """
147 };
148 """
149 parser.parse(interface)
150 results = parser.finish()
152 parser = parser.reset()
154 for invalid in invalidUnionTypes:
155 interface = testPre + string.Template("""
156 interface TestUnion {
157 void method(${type} arg);
158 };
159 """).substitute(type=invalid)
161 threw = False
162 try:
163 parser.parse(interface)
164 results = parser.finish()
165 except:
166 threw = True
168 harness.ok(threw, "Should have thrown.")
170 parser = parser.reset()