test_interfacemixin.py (14010B)
1 import WebIDL 2 3 4 def WebIDLTest(parser, harness): 5 parser.parse("interface mixin Foo { };") 6 results = parser.finish() 7 harness.ok(True, "Empty interface mixin parsed without error.") 8 harness.check(len(results), 1, "Should be one production") 9 harness.ok( 10 isinstance(results[0], WebIDL.IDLInterfaceMixin), 11 "Should be an IDLInterfaceMixin", 12 ) 13 mixin = results[0] 14 harness.check( 15 mixin.identifier.QName(), "::Foo", "Interface mixin has the right QName" 16 ) 17 harness.check(mixin.identifier.name, "Foo", "Interface mixin has the right name") 18 19 parser = parser.reset() 20 parser.parse( 21 """ 22 interface mixin QNameBase { 23 const long foo = 3; 24 }; 25 """ 26 ) 27 results = parser.finish() 28 harness.check(len(results), 1, "Should be one productions") 29 harness.ok( 30 isinstance(results[0], WebIDL.IDLInterfaceMixin), 31 "Should be an IDLInterfaceMixin", 32 ) 33 harness.check(len(results[0].members), 1, "Expect 1 productions") 34 mixin = results[0] 35 harness.check( 36 mixin.members[0].identifier.QName(), 37 "::QNameBase::foo", 38 "Member has the right QName", 39 ) 40 41 parser = parser.reset() 42 parser.parse( 43 """ 44 interface mixin A { 45 readonly attribute boolean x; 46 undefined foo(); 47 }; 48 partial interface mixin A { 49 readonly attribute boolean y; 50 undefined foo(long arg); 51 }; 52 """ 53 ) 54 results = parser.finish() 55 harness.check( 56 len(results), 2, "Should have two results with partial interface mixin" 57 ) 58 mixin = results[0] 59 harness.check( 60 len(mixin.members), 3, "Should have three members with partial interface mixin" 61 ) 62 harness.check( 63 mixin.members[0].identifier.name, 64 "x", 65 "First member should be x with partial interface mixin", 66 ) 67 harness.check( 68 mixin.members[1].identifier.name, 69 "foo", 70 "Second member should be foo with partial interface mixin", 71 ) 72 harness.check( 73 len(mixin.members[1].signatures()), 74 2, 75 "Should have two foo signatures with partial interface mixin", 76 ) 77 harness.check( 78 mixin.members[2].identifier.name, 79 "y", 80 "Third member should be y with partial interface mixin", 81 ) 82 83 parser = parser.reset() 84 parser.parse( 85 """ 86 partial interface mixin A { 87 readonly attribute boolean y; 88 undefined foo(long arg); 89 }; 90 interface mixin A { 91 readonly attribute boolean x; 92 undefined foo(); 93 }; 94 """ 95 ) 96 results = parser.finish() 97 harness.check( 98 len(results), 2, "Should have two results with reversed partial interface mixin" 99 ) 100 mixin = results[1] 101 harness.check( 102 len(mixin.members), 103 3, 104 "Should have three members with reversed partial interface mixin", 105 ) 106 harness.check( 107 mixin.members[0].identifier.name, 108 "x", 109 "First member should be x with reversed partial interface mixin", 110 ) 111 harness.check( 112 mixin.members[1].identifier.name, 113 "foo", 114 "Second member should be foo with reversed partial interface mixin", 115 ) 116 harness.check( 117 len(mixin.members[1].signatures()), 118 2, 119 "Should have two foo signatures with reversed partial interface mixin", 120 ) 121 harness.check( 122 mixin.members[2].identifier.name, 123 "y", 124 "Third member should be y with reversed partial interface mixin", 125 ) 126 127 parser = parser.reset() 128 parser.parse( 129 """ 130 interface Interface {}; 131 interface mixin Mixin { 132 attribute short x; 133 }; 134 Interface includes Mixin; 135 """ 136 ) 137 results = parser.finish() 138 iface = results[0] 139 harness.check(len(iface.members), 1, "Should merge members from mixins") 140 harness.check( 141 iface.members[0].identifier.name, "x", "Should merge members from mixins" 142 ) 143 144 parser = parser.reset() 145 threw = False 146 try: 147 parser.parse( 148 """ 149 interface mixin A { 150 readonly attribute boolean x; 151 }; 152 interface mixin A { 153 readonly attribute boolean y; 154 }; 155 """ 156 ) 157 results = parser.finish() 158 except WebIDL.WebIDLError: 159 threw = True 160 harness.ok( 161 threw, "Should not allow two non-partial interface mixins with the same name" 162 ) 163 164 parser = parser.reset() 165 threw = False 166 try: 167 parser.parse( 168 """ 169 partial interface mixin A { 170 readonly attribute boolean x; 171 }; 172 partial interface mixin A { 173 readonly attribute boolean y; 174 }; 175 """ 176 ) 177 results = parser.finish() 178 except WebIDL.WebIDLError: 179 threw = True 180 harness.ok(threw, "Must have a non-partial interface mixin for a given name") 181 182 parser = parser.reset() 183 threw = False 184 try: 185 parser.parse( 186 """ 187 dictionary A { 188 boolean x; 189 }; 190 partial interface mixin A { 191 readonly attribute boolean y; 192 }; 193 """ 194 ) 195 results = parser.finish() 196 except WebIDL.WebIDLError: 197 threw = True 198 harness.ok( 199 threw, 200 "Should not allow a name collision between partial interface " 201 "mixin and other object", 202 ) 203 204 parser = parser.reset() 205 threw = False 206 try: 207 parser.parse( 208 """ 209 dictionary A { 210 boolean x; 211 }; 212 interface mixin A { 213 readonly attribute boolean y; 214 }; 215 """ 216 ) 217 results = parser.finish() 218 except WebIDL.WebIDLError: 219 threw = True 220 harness.ok( 221 threw, 222 "Should not allow a name collision between interface mixin and other object", 223 ) 224 225 parser = parser.reset() 226 threw = False 227 try: 228 parser.parse( 229 """ 230 interface mixin A { 231 readonly attribute boolean x; 232 }; 233 interface A; 234 """ 235 ) 236 results = parser.finish() 237 except WebIDL.WebIDLError: 238 threw = True 239 harness.ok( 240 threw, 241 "Should not allow a name collision between external interface " 242 "and interface mixin", 243 ) 244 245 parser = parser.reset() 246 threw = False 247 try: 248 parser.parse( 249 """ 250 [SomeRandomAnnotation] 251 interface mixin A { 252 readonly attribute boolean y; 253 }; 254 """ 255 ) 256 results = parser.finish() 257 except WebIDL.WebIDLError: 258 threw = True 259 harness.ok( 260 threw, "Should not allow unknown extended attributes on interface mixins" 261 ) 262 263 parser = parser.reset() 264 threw = False 265 try: 266 parser.parse( 267 """ 268 interface mixin A { 269 getter double (DOMString propertyName); 270 }; 271 """ 272 ) 273 results = parser.finish() 274 except WebIDL.WebIDLError: 275 threw = True 276 harness.ok(threw, "Should not allow getters on interface mixins") 277 278 parser = parser.reset() 279 threw = False 280 try: 281 parser.parse( 282 """ 283 interface mixin A { 284 setter undefined (DOMString propertyName, double propertyValue); 285 }; 286 """ 287 ) 288 results = parser.finish() 289 except WebIDL.WebIDLError: 290 threw = True 291 harness.ok(threw, "Should not allow setters on interface mixins") 292 293 parser = parser.reset() 294 threw = False 295 try: 296 parser.parse( 297 """ 298 interface mixin A { 299 deleter undefined (DOMString propertyName); 300 }; 301 """ 302 ) 303 results = parser.finish() 304 except WebIDL.WebIDLError: 305 threw = True 306 harness.ok(threw, "Should not allow deleters on interface mixins") 307 308 parser = parser.reset() 309 threw = False 310 try: 311 parser.parse( 312 """ 313 interface mixin A { 314 legacycaller double compute(double x); 315 }; 316 """ 317 ) 318 results = parser.finish() 319 except WebIDL.WebIDLError: 320 threw = True 321 harness.ok(threw, "Should not allow legacycallers on interface mixins") 322 323 parser = parser.reset() 324 threw = False 325 try: 326 parser.parse( 327 """ 328 interface mixin A { 329 inherit attribute x; 330 }; 331 """ 332 ) 333 results = parser.finish() 334 except WebIDL.WebIDLError: 335 threw = True 336 harness.ok(threw, "Should not allow inherited attribute on interface mixins") 337 338 parser = parser.reset() 339 threw = False 340 try: 341 parser.parse( 342 """ 343 interface Interface {}; 344 interface NotMixin { 345 attribute short x; 346 }; 347 Interface includes NotMixin; 348 """ 349 ) 350 results = parser.finish() 351 except WebIDL.WebIDLError: 352 threw = True 353 harness.ok(threw, "Should fail if the right side does not point an interface mixin") 354 355 parser = parser.reset() 356 threw = False 357 try: 358 parser.parse( 359 """ 360 interface mixin NotInterface {}; 361 interface mixin Mixin { 362 attribute short x; 363 }; 364 NotInterface includes Mixin; 365 """ 366 ) 367 results = parser.finish() 368 except WebIDL.WebIDLError: 369 threw = True 370 harness.ok(threw, "Should fail if the left side does not point an interface") 371 372 parser = parser.reset() 373 threw = False 374 try: 375 parser.parse( 376 """ 377 interface mixin Mixin { 378 iterable<DOMString>; 379 }; 380 """ 381 ) 382 results = parser.finish() 383 except WebIDL.WebIDLError: 384 threw = True 385 harness.ok(threw, "Should fail if an interface mixin includes iterable") 386 387 parser = parser.reset() 388 threw = False 389 try: 390 parser.parse( 391 """ 392 interface mixin Mixin { 393 setlike<DOMString>; 394 }; 395 """ 396 ) 397 results = parser.finish() 398 except WebIDL.WebIDLError: 399 threw = True 400 harness.ok(threw, "Should fail if an interface mixin includes setlike") 401 402 parser = parser.reset() 403 threw = False 404 try: 405 parser.parse( 406 """ 407 interface mixin Mixin { 408 maplike<DOMString, DOMString>; 409 }; 410 """ 411 ) 412 results = parser.finish() 413 except WebIDL.WebIDLError: 414 threw = True 415 harness.ok(threw, "Should fail if an interface mixin includes maplike") 416 417 parser = parser.reset() 418 threw = False 419 try: 420 parser.parse( 421 """ 422 interface Interface { 423 attribute short attr; 424 }; 425 interface mixin Mixin { 426 attribute short attr; 427 }; 428 Interface includes Mixin; 429 """ 430 ) 431 results = parser.finish() 432 except WebIDL.WebIDLError: 433 threw = True 434 harness.ok( 435 threw, "Should fail if the included mixin interface has duplicated member" 436 ) 437 438 parser = parser.reset() 439 threw = False 440 try: 441 parser.parse( 442 """ 443 interface Interface {}; 444 interface mixin Mixin1 { 445 attribute short attr; 446 }; 447 interface mixin Mixin2 { 448 attribute short attr; 449 }; 450 Interface includes Mixin1; 451 Interface includes Mixin2; 452 """ 453 ) 454 results = parser.finish() 455 except WebIDL.WebIDLError: 456 threw = True 457 harness.ok( 458 threw, "Should fail if the included mixin interfaces have duplicated member" 459 ) 460 461 parser = parser.reset() 462 parser.parse( 463 """ 464 [Global=Window, Exposed=Window] interface Window {}; 465 [Global=Worker, Exposed=Worker] interface Worker {}; 466 [Exposed=Window] 467 interface Base {}; 468 interface mixin Mixin { 469 Base returnSelf(); 470 }; 471 Base includes Mixin; 472 """ 473 ) 474 results = parser.finish() 475 base = results[2] 476 attr = base.members[0] 477 harness.check( 478 attr.exposureSet, 479 set(["Window"]), 480 "Should expose on globals where the base interfaces are exposed", 481 ) 482 483 parser = parser.reset() 484 parser.parse( 485 """ 486 [Global=Window, Exposed=Window] interface Window {}; 487 [Global=Worker, Exposed=Worker] interface Worker {}; 488 [Exposed=Window] 489 interface Base {}; 490 [Exposed=Window] 491 interface mixin Mixin { 492 attribute short a; 493 }; 494 Base includes Mixin; 495 """ 496 ) 497 results = parser.finish() 498 base = results[2] 499 attr = base.members[0] 500 harness.check( 501 attr.exposureSet, set(["Window"]), "Should follow [Exposed] on interface mixin" 502 ) 503 504 parser = parser.reset() 505 parser.parse( 506 """ 507 [Global=Window, Exposed=Window] interface Window {}; 508 [Global=Worker, Exposed=Worker] interface Worker {}; 509 [Exposed=Window] 510 interface Base1 {}; 511 [Exposed=Worker] 512 interface Base2 {}; 513 interface mixin Mixin { 514 attribute short a; 515 }; 516 Base1 includes Mixin; 517 Base2 includes Mixin; 518 """ 519 ) 520 results = parser.finish() 521 base = results[2] 522 attr = base.members[0] 523 harness.check( 524 attr.exposureSet, 525 set(["Window", "Worker"]), 526 "Should expose on all globals where including interfaces are exposed", 527 ) 528 base = results[3] 529 attr = base.members[0] 530 harness.check( 531 attr.exposureSet, 532 set(["Window", "Worker"]), 533 "Should expose on all globals where including interfaces are exposed", 534 )