test_constructor.py (17026B)
1 import WebIDL 2 3 4 def 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="IsNotUAWidget"] 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=["IsNotUAWidget"], 281 ) 282 283 parser = parser.reset() 284 parser.parse( 285 "\n" 286 " interface TestPrefChromeOnlySCFuncConstructor {\n" 287 ' [ChromeOnly, Pref="dom.webidl.test1", SecureContext, ' 288 'Func="IsNotUAWidget"]\n' 289 " constructor();\n" 290 " };\n" 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=["IsNotUAWidget"], 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 WebIDL.WebIDLError: 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 WebIDL.WebIDLError: 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 WebIDL.WebIDLError: 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 WebIDL.WebIDLError: 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 WebIDL.WebIDLError: 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 WebIDL.WebIDLError: 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 WebIDL.WebIDLError: 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 WebIDL.WebIDLError: 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 WebIDL.WebIDLError: 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 WebIDL.WebIDLError: 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 WebIDL.WebIDLError: 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 WebIDL.WebIDLError: 548 threw = True 549 550 harness.ok( 551 threw, 552 "Can't have a constructor operation on a [LegacyNoInterfaceObject] interface", 553 ) 554 555 parser = parser.reset() 556 threw = False 557 try: 558 parser.parse( 559 """ 560 interface InterfaceWithPartial { 561 }; 562 563 partial interface InterfaceWithPartial { 564 constructor(); 565 }; 566 """ 567 ) 568 results = parser.finish() 569 except WebIDL.WebIDLError: 570 threw = True 571 572 harness.ok(threw, "Can't have a constructor operation on a partial interface") 573 574 parser = parser.reset() 575 threw = False 576 try: 577 parser.parse( 578 """ 579 interface InterfaceWithMixin { 580 }; 581 582 interface mixin Mixin { 583 constructor(); 584 }; 585 586 InterfaceWithMixin includes Mixin 587 """ 588 ) 589 results = parser.finish() 590 except WebIDL.WebIDLError: 591 threw = True 592 593 harness.ok(threw, "Can't have a constructor operation on a mixin")