• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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