1import WebIDL 2 3 4def WebIDLTest(parser, harness): 5 def checkArgument(argument, QName, name, type, optional, variadic): 6 harness.ok(isinstance(argument, WebIDL.IDLArgument), "Should be an IDLArgument") 7 harness.check( 8 argument.identifier.QName(), QName, "Argument has the right QName" 9 ) 10 harness.check(argument.identifier.name, name, "Argument has the right name") 11 harness.check(str(argument.type), type, "Argument has the right return type") 12 harness.check( 13 argument.optional, optional, "Argument has the right optional value" 14 ) 15 harness.check( 16 argument.variadic, variadic, "Argument has the right variadic value" 17 ) 18 19 def checkMethod( 20 method, 21 QName, 22 name, 23 signatures, 24 static=True, 25 getter=False, 26 setter=False, 27 deleter=False, 28 legacycaller=False, 29 stringifier=False, 30 chromeOnly=False, 31 htmlConstructor=False, 32 secureContext=False, 33 pref=None, 34 func=None, 35 ): 36 harness.ok(isinstance(method, WebIDL.IDLMethod), "Should be an IDLMethod") 37 harness.ok(method.isMethod(), "Method is a method") 38 harness.ok(not method.isAttr(), "Method is not an attr") 39 harness.ok(not method.isConst(), "Method is not a const") 40 harness.check(method.identifier.QName(), QName, "Method has the right QName") 41 harness.check(method.identifier.name, name, "Method has the right name") 42 harness.check(method.isStatic(), static, "Method has the correct static value") 43 harness.check(method.isGetter(), getter, "Method has the correct getter value") 44 harness.check(method.isSetter(), setter, "Method has the correct setter value") 45 harness.check( 46 method.isDeleter(), deleter, "Method has the correct deleter value" 47 ) 48 harness.check( 49 method.isLegacycaller(), 50 legacycaller, 51 "Method has the correct legacycaller value", 52 ) 53 harness.check( 54 method.isStringifier(), 55 stringifier, 56 "Method has the correct stringifier value", 57 ) 58 harness.check( 59 method.getExtendedAttribute("ChromeOnly") is not None, 60 chromeOnly, 61 "Method has the correct value for ChromeOnly", 62 ) 63 harness.check( 64 method.isHTMLConstructor(), 65 htmlConstructor, 66 "Method has the correct htmlConstructor value", 67 ) 68 harness.check( 69 len(method.signatures()), 70 len(signatures), 71 "Method has the correct number of signatures", 72 ) 73 harness.check( 74 method.getExtendedAttribute("Pref"), 75 pref, 76 "Method has the correct pref value", 77 ) 78 harness.check( 79 method.getExtendedAttribute("Func"), 80 func, 81 "Method has the correct func value", 82 ) 83 harness.check( 84 method.getExtendedAttribute("SecureContext") is not None, 85 secureContext, 86 "Method has the correct SecureContext value", 87 ) 88 89 sigpairs = zip(method.signatures(), signatures) 90 for (gotSignature, expectedSignature) in sigpairs: 91 (gotRetType, gotArgs) = gotSignature 92 (expectedRetType, expectedArgs) = expectedSignature 93 94 harness.check( 95 str(gotRetType), expectedRetType, "Method has the expected return type." 96 ) 97 98 for i in range(0, len(gotArgs)): 99 (QName, name, type, optional, variadic) = expectedArgs[i] 100 checkArgument(gotArgs[i], QName, name, type, optional, variadic) 101 102 def checkResults(results): 103 harness.check(len(results), 3, "Should be three productions") 104 harness.ok( 105 isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface" 106 ) 107 harness.ok( 108 isinstance(results[1], WebIDL.IDLInterface), "Should be an IDLInterface" 109 ) 110 harness.ok( 111 isinstance(results[2], WebIDL.IDLInterface), "Should be an IDLInterface" 112 ) 113 114 checkMethod( 115 results[0].ctor(), 116 "::TestConstructorNoArgs::constructor", 117 "constructor", 118 [("TestConstructorNoArgs (Wrapper)", [])], 119 ) 120 harness.check( 121 len(results[0].members), 0, "TestConstructorNoArgs should not have members" 122 ) 123 checkMethod( 124 results[1].ctor(), 125 "::TestConstructorWithArgs::constructor", 126 "constructor", 127 [ 128 ( 129 "TestConstructorWithArgs (Wrapper)", 130 [ 131 ( 132 "::TestConstructorWithArgs::constructor::name", 133 "name", 134 "String", 135 False, 136 False, 137 ) 138 ], 139 ) 140 ], 141 ) 142 harness.check( 143 len(results[1].members), 144 0, 145 "TestConstructorWithArgs should not have members", 146 ) 147 checkMethod( 148 results[2].ctor(), 149 "::TestConstructorOverloads::constructor", 150 "constructor", 151 [ 152 ( 153 "TestConstructorOverloads (Wrapper)", 154 [ 155 ( 156 "::TestConstructorOverloads::constructor::foo", 157 "foo", 158 "Object", 159 False, 160 False, 161 ) 162 ], 163 ), 164 ( 165 "TestConstructorOverloads (Wrapper)", 166 [ 167 ( 168 "::TestConstructorOverloads::constructor::bar", 169 "bar", 170 "Boolean", 171 False, 172 False, 173 ) 174 ], 175 ), 176 ], 177 ) 178 harness.check( 179 len(results[2].members), 180 0, 181 "TestConstructorOverloads should not have members", 182 ) 183 184 parser.parse( 185 """ 186 interface TestConstructorNoArgs { 187 constructor(); 188 }; 189 190 interface TestConstructorWithArgs { 191 constructor(DOMString name); 192 }; 193 194 interface TestConstructorOverloads { 195 constructor(object foo); 196 constructor(boolean bar); 197 }; 198 """ 199 ) 200 results = parser.finish() 201 checkResults(results) 202 203 parser = parser.reset() 204 parser.parse( 205 """ 206 interface TestPrefConstructor { 207 [Pref="dom.webidl.test1"] constructor(); 208 }; 209 """ 210 ) 211 results = parser.finish() 212 harness.check(len(results), 1, "Should be one production") 213 harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") 214 215 checkMethod( 216 results[0].ctor(), 217 "::TestPrefConstructor::constructor", 218 "constructor", 219 [("TestPrefConstructor (Wrapper)", [])], 220 pref=["dom.webidl.test1"], 221 ) 222 223 parser = parser.reset() 224 parser.parse( 225 """ 226 interface TestChromeOnlyConstructor { 227 [ChromeOnly] constructor(); 228 }; 229 """ 230 ) 231 results = parser.finish() 232 harness.check(len(results), 1, "Should be one production") 233 harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") 234 235 checkMethod( 236 results[0].ctor(), 237 "::TestChromeOnlyConstructor::constructor", 238 "constructor", 239 [("TestChromeOnlyConstructor (Wrapper)", [])], 240 chromeOnly=True, 241 ) 242 243 parser = parser.reset() 244 parser.parse( 245 """ 246 interface TestSCConstructor { 247 [SecureContext] constructor(); 248 }; 249 """ 250 ) 251 results = parser.finish() 252 harness.check(len(results), 1, "Should be one production") 253 harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") 254 255 checkMethod( 256 results[0].ctor(), 257 "::TestSCConstructor::constructor", 258 "constructor", 259 [("TestSCConstructor (Wrapper)", [])], 260 secureContext=True, 261 ) 262 263 parser = parser.reset() 264 parser.parse( 265 """ 266 interface TestFuncConstructor { 267 [Func="Document::IsWebAnimationsEnabled"] constructor(); 268 }; 269 """ 270 ) 271 results = parser.finish() 272 harness.check(len(results), 1, "Should be one production") 273 harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") 274 275 checkMethod( 276 results[0].ctor(), 277 "::TestFuncConstructor::constructor", 278 "constructor", 279 [("TestFuncConstructor (Wrapper)", [])], 280 func=["Document::IsWebAnimationsEnabled"], 281 ) 282 283 parser = parser.reset() 284 parser.parse( 285 """ 286 interface TestPrefChromeOnlySCFuncConstructor { 287 [ChromeOnly, Pref="dom.webidl.test1", SecureContext, Func="Document::IsWebAnimationsEnabled"] 288 constructor(); 289 }; 290 """ 291 ) 292 results = parser.finish() 293 harness.check(len(results), 1, "Should be one production") 294 harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") 295 296 checkMethod( 297 results[0].ctor(), 298 "::TestPrefChromeOnlySCFuncConstructor::constructor", 299 "constructor", 300 [("TestPrefChromeOnlySCFuncConstructor (Wrapper)", [])], 301 func=["Document::IsWebAnimationsEnabled"], 302 pref=["dom.webidl.test1"], 303 chromeOnly=True, 304 secureContext=True, 305 ) 306 307 parser = parser.reset() 308 parser.parse( 309 """ 310 interface TestHTMLConstructor { 311 [HTMLConstructor] constructor(); 312 }; 313 """ 314 ) 315 results = parser.finish() 316 harness.check(len(results), 1, "Should be one production") 317 harness.ok(isinstance(results[0], WebIDL.IDLInterface), "Should be an IDLInterface") 318 319 checkMethod( 320 results[0].ctor(), 321 "::TestHTMLConstructor::constructor", 322 "constructor", 323 [("TestHTMLConstructor (Wrapper)", [])], 324 htmlConstructor=True, 325 ) 326 327 parser = parser.reset() 328 threw = False 329 try: 330 parser.parse( 331 """ 332 interface TestChromeOnlyConstructor { 333 constructor() 334 [ChromeOnly] constructor(DOMString a); 335 }; 336 """ 337 ) 338 results = parser.finish() 339 except: 340 threw = True 341 342 harness.ok(threw, "Can't have both a constructor and a ChromeOnly constructor") 343 344 # Test HTMLConstructor with argument 345 parser = parser.reset() 346 threw = False 347 try: 348 parser.parse( 349 """ 350 interface TestHTMLConstructorWithArgs { 351 [HTMLConstructor] constructor(DOMString a); 352 }; 353 """ 354 ) 355 results = parser.finish() 356 except: 357 threw = True 358 359 harness.ok(threw, "HTMLConstructor should take no argument") 360 361 # Test HTMLConstructor on a callback interface 362 parser = parser.reset() 363 threw = False 364 try: 365 parser.parse( 366 """ 367 callback interface TestHTMLConstructorOnCallbackInterface { 368 [HTMLConstructor] constructor(); 369 }; 370 """ 371 ) 372 results = parser.finish() 373 except: 374 threw = True 375 376 harness.ok(threw, "HTMLConstructor can't be used on a callback interface") 377 378 # Test HTMLConstructor and constructor operation 379 parser = parser.reset() 380 threw = False 381 try: 382 parser.parse( 383 """ 384 interface TestHTMLConstructorAndConstructor { 385 constructor(); 386 [HTMLConstructor] constructor(); 387 }; 388 """ 389 ) 390 results = parser.finish() 391 except: 392 threw = True 393 394 harness.ok(threw, "Can't have both a constructor and a HTMLConstructor") 395 396 parser = parser.reset() 397 threw = False 398 try: 399 parser.parse( 400 """ 401 interface TestHTMLConstructorAndConstructor { 402 [Throws] 403 constructor(); 404 [HTMLConstructor] constructor(); 405 }; 406 """ 407 ) 408 results = parser.finish() 409 except: 410 threw = True 411 412 harness.ok(threw, "Can't have both a throwing constructor and a HTMLConstructor") 413 414 parser = parser.reset() 415 threw = False 416 try: 417 parser.parse( 418 """ 419 interface TestHTMLConstructorAndConstructor { 420 constructor(DOMString a); 421 [HTMLConstructor] constructor(); 422 }; 423 """ 424 ) 425 results = parser.finish() 426 except: 427 threw = True 428 429 harness.ok(threw, "Can't have both a HTMLConstructor and a constructor operation") 430 431 parser = parser.reset() 432 threw = False 433 try: 434 parser.parse( 435 """ 436 interface TestHTMLConstructorAndConstructor { 437 [Throws] 438 constructor(DOMString a); 439 [HTMLConstructor] constructor(); 440 }; 441 """ 442 ) 443 results = parser.finish() 444 except: 445 threw = True 446 447 harness.ok( 448 threw, 449 "Can't have both a HTMLConstructor and a throwing constructor " "operation", 450 ) 451 452 # Test HTMLConstructor and [ChromeOnly] constructor operation 453 parser = parser.reset() 454 threw = False 455 try: 456 parser.parse( 457 """ 458 interface TestHTMLConstructorAndConstructor { 459 [ChromeOnly] 460 constructor(); 461 [HTMLConstructor] constructor(); 462 }; 463 """ 464 ) 465 results = parser.finish() 466 except: 467 threw = True 468 469 harness.ok(threw, "Can't have both a ChromeOnly constructor and a HTMLConstructor") 470 471 parser = parser.reset() 472 threw = False 473 try: 474 parser.parse( 475 """ 476 interface TestHTMLConstructorAndConstructor { 477 [Throws, ChromeOnly] 478 constructor(); 479 [HTMLConstructor] constructor(); 480 }; 481 """ 482 ) 483 results = parser.finish() 484 except: 485 threw = True 486 487 harness.ok( 488 threw, 489 "Can't have both a throwing chromeonly constructor and a " "HTMLConstructor", 490 ) 491 492 parser = parser.reset() 493 threw = False 494 try: 495 parser.parse( 496 """ 497 interface TestHTMLConstructorAndConstructor { 498 [ChromeOnly] 499 constructor(DOMString a); 500 [HTMLConstructor] constructor(); 501 }; 502 """ 503 ) 504 results = parser.finish() 505 except: 506 threw = True 507 508 harness.ok( 509 threw, 510 "Can't have both a HTMLConstructor and a chromeonly constructor " "operation", 511 ) 512 513 parser = parser.reset() 514 threw = False 515 try: 516 parser.parse( 517 """ 518 interface TestHTMLConstructorAndConstructor { 519 [Throws, ChromeOnly] 520 constructor(DOMString a); 521 [HTMLConstructor] constructor(); 522 }; 523 """ 524 ) 525 results = parser.finish() 526 except: 527 threw = True 528 529 harness.ok( 530 threw, 531 "Can't have both a HTMLConstructor and a throwing chromeonly " 532 "constructor operation", 533 ) 534 535 parser = parser.reset() 536 threw = False 537 try: 538 parser.parse( 539 """ 540 [LegacyNoInterfaceObject] 541 interface InterfaceWithoutInterfaceObject { 542 constructor(); 543 }; 544 """ 545 ) 546 results = parser.finish() 547 except: 548 threw = True 549 550 harness.ok( 551 threw, 552 "Can't have a constructor operation on a [LegacyNoInterfaceObject] " 553 "interface", 554 ) 555 556 parser = parser.reset() 557 threw = False 558 try: 559 parser.parse( 560 """ 561 interface InterfaceWithPartial { 562 }; 563 564 partial interface InterfaceWithPartial { 565 constructor(); 566 }; 567 """ 568 ) 569 results = parser.finish() 570 except: 571 threw = True 572 573 harness.ok(threw, "Can't have a constructor operation on a partial interface") 574 575 parser = parser.reset() 576 threw = False 577 try: 578 parser.parse( 579 """ 580 interface InterfaceWithMixin { 581 }; 582 583 interface mixin Mixin { 584 constructor(); 585 }; 586 587 InterfaceWithMixin includes Mixin 588 """ 589 ) 590 results = parser.finish() 591 except: 592 threw = True 593 594 harness.ok(threw, "Can't have a constructor operation on a mixin") 595