1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/bindings/parser/tests/test_interface.py Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,405 @@ 1.4 +import WebIDL 1.5 + 1.6 +def WebIDLTest(parser, harness): 1.7 + parser.parse("interface Foo { };") 1.8 + results = parser.finish() 1.9 + harness.ok(True, "Empty interface parsed without error.") 1.10 + harness.check(len(results), 1, "Should be one production") 1.11 + harness.ok(isinstance(results[0], WebIDL.IDLInterface), 1.12 + "Should be an IDLInterface") 1.13 + iface = results[0] 1.14 + harness.check(iface.identifier.QName(), "::Foo", "Interface has the right QName") 1.15 + harness.check(iface.identifier.name, "Foo", "Interface has the right name") 1.16 + harness.check(iface.parent, None, "Interface has no parent") 1.17 + 1.18 + parser.parse("interface Bar : Foo { };") 1.19 + results = parser.finish() 1.20 + harness.ok(True, "Empty interface parsed without error.") 1.21 + harness.check(len(results), 2, "Should be two productions") 1.22 + harness.ok(isinstance(results[1], WebIDL.IDLInterface), 1.23 + "Should be an IDLInterface") 1.24 + iface = results[1] 1.25 + harness.check(iface.identifier.QName(), "::Bar", "Interface has the right QName") 1.26 + harness.check(iface.identifier.name, "Bar", "Interface has the right name") 1.27 + harness.ok(isinstance(iface.parent, WebIDL.IDLInterface), 1.28 + "Interface has a parent") 1.29 + 1.30 + parser = parser.reset() 1.31 + parser.parse(""" 1.32 + interface QNameBase { 1.33 + attribute long foo; 1.34 + }; 1.35 + 1.36 + interface QNameDerived : QNameBase { 1.37 + attribute long long foo; 1.38 + attribute byte bar; 1.39 + }; 1.40 + """) 1.41 + results = parser.finish() 1.42 + harness.check(len(results), 2, "Should be two productions") 1.43 + harness.ok(isinstance(results[0], WebIDL.IDLInterface), 1.44 + "Should be an IDLInterface") 1.45 + harness.ok(isinstance(results[1], WebIDL.IDLInterface), 1.46 + "Should be an IDLInterface") 1.47 + harness.check(results[1].parent, results[0], "Inheritance chain is right") 1.48 + harness.check(len(results[0].members), 1, "Expect 1 productions") 1.49 + harness.check(len(results[1].members), 2, "Expect 2 productions") 1.50 + base = results[0] 1.51 + derived = results[1] 1.52 + harness.check(base.members[0].identifier.QName(), "::QNameBase::foo", 1.53 + "Member has the right QName") 1.54 + harness.check(derived.members[0].identifier.QName(), "::QNameDerived::foo", 1.55 + "Member has the right QName") 1.56 + harness.check(derived.members[1].identifier.QName(), "::QNameDerived::bar", 1.57 + "Member has the right QName") 1.58 + 1.59 + parser = parser.reset() 1.60 + threw = False 1.61 + try: 1.62 + parser.parse(""" 1.63 + interface A : B {}; 1.64 + interface B : A {}; 1.65 + """) 1.66 + results = parser.finish() 1.67 + except: 1.68 + threw = True 1.69 + 1.70 + harness.ok(threw, "Should not allow cycles in interface inheritance chains") 1.71 + 1.72 + parser = parser.reset() 1.73 + threw = False 1.74 + try: 1.75 + parser.parse(""" 1.76 + interface A : C {}; 1.77 + interface C : B {}; 1.78 + interface B : A {}; 1.79 + """) 1.80 + results = parser.finish() 1.81 + except: 1.82 + threw = True 1.83 + 1.84 + harness.ok(threw, "Should not allow indirect cycles in interface inheritance chains") 1.85 + 1.86 + parser = parser.reset() 1.87 + threw = False 1.88 + try: 1.89 + parser.parse(""" 1.90 + interface A {}; 1.91 + interface B {}; 1.92 + A implements B; 1.93 + B implements A; 1.94 + """) 1.95 + results = parser.finish() 1.96 + except: 1.97 + threw = True 1.98 + 1.99 + harness.ok(threw, "Should not allow cycles via implements") 1.100 + 1.101 + parser = parser.reset() 1.102 + threw = False 1.103 + try: 1.104 + parser.parse(""" 1.105 + interface A {}; 1.106 + interface C {}; 1.107 + interface B {}; 1.108 + A implements C; 1.109 + C implements B; 1.110 + B implements A; 1.111 + """) 1.112 + results = parser.finish() 1.113 + except: 1.114 + threw = True 1.115 + 1.116 + harness.ok(threw, "Should not allow indirect cycles via implements") 1.117 + 1.118 + parser = parser.reset() 1.119 + threw = False 1.120 + try: 1.121 + parser.parse(""" 1.122 + interface A : B {}; 1.123 + interface B {}; 1.124 + B implements A; 1.125 + """) 1.126 + results = parser.finish() 1.127 + except: 1.128 + threw = True 1.129 + 1.130 + harness.ok(threw, "Should not allow inheriting from an interface that implements us") 1.131 + 1.132 + parser = parser.reset() 1.133 + threw = False 1.134 + try: 1.135 + parser.parse(""" 1.136 + interface A : B {}; 1.137 + interface B {}; 1.138 + interface C {}; 1.139 + B implements C; 1.140 + C implements A; 1.141 + """) 1.142 + results = parser.finish() 1.143 + except: 1.144 + threw = True 1.145 + 1.146 + harness.ok(threw, "Should not allow inheriting from an interface that indirectly implements us") 1.147 + 1.148 + parser = parser.reset() 1.149 + threw = False 1.150 + try: 1.151 + parser.parse(""" 1.152 + interface A : B {}; 1.153 + interface B : C {}; 1.154 + interface C {}; 1.155 + C implements A; 1.156 + """) 1.157 + results = parser.finish() 1.158 + except: 1.159 + threw = True 1.160 + 1.161 + harness.ok(threw, "Should not allow indirectly inheriting from an interface that implements us") 1.162 + 1.163 + parser = parser.reset() 1.164 + threw = False 1.165 + try: 1.166 + parser.parse(""" 1.167 + interface A : B {}; 1.168 + interface B : C {}; 1.169 + interface C {}; 1.170 + interface D {}; 1.171 + C implements D; 1.172 + D implements A; 1.173 + """) 1.174 + results = parser.finish() 1.175 + except: 1.176 + threw = True 1.177 + 1.178 + harness.ok(threw, "Should not allow indirectly inheriting from an interface that indirectly implements us") 1.179 + 1.180 + parser = parser.reset() 1.181 + threw = False 1.182 + try: 1.183 + parser.parse(""" 1.184 + interface A; 1.185 + interface B : A {}; 1.186 + """) 1.187 + results = parser.finish() 1.188 + except: 1.189 + threw = True 1.190 + 1.191 + harness.ok(threw, "Should not allow inheriting from an interface that is only forward declared") 1.192 + 1.193 + parser = parser.reset() 1.194 + parser.parse(""" 1.195 + [Constructor(long arg)] 1.196 + interface A { 1.197 + readonly attribute boolean x; 1.198 + void foo(); 1.199 + }; 1.200 + [Constructor] 1.201 + partial interface A { 1.202 + readonly attribute boolean y; 1.203 + void foo(long arg); 1.204 + }; 1.205 + """); 1.206 + results = parser.finish(); 1.207 + harness.check(len(results), 1, 1.208 + "Should have one result with partial interface") 1.209 + iface = results[0] 1.210 + harness.check(len(iface.members), 3, 1.211 + "Should have three members with partial interface") 1.212 + harness.check(iface.members[0].identifier.name, "x", 1.213 + "First member should be x with partial interface") 1.214 + harness.check(iface.members[1].identifier.name, "foo", 1.215 + "Second member should be foo with partial interface") 1.216 + harness.check(len(iface.members[1].signatures()), 2, 1.217 + "Should have two foo signatures with partial interface") 1.218 + harness.check(iface.members[2].identifier.name, "y", 1.219 + "Third member should be y with partial interface") 1.220 + harness.check(len(iface.ctor().signatures()), 2, 1.221 + "Should have two constructors with partial interface") 1.222 + 1.223 + parser = parser.reset() 1.224 + parser.parse(""" 1.225 + [Constructor] 1.226 + partial interface A { 1.227 + readonly attribute boolean y; 1.228 + void foo(long arg); 1.229 + }; 1.230 + [Constructor(long arg)] 1.231 + interface A { 1.232 + readonly attribute boolean x; 1.233 + void foo(); 1.234 + }; 1.235 + """); 1.236 + results = parser.finish(); 1.237 + harness.check(len(results), 1, 1.238 + "Should have one result with reversed partial interface") 1.239 + iface = results[0] 1.240 + harness.check(len(iface.members), 3, 1.241 + "Should have three members with reversed partial interface") 1.242 + harness.check(iface.members[0].identifier.name, "x", 1.243 + "First member should be x with reversed partial interface") 1.244 + harness.check(iface.members[1].identifier.name, "foo", 1.245 + "Second member should be foo with reversed partial interface") 1.246 + harness.check(len(iface.members[1].signatures()), 2, 1.247 + "Should have two foo signatures with reversed partial interface") 1.248 + harness.check(iface.members[2].identifier.name, "y", 1.249 + "Third member should be y with reversed partial interface") 1.250 + harness.check(len(iface.ctor().signatures()), 2, 1.251 + "Should have two constructors with reversed partial interface") 1.252 + 1.253 + parser = parser.reset() 1.254 + threw = False 1.255 + try: 1.256 + parser.parse(""" 1.257 + interface A { 1.258 + readonly attribute boolean x; 1.259 + }; 1.260 + interface A { 1.261 + readonly attribute boolean y; 1.262 + }; 1.263 + """) 1.264 + results = parser.finish() 1.265 + except: 1.266 + threw = True 1.267 + harness.ok(threw, 1.268 + "Should not allow two non-partial interfaces with the same name") 1.269 + 1.270 + parser = parser.reset() 1.271 + threw = False 1.272 + try: 1.273 + parser.parse(""" 1.274 + partial interface A { 1.275 + readonly attribute boolean x; 1.276 + }; 1.277 + partial interface A { 1.278 + readonly attribute boolean y; 1.279 + }; 1.280 + """) 1.281 + results = parser.finish() 1.282 + except: 1.283 + threw = True 1.284 + harness.ok(threw, 1.285 + "Must have a non-partial interface for a given name") 1.286 + 1.287 + parser = parser.reset() 1.288 + threw = False 1.289 + try: 1.290 + parser.parse(""" 1.291 + dictionary A { 1.292 + boolean x; 1.293 + }; 1.294 + partial interface A { 1.295 + readonly attribute boolean y; 1.296 + }; 1.297 + """) 1.298 + results = parser.finish() 1.299 + except: 1.300 + threw = True 1.301 + harness.ok(threw, 1.302 + "Should not allow a name collision between partial interface " 1.303 + "and other object") 1.304 + 1.305 + parser = parser.reset() 1.306 + threw = False 1.307 + try: 1.308 + parser.parse(""" 1.309 + dictionary A { 1.310 + boolean x; 1.311 + }; 1.312 + interface A { 1.313 + readonly attribute boolean y; 1.314 + }; 1.315 + """) 1.316 + results = parser.finish() 1.317 + except: 1.318 + threw = True 1.319 + harness.ok(threw, 1.320 + "Should not allow a name collision between interface " 1.321 + "and other object") 1.322 + 1.323 + parser = parser.reset() 1.324 + threw = False 1.325 + try: 1.326 + parser.parse(""" 1.327 + dictionary A { 1.328 + boolean x; 1.329 + }; 1.330 + interface A; 1.331 + """) 1.332 + results = parser.finish() 1.333 + except: 1.334 + threw = True 1.335 + harness.ok(threw, 1.336 + "Should not allow a name collision between external interface " 1.337 + "and other object") 1.338 + 1.339 + parser = parser.reset() 1.340 + threw = False 1.341 + try: 1.342 + parser.parse(""" 1.343 + interface A { 1.344 + readonly attribute boolean x; 1.345 + }; 1.346 + interface A; 1.347 + """) 1.348 + results = parser.finish() 1.349 + except: 1.350 + threw = True 1.351 + harness.ok(threw, 1.352 + "Should not allow a name collision between external interface " 1.353 + "and interface") 1.354 + 1.355 + parser = parser.reset() 1.356 + parser.parse(""" 1.357 + interface A; 1.358 + interface A; 1.359 + """) 1.360 + results = parser.finish() 1.361 + harness.ok(len(results) == 1 and 1.362 + isinstance(results[0], WebIDL.IDLExternalInterface), 1.363 + "Should allow name collisions between external interface " 1.364 + "declarations") 1.365 + 1.366 + parser = parser.reset() 1.367 + threw = False 1.368 + try: 1.369 + parser.parse(""" 1.370 + [SomeRandomAnnotation] 1.371 + interface A { 1.372 + readonly attribute boolean y; 1.373 + }; 1.374 + """) 1.375 + results = parser.finish() 1.376 + except: 1.377 + threw = True 1.378 + harness.ok(threw, 1.379 + "Should not allow unknown extended attributes on interfaces") 1.380 + 1.381 + parser = parser.reset() 1.382 + threw = False 1.383 + try: 1.384 + parser.parse(""" 1.385 + interface B {}; 1.386 + [ArrayClass] 1.387 + interface A : B { 1.388 + }; 1.389 + """) 1.390 + results = parser.finish() 1.391 + except: 1.392 + threw = True 1.393 + harness.ok(threw, 1.394 + "Should not allow [ArrayClass] on interfaces with parents") 1.395 + 1.396 + parser = parser.reset() 1.397 + threw = False 1.398 + try: 1.399 + parser.parse(""" 1.400 + [ArrayClass] 1.401 + interface A { 1.402 + }; 1.403 + """) 1.404 + results = parser.finish() 1.405 + except: 1.406 + threw = True 1.407 + harness.ok(not threw, 1.408 + "Should allow [ArrayClass] on interfaces without parents")