1"use strict"; 2 3function assert(actual, expected, message) { 4 if (arguments.length == 1) 5 expected = true; 6 7 if (actual === expected) 8 return; 9 10 if (actual !== null && expected !== null 11 && typeof actual == 'object' && typeof expected == 'object' 12 && actual.toString() === expected.toString()) 13 return; 14 15 throw Error("assertion failed: got |" + actual + "|" + 16 ", expected |" + expected + "|" + 17 (message ? " (" + message + ")" : "")); 18} 19 20function assert_throws(expected_error, func) 21{ 22 var err = false; 23 try { 24 func(); 25 } catch(e) { 26 err = true; 27 if (!(e instanceof expected_error)) { 28 throw Error("unexpected exception type"); 29 } 30 } 31 if (!err) { 32 throw Error("expected exception"); 33 } 34} 35 36// load more elaborate version of assert if available 37try { __loadScript("test_assert.js"); } catch(e) {} 38 39/*----------------*/ 40 41function my_func(a, b) 42{ 43 return a + b; 44} 45 46function test_function() 47{ 48 function f(a, b) { 49 var i, tab = []; 50 tab.push(this); 51 for(i = 0; i < arguments.length; i++) 52 tab.push(arguments[i]); 53 return tab; 54 } 55 function constructor1(a) { 56 this.x = a; 57 } 58 59 var r, g; 60 61 r = my_func.call(null, 1, 2); 62 assert(r, 3, "call"); 63 64 r = my_func.apply(null, [1, 2]); 65 assert(r, 3, "apply"); 66 67 r = (function () { return 1; }).apply(null, undefined); 68 assert(r, 1); 69 70 assert_throws(TypeError, (function() { 71 Reflect.apply((function () { return 1; }), null, undefined); 72 })); 73 74 r = new Function("a", "b", "return a + b;"); 75 assert(r(2,3), 5, "function"); 76 77 g = f.bind(1, 2); 78 assert(g.length, 1); 79 assert(g.name, "bound f"); 80 assert(g(3), [1,2,3]); 81 82 g = constructor1.bind(null, 1); 83 r = new g(); 84 assert(r.x, 1); 85} 86 87function test() 88{ 89 var r, a, b, c, err; 90 91 r = Error("hello"); 92 assert(r.message, "hello", "Error"); 93 94 a = new Object(); 95 a.x = 1; 96 assert(a.x, 1, "Object"); 97 98 assert(Object.getPrototypeOf(a), Object.prototype, "getPrototypeOf"); 99 Object.defineProperty(a, "y", { value: 3, writable: true, configurable: true, enumerable: true }); 100 assert(a.y, 3, "defineProperty"); 101 102 Object.defineProperty(a, "z", { get: function () { return 4; }, set: function(val) { this.z_val = val; }, configurable: true, enumerable: true }); 103 assert(a.z, 4, "get"); 104 a.z = 5; 105 assert(a.z_val, 5, "set"); 106 107 a = { get z() { return 4; }, set z(val) { this.z_val = val; } }; 108 assert(a.z, 4, "get"); 109 a.z = 5; 110 assert(a.z_val, 5, "set"); 111 112 b = Object.create(a); 113 assert(Object.getPrototypeOf(b), a, "create"); 114 c = {u:2}; 115 /* XXX: refcount bug in 'b' instead of 'a' */ 116 Object.setPrototypeOf(a, c); 117 assert(Object.getPrototypeOf(a), c, "setPrototypeOf"); 118 119 a = {}; 120 assert(a.toString(), "[object Object]", "toString"); 121 122 a = {x:1}; 123 assert(Object.isExtensible(a), true, "extensible"); 124 Object.preventExtensions(a); 125 126 err = false; 127 try { 128 a.y = 2; 129 } catch(e) { 130 err = true; 131 } 132 assert(Object.isExtensible(a), false, "extensible"); 133 assert(typeof a.y, "undefined", "extensible"); 134 assert(err, true, "extensible"); 135} 136 137function test_enum() 138{ 139 var a, tab; 140 a = {x:1, 141 "18014398509481984": 1, 142 "9007199254740992": 1, 143 "9007199254740991": 1, 144 "4294967296": 1, 145 "4294967295": 1, 146 y:1, 147 "4294967294": 1, 148 "1": 2}; 149 tab = Object.keys(a); 150// console.log("tab=" + tab.toString()); 151 assert(tab, ["1","4294967294","x","18014398509481984","9007199254740992","9007199254740991","4294967296","4294967295","y"], "keys"); 152} 153 154function test_array() 155{ 156 var a, err; 157 158 a = [1, 2, 3]; 159 assert(a.length, 3, "array"); 160 assert(a[2], 3, "array1"); 161 162 a = new Array(10); 163 assert(a.length, 10, "array2"); 164 165 a = new Array(1, 2); 166 assert(a.length === 2 && a[0] === 1 && a[1] === 2, true, "array3"); 167 168 a = [1, 2, 3]; 169 a.length = 2; 170 assert(a.length === 2 && a[0] === 1 && a[1] === 2, true, "array4"); 171 172 a = []; 173 a[1] = 10; 174 a[4] = 3; 175 assert(a.length, 5); 176 177 a = [1,2]; 178 a.length = 5; 179 a[4] = 1; 180 a.length = 4; 181 assert(a[4] !== 1, true, "array5"); 182 183 a = [1,2]; 184 a.push(3,4); 185 assert(a.join(), "1,2,3,4", "join"); 186 187 a = [1,2,3,4,5]; 188 Object.defineProperty(a, "3", { configurable: false }); 189 err = false; 190 try { 191 a.length = 2; 192 } catch(e) { 193 err = true; 194 } 195 assert(err && a.toString() === "1,2,3,4"); 196} 197 198function test_string() 199{ 200 var a; 201 a = String("abc"); 202 assert(a.length, 3, "string"); 203 assert(a[1], "b", "string"); 204 assert(a.charCodeAt(1), 0x62, "string"); 205 assert(String.fromCharCode(65), "A", "string"); 206 assert(String.fromCharCode.apply(null, [65, 66, 67]), "ABC", "string"); 207 assert(a.charAt(1), "b"); 208 assert(a.charAt(-1), ""); 209 assert(a.charAt(3), ""); 210 211 a = "abcd"; 212 assert(a.substring(1, 3), "bc", "substring"); 213 a = String.fromCharCode(0x20ac); 214 assert(a.charCodeAt(0), 0x20ac, "unicode"); 215 assert(a, "€", "unicode"); 216 assert(a, "\u20ac", "unicode"); 217 assert(a, "\u{20ac}", "unicode"); 218 assert("a", "\x61", "unicode"); 219 220 a = "\u{10ffff}"; 221 assert(a.length, 2, "unicode"); 222 assert(a, "\u{dbff}\u{dfff}", "unicode"); 223 assert(a.codePointAt(0), 0x10ffff); 224 assert(String.fromCodePoint(0x10ffff), a); 225 226 assert("a".concat("b", "c"), "abc"); 227 228 assert("abcabc".indexOf("cab"), 2); 229 assert("abcabc".indexOf("cab2"), -1); 230 assert("abc".indexOf("c"), 2); 231 232 assert("aaa".indexOf("a"), 0); 233 assert("aaa".indexOf("a", NaN), 0); 234 assert("aaa".indexOf("a", -Infinity), 0); 235 assert("aaa".indexOf("a", -1), 0); 236 assert("aaa".indexOf("a", -0), 0); 237 assert("aaa".indexOf("a", 0), 0); 238 assert("aaa".indexOf("a", 1), 1); 239 assert("aaa".indexOf("a", 2), 2); 240 assert("aaa".indexOf("a", 3), -1); 241 assert("aaa".indexOf("a", 4), -1); 242 assert("aaa".indexOf("a", Infinity), -1); 243 244 assert("aaa".indexOf(""), 0); 245 assert("aaa".indexOf("", NaN), 0); 246 assert("aaa".indexOf("", -Infinity), 0); 247 assert("aaa".indexOf("", -1), 0); 248 assert("aaa".indexOf("", -0), 0); 249 assert("aaa".indexOf("", 0), 0); 250 assert("aaa".indexOf("", 1), 1); 251 assert("aaa".indexOf("", 2), 2); 252 assert("aaa".indexOf("", 3), 3); 253 assert("aaa".indexOf("", 4), 3); 254 assert("aaa".indexOf("", Infinity), 3); 255 256 assert("aaa".lastIndexOf("a"), 2); 257 assert("aaa".lastIndexOf("a", NaN), 2); 258 assert("aaa".lastIndexOf("a", -Infinity), 0); 259 assert("aaa".lastIndexOf("a", -1), 0); 260 assert("aaa".lastIndexOf("a", -0), 0); 261 assert("aaa".lastIndexOf("a", 0), 0); 262 assert("aaa".lastIndexOf("a", 1), 1); 263 assert("aaa".lastIndexOf("a", 2), 2); 264 assert("aaa".lastIndexOf("a", 3), 2); 265 assert("aaa".lastIndexOf("a", 4), 2); 266 assert("aaa".lastIndexOf("a", Infinity), 2); 267 268 assert("aaa".lastIndexOf(""), 3); 269 assert("aaa".lastIndexOf("", NaN), 3); 270 assert("aaa".lastIndexOf("", -Infinity), 0); 271 assert("aaa".lastIndexOf("", -1), 0); 272 assert("aaa".lastIndexOf("", -0), 0); 273 assert("aaa".lastIndexOf("", 0), 0); 274 assert("aaa".lastIndexOf("", 1), 1); 275 assert("aaa".lastIndexOf("", 2), 2); 276 assert("aaa".lastIndexOf("", 3), 3); 277 assert("aaa".lastIndexOf("", 4), 3); 278 assert("aaa".lastIndexOf("", Infinity), 3); 279 280 assert("a,b,c".split(","), ["a","b","c"]); 281 assert(",b,c".split(","), ["","b","c"]); 282 assert("a,b,".split(","), ["a","b",""]); 283 284 assert("aaaa".split(), [ "aaaa" ]); 285 assert("aaaa".split(undefined, 0), [ ]); 286 assert("aaaa".split(""), [ "a", "a", "a", "a" ]); 287 assert("aaaa".split("", 0), [ ]); 288 assert("aaaa".split("", 1), [ "a" ]); 289 assert("aaaa".split("", 2), [ "a", "a" ]); 290 assert("aaaa".split("a"), [ "", "", "", "", "" ]); 291 assert("aaaa".split("a", 2), [ "", "" ]); 292 assert("aaaa".split("aa"), [ "", "", "" ]); 293 assert("aaaa".split("aa", 0), [ ]); 294 assert("aaaa".split("aa", 1), [ "" ]); 295 assert("aaaa".split("aa", 2), [ "", "" ]); 296 assert("aaaa".split("aaa"), [ "", "a" ]); 297 assert("aaaa".split("aaaa"), [ "", "" ]); 298 assert("aaaa".split("aaaaa"), [ "aaaa" ]); 299 assert("aaaa".split("aaaaa", 0), [ ]); 300 assert("aaaa".split("aaaaa", 1), [ "aaaa" ]); 301 302 assert(eval('"\0"'), "\0"); 303 304 assert("abc".padStart(Infinity, ""), "abc"); 305} 306 307function test_math() 308{ 309 var a; 310 a = 1.4; 311 assert(Math.floor(a), 1); 312 assert(Math.ceil(a), 2); 313 assert(Math.imul(0x12345678, 123), -1088058456); 314 assert(Math.fround(0.1), 0.10000000149011612); 315 assert(Math.hypot() == 0); 316 assert(Math.hypot(-2) == 2); 317 assert(Math.hypot(3, 4) == 5); 318 assert(Math.abs(Math.hypot(3, 4, 5) - 7.0710678118654755) <= 1e-15); 319} 320 321function test_number() 322{ 323 assert(parseInt("123"), 123); 324 assert(parseInt(" 123r"), 123); 325 assert(parseInt("0x123"), 0x123); 326 assert(parseInt("0o123"), 0); 327 assert(+" 123 ", 123); 328 assert(+"0b111", 7); 329 assert(+"0o123", 83); 330 assert(parseFloat("0x1234"), 0); 331 assert(parseFloat("Infinity"), Infinity); 332 assert(parseFloat("-Infinity"), -Infinity); 333 assert(parseFloat("123.2"), 123.2); 334 assert(parseFloat("123.2e3"), 123200); 335 assert(Number.isNaN(Number("+"))); 336 assert(Number.isNaN(Number("-"))); 337 assert(Number.isNaN(Number("\x00a"))); 338 339 assert((25).toExponential(0), "3e+1"); 340 assert((-25).toExponential(0), "-3e+1"); 341 assert((2.5).toPrecision(1), "3"); 342 assert((-2.5).toPrecision(1), "-3"); 343 assert((1.125).toFixed(2), "1.13"); 344 assert((-1.125).toFixed(2), "-1.13"); 345} 346 347function test_eval2() 348{ 349 var g_call_count = 0; 350 /* force non strict mode for f1 and f2 */ 351 var f1 = new Function("eval", "eval(1, 2)"); 352 var f2 = new Function("eval", "eval(...[1, 2])"); 353 function g(a, b) { 354 assert(a, 1); 355 assert(b, 2); 356 g_call_count++; 357 } 358 f1(g); 359 f2(g); 360 assert(g_call_count, 2); 361} 362 363function test_eval() 364{ 365 function f(b) { 366 var x = 1; 367 return eval(b); 368 } 369 var r, a; 370 371 r = eval("1+1;"); 372 assert(r, 2, "eval"); 373 374 r = eval("var my_var=2; my_var;"); 375 assert(r, 2, "eval"); 376 assert(typeof my_var, "undefined"); 377 378 assert(eval("if (1) 2; else 3;"), 2); 379 assert(eval("if (0) 2; else 3;"), 3); 380 381 assert(f.call(1, "this"), 1); 382 383 a = 2; 384 assert(eval("a"), 2); 385 386 eval("a = 3"); 387 assert(a, 3); 388 389 assert(f("arguments.length", 1), 2); 390 assert(f("arguments[1]", 1), 1); 391 392 a = 4; 393 assert(f("a"), 4); 394 f("a=3"); 395 assert(a, 3); 396 397 test_eval2(); 398} 399 400function test_typed_array() 401{ 402 var buffer, a, i; 403 404 a = new Uint8Array(4); 405 assert(a.length, 4); 406 for(i = 0; i < a.length; i++) 407 a[i] = i; 408 assert(a.join(","), "0,1,2,3"); 409 a[0] = -1; 410 assert(a[0], 255); 411 412 a = new Int8Array(3); 413 a[0] = 255; 414 assert(a[0], -1); 415 416 a = new Int32Array(3); 417 a[0] = Math.pow(2, 32) - 1; 418 assert(a[0], -1); 419 assert(a.BYTES_PER_ELEMENT, 4); 420 421 a = new Uint8ClampedArray(4); 422 a[0] = -100; 423 a[1] = 1.5; 424 a[2] = 0.5; 425 a[3] = 1233.5; 426 assert(a.toString(), "0,2,0,255"); 427 428 buffer = new ArrayBuffer(16); 429 assert(buffer.byteLength, 16); 430 a = new Uint32Array(buffer, 12, 1); 431 assert(a.length, 1); 432 a[0] = -1; 433 434 a = new Uint16Array(buffer, 2); 435 a[0] = -1; 436 437 a = new Float32Array(buffer, 8, 1); 438 a[0] = 1; 439 440 a = new Uint8Array(buffer); 441 442 assert(a.toString(), "0,0,255,255,0,0,0,0,0,0,128,63,255,255,255,255"); 443 444 assert(a.buffer, buffer); 445 446 a = new Uint8Array([1, 2, 3, 4]); 447 assert(a.toString(), "1,2,3,4"); 448 a.set([10, 11], 2); 449 assert(a.toString(), "1,2,10,11"); 450} 451 452function test_json() 453{ 454 var a, s; 455 s = '{"x":1,"y":true,"z":null,"a":[1,2,3],"s":"str"}'; 456 a = JSON.parse(s); 457 assert(a.x, 1); 458 assert(a.y, true); 459 assert(a.z, null); 460 assert(JSON.stringify(a), s); 461 462 /* indentation test */ 463 assert(JSON.stringify([[{x:1,y:{},z:[]},2,3]],undefined,1), 464`[ 465 [ 466 { 467 "x": 1, 468 "y": {}, 469 "z": [] 470 }, 471 2, 472 3 473 ] 474]`); 475} 476 477function test_date() 478{ 479 var d = new Date(1506098258091), a, s; 480 assert(d.toISOString(), "2017-09-22T16:37:38.091Z"); 481 d.setUTCHours(18, 10, 11); 482 assert(d.toISOString(), "2017-09-22T18:10:11.091Z"); 483 a = Date.parse(d.toISOString()); 484 assert((new Date(a)).toISOString(), d.toISOString()); 485 s = new Date("2020-01-01T01:01:01.1Z").toISOString(); 486 assert(s == "2020-01-01T01:01:01.100Z"); 487 s = new Date("2020-01-01T01:01:01.12Z").toISOString(); 488 assert(s == "2020-01-01T01:01:01.120Z"); 489 s = new Date("2020-01-01T01:01:01.123Z").toISOString(); 490 assert(s == "2020-01-01T01:01:01.123Z"); 491 s = new Date("2020-01-01T01:01:01.1234Z").toISOString(); 492 assert(s == "2020-01-01T01:01:01.123Z"); 493 s = new Date("2020-01-01T01:01:01.12345Z").toISOString(); 494 assert(s == "2020-01-01T01:01:01.123Z"); 495 s = new Date("2020-01-01T01:01:01.1235Z").toISOString(); 496 assert(s == "2020-01-01T01:01:01.124Z"); 497 s = new Date("2020-01-01T01:01:01.9999Z").toISOString(); 498 assert(s == "2020-01-01T01:01:02.000Z"); 499} 500 501function test_regexp() 502{ 503 var a, str; 504 str = "abbbbbc"; 505 a = /(b+)c/.exec(str); 506 assert(a[0], "bbbbbc"); 507 assert(a[1], "bbbbb"); 508 assert(a.index, 1); 509 assert(a.input, str); 510 a = /(b+)c/.test(str); 511 assert(a, true); 512 assert(/\x61/.exec("a")[0], "a"); 513 assert(/\u0061/.exec("a")[0], "a"); 514 assert(/\ca/.exec("\x01")[0], "\x01"); 515 assert(/\\a/.exec("\\a")[0], "\\a"); 516 assert(/\c0/.exec("\\c0")[0], "\\c0"); 517 518 a = /(\.(?=com|org)|\/)/.exec("ah.com"); 519 assert(a.index === 2 && a[0] === "."); 520 521 a = /(\.(?!com|org)|\/)/.exec("ah.com"); 522 assert(a, null); 523 524 a = /(?=(a+))/.exec("baaabac"); 525 assert(a.index === 1 && a[0] === "" && a[1] === "aaa"); 526 527 a = /(z)((a+)?(b+)?(c))*/.exec("zaacbbbcac"); 528 assert(a, ["zaacbbbcac","z","ac","a",,"c"]); 529 530 a = eval("/\0a/"); 531 assert(a.toString(), "/\0a/"); 532 assert(a.exec("\0a")[0], "\0a"); 533 534 assert(/{1a}/.toString(), "/{1a}/"); 535 a = /a{1+/.exec("a{11"); 536 assert(a, ["a{11"] ); 537} 538 539function test_symbol() 540{ 541 var a, b, obj, c; 542 a = Symbol("abc"); 543 obj = {}; 544 obj[a] = 2; 545 assert(obj[a], 2); 546 assert(typeof obj["abc"], "undefined"); 547 assert(String(a), "Symbol(abc)"); 548 b = Symbol("abc"); 549 assert(a == a); 550 assert(a === a); 551 assert(a != b); 552 assert(a !== b); 553 554 b = Symbol.for("abc"); 555 c = Symbol.for("abc"); 556 assert(b === c); 557 assert(b !== a); 558 559 assert(Symbol.keyFor(b), "abc"); 560 assert(Symbol.keyFor(a), undefined); 561 562 a = Symbol("aaa"); 563 assert(a.valueOf(), a); 564 assert(a.toString(), "Symbol(aaa)"); 565 566 b = Object(a); 567 assert(b.valueOf(), a); 568 assert(b.toString(), "Symbol(aaa)"); 569} 570 571function test_map() 572{ 573 var a, i, n, tab, o, v; 574 n = 1000; 575 a = new Map(); 576 tab = []; 577 for(i = 0; i < n; i++) { 578 v = { }; 579 o = { id: i }; 580 tab[i] = [o, v]; 581 a.set(o, v); 582 } 583 584 assert(a.size, n); 585 for(i = 0; i < n; i++) { 586 assert(a.get(tab[i][0]), tab[i][1]); 587 } 588 589 i = 0; 590 a.forEach(function (v, o) { 591 assert(o, tab[i++][0]); 592 assert(a.has(o)); 593 assert(a.delete(o)); 594 assert(!a.has(o)); 595 }); 596 597 assert(a.size, 0); 598} 599 600function test_weak_map() 601{ 602 var a, i, n, tab, o, v, n2; 603 a = new WeakMap(); 604 n = 10; 605 tab = []; 606 for(i = 0; i < n; i++) { 607 v = { }; 608 o = { id: i }; 609 tab[i] = [o, v]; 610 a.set(o, v); 611 } 612 o = null; 613 614 n2 = n >> 1; 615 for(i = 0; i < n2; i++) { 616 a.delete(tab[i][0]); 617 } 618 for(i = n2; i < n; i++) { 619 tab[i][0] = null; /* should remove the object from the WeakMap too */ 620 } 621 /* the WeakMap should be empty here */ 622} 623 624function test_generator() 625{ 626 function *f() { 627 var ret; 628 yield 1; 629 ret = yield 2; 630 assert(ret, "next_arg"); 631 return 3; 632 } 633 function *f2() { 634 yield 1; 635 yield 2; 636 return "ret_val"; 637 } 638 function *f1() { 639 var ret = yield *f2(); 640 assert(ret, "ret_val"); 641 return 3; 642 } 643 var g, v; 644 g = f(); 645 v = g.next(); 646 assert(v.value === 1 && v.done === false); 647 v = g.next(); 648 assert(v.value === 2 && v.done === false); 649 v = g.next("next_arg"); 650 assert(v.value === 3 && v.done === true); 651 v = g.next(); 652 assert(v.value === undefined && v.done === true); 653 654 g = f1(); 655 v = g.next(); 656 assert(v.value === 1 && v.done === false); 657 v = g.next(); 658 assert(v.value === 2 && v.done === false); 659 v = g.next(); 660 assert(v.value === 3 && v.done === true); 661 v = g.next(); 662 assert(v.value === undefined && v.done === true); 663} 664 665test(); 666test_function(); 667test_enum(); 668test_array(); 669test_string(); 670test_math(); 671test_number(); 672test_eval(); 673test_typed_array(); 674test_json(); 675test_date(); 676test_regexp(); 677test_symbol(); 678test_map(); 679test_weak_map(); 680test_generator(); 681