quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

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();