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