test_language.js (14686B)
1 function assert(actual, expected, message) { 2 if (arguments.length == 1) 3 expected = true; 4 5 if (Object.is(actual, expected)) 6 return; 7 8 if (actual !== null && expected !== null 9 && typeof actual == 'object' && typeof expected == 'object' 10 && actual.toString() === expected.toString()) 11 return; 12 13 throw Error("assertion failed: got |" + actual + "|" + 14 ", expected |" + expected + "|" + 15 (message ? " (" + message + ")" : "")); 16 } 17 18 function assert_throws(expected_error, func) 19 { 20 var err = false; 21 try { 22 func(); 23 } catch(e) { 24 err = true; 25 if (!(e instanceof expected_error)) { 26 throw Error("unexpected exception type"); 27 } 28 } 29 if (!err) { 30 throw Error("expected exception"); 31 } 32 } 33 34 // load more elaborate version of assert if available 35 try { __loadScript("test_assert.js"); } catch(e) {} 36 37 /*----------------*/ 38 39 function test_op1() 40 { 41 var r, a; 42 r = 1 + 2; 43 assert(r, 3, "1 + 2 === 3"); 44 45 r = 1 - 2; 46 assert(r, -1, "1 - 2 === -1"); 47 48 r = -1; 49 assert(r, -1, "-1 === -1"); 50 51 r = +2; 52 assert(r, 2, "+2 === 2"); 53 54 r = 2 * 3; 55 assert(r, 6, "2 * 3 === 6"); 56 57 r = 4 / 2; 58 assert(r, 2, "4 / 2 === 2"); 59 60 r = 4 % 3; 61 assert(r, 1, "4 % 3 === 3"); 62 63 r = 4 << 2; 64 assert(r, 16, "4 << 2 === 16"); 65 66 r = 1 << 0; 67 assert(r, 1, "1 << 0 === 1"); 68 69 r = 1 << 31; 70 assert(r, -2147483648, "1 << 31 === -2147483648"); 71 72 r = 1 << 32; 73 assert(r, 1, "1 << 32 === 1"); 74 75 r = (1 << 31) < 0; 76 assert(r, true, "(1 << 31) < 0 === true"); 77 78 r = -4 >> 1; 79 assert(r, -2, "-4 >> 1 === -2"); 80 81 r = -4 >>> 1; 82 assert(r, 0x7ffffffe, "-4 >>> 1 === 0x7ffffffe"); 83 84 r = 1 & 1; 85 assert(r, 1, "1 & 1 === 1"); 86 87 r = 0 | 1; 88 assert(r, 1, "0 | 1 === 1"); 89 90 r = 1 ^ 1; 91 assert(r, 0, "1 ^ 1 === 0"); 92 93 r = ~1; 94 assert(r, -2, "~1 === -2"); 95 96 r = !1; 97 assert(r, false, "!1 === false"); 98 99 assert((1 < 2), true, "(1 < 2) === true"); 100 101 assert((2 > 1), true, "(2 > 1) === true"); 102 103 assert(('b' > 'a'), true, "('b' > 'a') === true"); 104 105 assert(2 ** 8, 256, "2 ** 8 === 256"); 106 } 107 108 function test_cvt() 109 { 110 assert((NaN | 0) === 0); 111 assert((Infinity | 0) === 0); 112 assert(((-Infinity) | 0) === 0); 113 assert(("12345" | 0) === 12345); 114 assert(("0x12345" | 0) === 0x12345); 115 assert(((4294967296 * 3 - 4) | 0) === -4); 116 117 assert(("12345" >>> 0) === 12345); 118 assert(("0x12345" >>> 0) === 0x12345); 119 assert((NaN >>> 0) === 0); 120 assert((Infinity >>> 0) === 0); 121 assert(((-Infinity) >>> 0) === 0); 122 assert(((4294967296 * 3 - 4) >>> 0) === (4294967296 - 4)); 123 assert((19686109595169230000).toString() === "19686109595169230000"); 124 } 125 126 function test_eq() 127 { 128 assert(null == undefined); 129 assert(undefined == null); 130 assert(true == 1); 131 assert(0 == false); 132 assert("" == 0); 133 assert("123" == 123); 134 assert("122" != 123); 135 assert((new Number(1)) == 1); 136 assert(2 == (new Number(2))); 137 assert((new String("abc")) == "abc"); 138 assert({} != "abc"); 139 } 140 141 function test_inc_dec() 142 { 143 var a, r; 144 145 a = 1; 146 r = a++; 147 assert(r === 1 && a === 2, true, "++"); 148 149 a = 1; 150 r = ++a; 151 assert(r === 2 && a === 2, true, "++"); 152 153 a = 1; 154 r = a--; 155 assert(r === 1 && a === 0, true, "--"); 156 157 a = 1; 158 r = --a; 159 assert(r === 0 && a === 0, true, "--"); 160 161 a = {x:true}; 162 a.x++; 163 assert(a.x, 2, "++"); 164 165 a = {x:true}; 166 a.x--; 167 assert(a.x, 0, "--"); 168 169 a = [true]; 170 a[0]++; 171 assert(a[0], 2, "++"); 172 173 a = {x:true}; 174 r = a.x++; 175 assert(r === 1 && a.x === 2, true, "++"); 176 177 a = {x:true}; 178 r = a.x--; 179 assert(r === 1 && a.x === 0, true, "--"); 180 181 a = [true]; 182 r = a[0]++; 183 assert(r === 1 && a[0] === 2, true, "++"); 184 185 a = [true]; 186 r = a[0]--; 187 assert(r === 1 && a[0] === 0, true, "--"); 188 } 189 190 function F(x) 191 { 192 this.x = x; 193 } 194 195 function test_op2() 196 { 197 var a, b; 198 a = new Object; 199 a.x = 1; 200 assert(a.x, 1, "new"); 201 b = new F(2); 202 assert(b.x, 2, "new"); 203 204 a = {x : 2}; 205 assert(("x" in a), true, "in"); 206 assert(("y" in a), false, "in"); 207 208 a = {}; 209 assert((a instanceof Object), true, "instanceof"); 210 assert((a instanceof String), false, "instanceof"); 211 212 assert((typeof 1), "number", "typeof"); 213 assert((typeof Object), "function", "typeof"); 214 assert((typeof null), "object", "typeof"); 215 assert((typeof unknown_var), "undefined", "typeof"); 216 217 a = {x: 1, if: 2, async: 3}; 218 assert(a.if === 2); 219 assert(a.async === 3); 220 } 221 222 function test_delete() 223 { 224 var a, err; 225 226 a = {x: 1, y: 1}; 227 assert((delete a.x), true, "delete"); 228 assert(("x" in a), false, "delete"); 229 230 /* the following are not tested by test262 */ 231 assert(delete "abc"[100], true); 232 233 err = false; 234 try { 235 delete null.a; 236 } catch(e) { 237 err = (e instanceof TypeError); 238 } 239 assert(err, true, "delete"); 240 241 err = false; 242 try { 243 a = { f() { delete super.a; } }; 244 a.f(); 245 } catch(e) { 246 err = (e instanceof ReferenceError); 247 } 248 assert(err, true, "delete"); 249 } 250 251 function test_constructor() 252 { 253 function *G() {} 254 let ex 255 try { new G() } catch (ex_) { ex = ex_ } 256 assert(ex instanceof TypeError) 257 assert(ex.message, "G is not a constructor") 258 } 259 260 function test_prototype() 261 { 262 var f = function f() { }; 263 assert(f.prototype.constructor, f, "prototype"); 264 265 var g = function g() { }; 266 /* QuickJS bug */ 267 Object.defineProperty(g, "prototype", { writable: false }); 268 assert(g.prototype.constructor, g, "prototype"); 269 } 270 271 function test_arguments() 272 { 273 function f2() { 274 assert(arguments.length, 2, "arguments"); 275 assert(arguments[0], 1, "arguments"); 276 assert(arguments[1], 3, "arguments"); 277 } 278 f2(1, 3); 279 } 280 281 function test_class() 282 { 283 var o; 284 class C { 285 constructor() { 286 this.x = 10; 287 } 288 f() { 289 return 1; 290 } 291 static F() { 292 return -1; 293 } 294 get y() { 295 return 12; 296 } 297 }; 298 class D extends C { 299 constructor() { 300 super(); 301 this.z = 20; 302 } 303 g() { 304 return 2; 305 } 306 static G() { 307 return -2; 308 } 309 h() { 310 return super.f(); 311 } 312 static H() { 313 return super["F"](); 314 } 315 } 316 317 assert(C.F() === -1); 318 assert(Object.getOwnPropertyDescriptor(C.prototype, "y").get.name === "get y"); 319 320 o = new C(); 321 assert(o.f() === 1); 322 assert(o.x === 10); 323 324 assert(D.F() === -1); 325 assert(D.G() === -2); 326 assert(D.H() === -1); 327 328 o = new D(); 329 assert(o.f() === 1); 330 assert(o.g() === 2); 331 assert(o.x === 10); 332 assert(o.z === 20); 333 assert(o.h() === 1); 334 335 /* test class name scope */ 336 var E1 = class E { static F() { return E; } }; 337 assert(E1 === E1.F()); 338 339 class S { 340 static x = 42; 341 static y = S.x; 342 static z = this.x; 343 } 344 assert(S.x === 42); 345 assert(S.y === 42); 346 assert(S.z === 42); 347 348 class P { 349 get = () => "123"; 350 static() { return 42; } 351 } 352 assert(new P().get() === "123"); 353 assert(new P().static() === 42); 354 }; 355 356 function test_template() 357 { 358 var a, b; 359 b = 123; 360 a = `abc${b}d`; 361 assert(a, "abc123d"); 362 363 a = String.raw `abc${b}d`; 364 assert(a, "abc123d"); 365 366 a = "aaa"; 367 b = "bbb"; 368 assert(`aaa${a, b}ccc`, "aaabbbccc"); 369 } 370 371 function test_template_skip() 372 { 373 var a = "Bar"; 374 var { b = `${a + `a${a}` }baz` } = {}; 375 assert(b, "BaraBarbaz"); 376 } 377 378 function test_object_literal() 379 { 380 var x = 0, get = 1, set = 2, async = 3; 381 a = { get: 2, set: 3, async: 4, get a(){ return this.get} }; 382 assert(JSON.stringify(a), '{"get":2,"set":3,"async":4,"a":2}'); 383 assert(a.a === 2); 384 385 a = { x, get, set, async }; 386 assert(JSON.stringify(a), '{"x":0,"get":1,"set":2,"async":3}'); 387 } 388 389 function test_regexp_skip() 390 { 391 var a, b; 392 [a, b = /abc\(/] = [1]; 393 assert(a === 1); 394 395 [a, b =/abc\(/] = [2]; 396 assert(a === 2); 397 } 398 399 function test_labels() 400 { 401 do x: { break x; } while(0); 402 if (1) 403 x: { break x; } 404 else 405 x: { break x; } 406 with ({}) x: { break x; }; 407 while (0) x: { break x; }; 408 } 409 410 function test_labels2() 411 { 412 while (1) label: break 413 var i = 0 414 while (i < 3) label: { 415 if (i > 0) 416 break 417 i++ 418 } 419 assert(i, 1) 420 for (;;) label: break 421 for (i = 0; i < 3; i++) label: { 422 if (i > 0) 423 break 424 } 425 assert(i, 1) 426 } 427 428 function test_destructuring() 429 { 430 function * g () { return 0; }; 431 var [x] = g(); 432 assert(x, void 0); 433 } 434 435 function test_spread() 436 { 437 var x; 438 x = [1, 2, ...[3, 4]]; 439 assert(x.toString(), "1,2,3,4"); 440 441 x = [ ...[ , ] ]; 442 assert(Object.getOwnPropertyNames(x).toString(), "0,length"); 443 } 444 445 function test_function_length() 446 { 447 assert( ((a, b = 1, c) => {}).length, 1); 448 assert( (([a,b]) => {}).length, 1); 449 assert( (({a,b}) => {}).length, 1); 450 assert( ((c, [a,b] = 1, d) => {}).length, 1); 451 } 452 453 function test_argument_scope() 454 { 455 var f; 456 var c = "global"; 457 458 (function() { 459 "use strict"; 460 // XXX: node only throws in strict mode 461 f = function(a = eval("var arguments")) {}; 462 assert_throws(SyntaxError, f); 463 })(); 464 465 f = function(a = eval("1"), b = arguments[0]) { return b; }; 466 assert(f(12), 12); 467 468 f = function(a, b = arguments[0]) { return b; }; 469 assert(f(12), 12); 470 471 f = function(a, b = () => arguments) { return b; }; 472 assert(f(12)()[0], 12); 473 474 f = function(a = eval("1"), b = () => arguments) { return b; }; 475 assert(f(12)()[0], 12); 476 477 (function() { 478 "use strict"; 479 f = function(a = this) { return a; }; 480 assert(f.call(123), 123); 481 482 f = function f(a = f) { return a; }; 483 assert(f(), f); 484 485 f = function f(a = eval("f")) { return a; }; 486 assert(f(), f); 487 })(); 488 489 f = (a = eval("var c = 1"), probe = () => c) => { 490 var c = 2; 491 assert(c, 2); 492 assert(probe(), 1); 493 } 494 f(); 495 496 f = (a = eval("var arguments = 1"), probe = () => arguments) => { 497 var arguments = 2; 498 assert(arguments, 2); 499 assert(probe(), 1); 500 } 501 f(); 502 503 f = function f(a = eval("var c = 1"), b = c, probe = () => c) { 504 assert(b, 1); 505 assert(c, 1); 506 assert(probe(), 1) 507 } 508 f(); 509 510 assert(c, "global"); 511 f = function f(a, b = c, probe = () => c) { 512 eval("var c = 1"); 513 assert(c, 1); 514 assert(b, "global"); 515 assert(probe(), "global") 516 } 517 f(); 518 assert(c, "global"); 519 520 f = function f(a = eval("var c = 1"), probe = (d = eval("c")) => d) { 521 assert(probe(), 1) 522 } 523 f(); 524 } 525 526 function test_function_expr_name() 527 { 528 var f; 529 530 /* non strict mode test : assignment to the function name silently 531 fails */ 532 533 f = function myfunc() { 534 myfunc = 1; 535 return myfunc; 536 }; 537 assert(f(), f); 538 539 f = function myfunc() { 540 myfunc = 1; 541 (() => { 542 myfunc = 1; 543 })(); 544 return myfunc; 545 }; 546 assert(f(), f); 547 548 f = function myfunc() { 549 eval("myfunc = 1"); 550 return myfunc; 551 }; 552 assert(f(), f); 553 554 /* strict mode test : assignment to the function name raises a 555 TypeError exception */ 556 557 f = function myfunc() { 558 "use strict"; 559 myfunc = 1; 560 }; 561 assert_throws(TypeError, f); 562 563 f = function myfunc() { 564 "use strict"; 565 (() => { 566 myfunc = 1; 567 })(); 568 }; 569 assert_throws(TypeError, f); 570 571 f = function myfunc() { 572 "use strict"; 573 eval("myfunc = 1"); 574 }; 575 assert_throws(TypeError, f); 576 } 577 578 function test_parse_semicolon() 579 { 580 /* 'yield' or 'await' may not be considered as a token if the 581 previous ';' is missing */ 582 function *f() 583 { 584 function func() { 585 } 586 yield 1; 587 var h = x => x + 1 588 yield 2; 589 } 590 async function g() 591 { 592 function func() { 593 } 594 await 1; 595 var h = x => x + 1 596 await 2; 597 } 598 } 599 600 function test_parse_arrow_function() 601 { 602 assert(typeof eval("() => {}\n() => {}"), "function"); 603 assert(eval("() => {}\n+1"), 1); 604 assert(typeof eval("x => {}\n() => {}"), "function"); 605 assert(typeof eval("async () => {}\n() => {}"), "function"); 606 assert(typeof eval("async x => {}\n() => {}"), "function"); 607 } 608 609 /* optional chaining tests not present in test262 */ 610 function test_optional_chaining() 611 { 612 var a, z; 613 z = null; 614 a = { b: { c: 2 } }; 615 assert(delete z?.b.c, true); 616 assert(delete a?.b.c, true); 617 assert(JSON.stringify(a), '{"b":{}}', "optional chaining delete"); 618 619 a = { b: { c: 2 } }; 620 assert(delete z?.b["c"], true); 621 assert(delete a?.b["c"], true); 622 assert(JSON.stringify(a), '{"b":{}}'); 623 624 a = { 625 b() { return this._b; }, 626 _b: { c: 42 } 627 }; 628 629 assert((a?.b)().c, 42); 630 631 assert((a?.["b"])().c, 42); 632 } 633 634 function test_unicode_ident() 635 { 636 var õ = 3; 637 assert(typeof õ, "undefined"); 638 } 639 640 /* check global variable optimization */ 641 function test_global_var_opt() 642 { 643 var v2; 644 (1, eval)('var gvar1'); /* create configurable global variables */ 645 646 gvar1 = 1; 647 Object.defineProperty(globalThis, "gvar1", { writable: false }); 648 gvar1 = 2; 649 assert(gvar1, 1); 650 651 Object.defineProperty(globalThis, "gvar1", { get: function() { return "hello" }, 652 set: function(v) { v2 = v; } }); 653 assert(gvar1, "hello"); 654 gvar1 = 3; 655 assert(v2, 3); 656 657 Object.defineProperty(globalThis, "gvar1", { value: 4, writable: true, configurable: true }); 658 assert(gvar1, 4); 659 gvar1 = 6; 660 661 delete gvar1; 662 assert_throws(ReferenceError, function() { return gvar1 }); 663 gvar1 = 5; 664 assert(gvar1, 5); 665 } 666 667 function test_number_literals() 668 { 669 assert(0.1.a, undefined); 670 assert(0x1.a, undefined); 671 assert(0b1.a, undefined); 672 assert(01.a, undefined); 673 assert(0o1.a, undefined); 674 assert_throws(SyntaxError, () => eval('0.a')); 675 } 676 677 test_op1(); 678 test_cvt(); 679 test_eq(); 680 test_inc_dec(); 681 test_op2(); 682 test_constructor(); 683 test_delete(); 684 test_prototype(); 685 test_arguments(); 686 test_class(); 687 test_template(); 688 test_template_skip(); 689 test_object_literal(); 690 test_regexp_skip(); 691 test_labels(); 692 test_labels2(); 693 test_destructuring(); 694 test_spread(); 695 test_function_length(); 696 test_argument_scope(); 697 test_function_expr_name(); 698 test_parse_semicolon(); 699 test_optional_chaining(); 700 test_parse_arrow_function(); 701 test_unicode_ident(); 702 test_global_var_opt(); 703 test_number_literals();