|
1 # Import the WebIDL module, so we can do isinstance checks and whatnot |
|
2 import WebIDL |
|
3 |
|
4 def WebIDLTest(parser, harness): |
|
5 # Basic functionality |
|
6 threw = False |
|
7 try: |
|
8 parser.parse(""" |
|
9 A implements B; |
|
10 interface B { |
|
11 attribute long x; |
|
12 }; |
|
13 interface A { |
|
14 attribute long y; |
|
15 }; |
|
16 """) |
|
17 results = parser.finish() |
|
18 except: |
|
19 threw = True |
|
20 |
|
21 harness.ok(not threw, "Should not have thrown on implements statement " |
|
22 "before interfaces") |
|
23 harness.check(len(results), 3, "We have three statements") |
|
24 harness.ok(isinstance(results[1], WebIDL.IDLInterface), "B is an interface") |
|
25 harness.check(len(results[1].members), 1, "B has one member") |
|
26 A = results[2] |
|
27 harness.ok(isinstance(A, WebIDL.IDLInterface), "A is an interface") |
|
28 harness.check(len(A.members), 2, "A has two members") |
|
29 harness.check(A.members[0].identifier.name, "y", "First member is 'y'") |
|
30 harness.check(A.members[1].identifier.name, "x", "Second member is 'x'") |
|
31 |
|
32 # Duplicated member names not allowed |
|
33 threw = False |
|
34 try: |
|
35 parser.parse(""" |
|
36 C implements D; |
|
37 interface D { |
|
38 attribute long x; |
|
39 }; |
|
40 interface C { |
|
41 attribute long x; |
|
42 }; |
|
43 """) |
|
44 parser.finish() |
|
45 except: |
|
46 threw = True |
|
47 |
|
48 harness.ok(threw, "Should have thrown on implemented interface duplicating " |
|
49 "a name on base interface") |
|
50 |
|
51 # Same, but duplicated across implemented interfaces |
|
52 threw = False |
|
53 try: |
|
54 parser.parse(""" |
|
55 E implements F; |
|
56 E implements G; |
|
57 interface F { |
|
58 attribute long x; |
|
59 }; |
|
60 interface G { |
|
61 attribute long x; |
|
62 }; |
|
63 interface E {}; |
|
64 """) |
|
65 parser.finish() |
|
66 except: |
|
67 threw = True |
|
68 |
|
69 harness.ok(threw, "Should have thrown on implemented interfaces " |
|
70 "duplicating each other's member names") |
|
71 |
|
72 # Same, but duplicated across indirectly implemented interfaces |
|
73 threw = False |
|
74 try: |
|
75 parser.parse(""" |
|
76 H implements I; |
|
77 H implements J; |
|
78 I implements K; |
|
79 interface K { |
|
80 attribute long x; |
|
81 }; |
|
82 interface L { |
|
83 attribute long x; |
|
84 }; |
|
85 interface I {}; |
|
86 interface J : L {}; |
|
87 interface H {}; |
|
88 """) |
|
89 parser.finish() |
|
90 except: |
|
91 threw = True |
|
92 |
|
93 harness.ok(threw, "Should have thrown on indirectly implemented interfaces " |
|
94 "duplicating each other's member names") |
|
95 |
|
96 # Same, but duplicated across an implemented interface and its parent |
|
97 threw = False |
|
98 try: |
|
99 parser.parse(""" |
|
100 M implements N; |
|
101 interface O { |
|
102 attribute long x; |
|
103 }; |
|
104 interface N : O { |
|
105 attribute long x; |
|
106 }; |
|
107 interface M {}; |
|
108 """) |
|
109 parser.finish() |
|
110 except: |
|
111 threw = True |
|
112 |
|
113 harness.ok(threw, "Should have thrown on implemented interface and its " |
|
114 "ancestor duplicating member names") |
|
115 |
|
116 # Reset the parser so we can actually find things where we expect |
|
117 # them in the list |
|
118 parser = parser.reset() |
|
119 |
|
120 # Diamonds should be allowed |
|
121 threw = False |
|
122 try: |
|
123 parser.parse(""" |
|
124 P implements Q; |
|
125 P implements R; |
|
126 Q implements S; |
|
127 R implements S; |
|
128 interface Q {}; |
|
129 interface R {}; |
|
130 interface S { |
|
131 attribute long x; |
|
132 }; |
|
133 interface P {}; |
|
134 """) |
|
135 results = parser.finish() |
|
136 except: |
|
137 threw = True |
|
138 |
|
139 harness.ok(not threw, "Diamond inheritance is fine") |
|
140 harness.check(results[6].identifier.name, "S", "We should be looking at 'S'") |
|
141 harness.check(len(results[6].members), 1, "S should have one member") |
|
142 harness.check(results[6].members[0].identifier.name, "x", |
|
143 "S's member should be 'x'") |
|
144 |
|
145 parser = parser.reset() |
|
146 threw = False |
|
147 try: |
|
148 parser.parse(""" |
|
149 interface TestInterface { |
|
150 }; |
|
151 callback interface TestCallbackInterface { |
|
152 }; |
|
153 TestInterface implements TestCallbackInterface; |
|
154 """) |
|
155 results = parser.finish() |
|
156 except: |
|
157 threw = True |
|
158 |
|
159 harness.ok(threw, |
|
160 "Should not allow callback interfaces on the right-hand side " |
|
161 "of 'implements'") |
|
162 |
|
163 parser = parser.reset() |
|
164 threw = False |
|
165 try: |
|
166 parser.parse(""" |
|
167 interface TestInterface { |
|
168 }; |
|
169 callback interface TestCallbackInterface { |
|
170 }; |
|
171 TestCallbackInterface implements TestInterface; |
|
172 """) |
|
173 results = parser.finish() |
|
174 except: |
|
175 threw = True |
|
176 |
|
177 harness.ok(threw, |
|
178 "Should not allow callback interfaces on the left-hand side of " |
|
179 "'implements'") |
|
180 |
|
181 parser = parser.reset() |
|
182 threw = False |
|
183 try: |
|
184 parser.parse(""" |
|
185 interface TestInterface { |
|
186 }; |
|
187 dictionary Dict { |
|
188 }; |
|
189 Dict implements TestInterface; |
|
190 """) |
|
191 results = parser.finish() |
|
192 except: |
|
193 threw = True |
|
194 |
|
195 harness.ok(threw, |
|
196 "Should not allow non-interfaces on the left-hand side " |
|
197 "of 'implements'") |
|
198 |
|
199 parser = parser.reset() |
|
200 threw = False |
|
201 try: |
|
202 parser.parse(""" |
|
203 interface TestInterface { |
|
204 }; |
|
205 dictionary Dict { |
|
206 }; |
|
207 TestInterface implements Dict; |
|
208 """) |
|
209 results = parser.finish() |
|
210 except: |
|
211 threw = True |
|
212 |
|
213 harness.ok(threw, |
|
214 "Should not allow non-interfaces on the right-hand side " |
|
215 "of 'implements'") |
|
216 |