test_language.js (12988B)
1 function assert(actual, expected, message) { 2 if (arguments.length == 1) 3 expected = true; 4 5 if (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_prototype() 252 { 253 var f = function f() { }; 254 assert(f.prototype.constructor, f, "prototype"); 255 256 var g = function g() { }; 257 /* QuickJS bug */ 258 Object.defineProperty(g, "prototype", { writable: false }); 259 assert(g.prototype.constructor, g, "prototype"); 260 } 261 262 function test_arguments() 263 { 264 function f2() { 265 assert(arguments.length, 2, "arguments"); 266 assert(arguments[0], 1, "arguments"); 267 assert(arguments[1], 3, "arguments"); 268 } 269 f2(1, 3); 270 } 271 272 function test_class() 273 { 274 var o; 275 class C { 276 constructor() { 277 this.x = 10; 278 } 279 f() { 280 return 1; 281 } 282 static F() { 283 return -1; 284 } 285 get y() { 286 return 12; 287 } 288 }; 289 class D extends C { 290 constructor() { 291 super(); 292 this.z = 20; 293 } 294 g() { 295 return 2; 296 } 297 static G() { 298 return -2; 299 } 300 h() { 301 return super.f(); 302 } 303 static H() { 304 return super["F"](); 305 } 306 } 307 308 assert(C.F() === -1); 309 assert(Object.getOwnPropertyDescriptor(C.prototype, "y").get.name === "get y"); 310 311 o = new C(); 312 assert(o.f() === 1); 313 assert(o.x === 10); 314 315 assert(D.F() === -1); 316 assert(D.G() === -2); 317 assert(D.H() === -1); 318 319 o = new D(); 320 assert(o.f() === 1); 321 assert(o.g() === 2); 322 assert(o.x === 10); 323 assert(o.z === 20); 324 assert(o.h() === 1); 325 326 /* test class name scope */ 327 var E1 = class E { static F() { return E; } }; 328 assert(E1 === E1.F()); 329 330 class S { 331 static x = 42; 332 static y = S.x; 333 static z = this.x; 334 } 335 assert(S.x === 42); 336 assert(S.y === 42); 337 assert(S.z === 42); 338 339 class P { 340 get = () => "123"; 341 static() { return 42; } 342 } 343 assert(new P().get() === "123"); 344 assert(new P().static() === 42); 345 }; 346 347 function test_template() 348 { 349 var a, b; 350 b = 123; 351 a = `abc${b}d`; 352 assert(a, "abc123d"); 353 354 a = String.raw `abc${b}d`; 355 assert(a, "abc123d"); 356 357 a = "aaa"; 358 b = "bbb"; 359 assert(`aaa${a, b}ccc`, "aaabbbccc"); 360 } 361 362 function test_template_skip() 363 { 364 var a = "Bar"; 365 var { b = `${a + `a${a}` }baz` } = {}; 366 assert(b, "BaraBarbaz"); 367 } 368 369 function test_object_literal() 370 { 371 var x = 0, get = 1, set = 2; async = 3; 372 a = { get: 2, set: 3, async: 4, get a(){ return this.get} }; 373 assert(JSON.stringify(a), '{"get":2,"set":3,"async":4,"a":2}'); 374 assert(a.a === 2); 375 376 a = { x, get, set, async }; 377 assert(JSON.stringify(a), '{"x":0,"get":1,"set":2,"async":3}'); 378 } 379 380 function test_regexp_skip() 381 { 382 var a, b; 383 [a, b = /abc\(/] = [1]; 384 assert(a === 1); 385 386 [a, b =/abc\(/] = [2]; 387 assert(a === 2); 388 } 389 390 function test_labels() 391 { 392 do x: { break x; } while(0); 393 if (1) 394 x: { break x; } 395 else 396 x: { break x; } 397 with ({}) x: { break x; }; 398 while (0) x: { break x; }; 399 } 400 401 function test_destructuring() 402 { 403 function * g () { return 0; }; 404 var [x] = g(); 405 assert(x, void 0); 406 } 407 408 function test_spread() 409 { 410 var x; 411 x = [1, 2, ...[3, 4]]; 412 assert(x.toString(), "1,2,3,4"); 413 414 x = [ ...[ , ] ]; 415 assert(Object.getOwnPropertyNames(x).toString(), "0,length"); 416 } 417 418 function test_function_length() 419 { 420 assert( ((a, b = 1, c) => {}).length, 1); 421 assert( (([a,b]) => {}).length, 1); 422 assert( (({a,b}) => {}).length, 1); 423 assert( ((c, [a,b] = 1, d) => {}).length, 1); 424 } 425 426 function test_argument_scope() 427 { 428 var f; 429 var c = "global"; 430 431 (function() { 432 "use strict"; 433 // XXX: node only throws in strict mode 434 f = function(a = eval("var arguments")) {}; 435 assert_throws(SyntaxError, f); 436 })(); 437 438 f = function(a = eval("1"), b = arguments[0]) { return b; }; 439 assert(f(12), 12); 440 441 f = function(a, b = arguments[0]) { return b; }; 442 assert(f(12), 12); 443 444 f = function(a, b = () => arguments) { return b; }; 445 assert(f(12)()[0], 12); 446 447 f = function(a = eval("1"), b = () => arguments) { return b; }; 448 assert(f(12)()[0], 12); 449 450 (function() { 451 "use strict"; 452 f = function(a = this) { return a; }; 453 assert(f.call(123), 123); 454 455 f = function f(a = f) { return a; }; 456 assert(f(), f); 457 458 f = function f(a = eval("f")) { return a; }; 459 assert(f(), f); 460 })(); 461 462 f = (a = eval("var c = 1"), probe = () => c) => { 463 var c = 2; 464 assert(c, 2); 465 assert(probe(), 1); 466 } 467 f(); 468 469 f = (a = eval("var arguments = 1"), probe = () => arguments) => { 470 var arguments = 2; 471 assert(arguments, 2); 472 assert(probe(), 1); 473 } 474 f(); 475 476 f = function f(a = eval("var c = 1"), b = c, probe = () => c) { 477 assert(b, 1); 478 assert(c, 1); 479 assert(probe(), 1) 480 } 481 f(); 482 483 assert(c, "global"); 484 f = function f(a, b = c, probe = () => c) { 485 eval("var c = 1"); 486 assert(c, 1); 487 assert(b, "global"); 488 assert(probe(), "global") 489 } 490 f(); 491 assert(c, "global"); 492 493 f = function f(a = eval("var c = 1"), probe = (d = eval("c")) => d) { 494 assert(probe(), 1) 495 } 496 f(); 497 } 498 499 function test_function_expr_name() 500 { 501 var f; 502 503 /* non strict mode test : assignment to the function name silently 504 fails */ 505 506 f = function myfunc() { 507 myfunc = 1; 508 return myfunc; 509 }; 510 assert(f(), f); 511 512 f = function myfunc() { 513 myfunc = 1; 514 (() => { 515 myfunc = 1; 516 })(); 517 return myfunc; 518 }; 519 assert(f(), f); 520 521 f = function myfunc() { 522 eval("myfunc = 1"); 523 return myfunc; 524 }; 525 assert(f(), f); 526 527 /* strict mode test : assignment to the function name raises a 528 TypeError exception */ 529 530 f = function myfunc() { 531 "use strict"; 532 myfunc = 1; 533 }; 534 assert_throws(TypeError, f); 535 536 f = function myfunc() { 537 "use strict"; 538 (() => { 539 myfunc = 1; 540 })(); 541 }; 542 assert_throws(TypeError, f); 543 544 f = function myfunc() { 545 "use strict"; 546 eval("myfunc = 1"); 547 }; 548 assert_throws(TypeError, f); 549 } 550 551 function test_parse_semicolon() 552 { 553 /* 'yield' or 'await' may not be considered as a token if the 554 previous ';' is missing */ 555 function *f() 556 { 557 function func() { 558 } 559 yield 1; 560 var h = x => x + 1 561 yield 2; 562 } 563 async function g() 564 { 565 function func() { 566 } 567 await 1; 568 var h = x => x + 1 569 await 2; 570 } 571 } 572 573 function test_parse_arrow_function() 574 { 575 assert(typeof eval("() => {}\n() => {}"), "function"); 576 assert(eval("() => {}\n+1"), 1); 577 assert(typeof eval("x => {}\n() => {}"), "function"); 578 assert(typeof eval("async () => {}\n() => {}"), "function"); 579 assert(typeof eval("async x => {}\n() => {}"), "function"); 580 } 581 582 /* optional chaining tests not present in test262 */ 583 function test_optional_chaining() 584 { 585 var a, z; 586 z = null; 587 a = { b: { c: 2 } }; 588 assert(delete z?.b.c, true); 589 assert(delete a?.b.c, true); 590 assert(JSON.stringify(a), '{"b":{}}', "optional chaining delete"); 591 592 a = { b: { c: 2 } }; 593 assert(delete z?.b["c"], true); 594 assert(delete a?.b["c"], true); 595 assert(JSON.stringify(a), '{"b":{}}'); 596 597 a = { 598 b() { return this._b; }, 599 _b: { c: 42 } 600 }; 601 602 assert((a?.b)().c, 42); 603 604 assert((a?.["b"])().c, 42); 605 } 606 607 test_op1(); 608 test_cvt(); 609 test_eq(); 610 test_inc_dec(); 611 test_op2(); 612 test_delete(); 613 test_prototype(); 614 test_arguments(); 615 test_class(); 616 test_template(); 617 test_template_skip(); 618 test_object_literal(); 619 test_regexp_skip(); 620 test_labels(); 621 test_destructuring(); 622 test_spread(); 623 test_function_length(); 624 test_argument_scope(); 625 test_function_expr_name(); 626 test_parse_semicolon(); 627 test_optional_chaining(); 628 test_parse_arrow_function();