| /* |
| * Copyright (C) Igor Sysoev |
| * Copyright (C) NGINX, Inc. |
| */ |
| |
| |
| #include <njs_main.h> |
| |
| #include "njs_externals_test.h" |
| |
| |
| #define NJS_HAVE_LARGE_STACK (!NJS_HAVE_ADDRESS_SANITIZER && !NJS_HAVE_MEMORY_SANITIZER) |
| |
| #ifdef NJS_HAVE_LITTLE_ENDIAN |
| #define njs_evar(little, big) little |
| #else |
| #define njs_evar(little, big) big |
| #endif |
| |
| |
| #define njs_declare_sparse_array(nm, sz) \ |
| "var " nm " = Array(" njs_stringify(sz) "); " \ |
| "Object.defineProperty(" nm ", '0'," \ |
| "{writable:true, enumerable:false, configurable:true});" \ |
| "delete " nm "[0];" |
| |
| |
| #define njs_buffer_byte_map(func, sign, divisor) \ |
| "var buf = Buffer.alloc(6);" \ |
| "[1,2,3,4,5,6].map(byte => {" \ |
| " buf." func "(" sign "(2 ** (byte * 7)) / " \ |
| njs_stringify(divisor) ", 0, byte);" \ |
| " return njs.dump(buf);" \ |
| "})" |
| |
| |
| typedef struct { |
| njs_str_t script; |
| njs_str_t ret; |
| } njs_unit_test_t; |
| |
| |
| static njs_unit_test_t njs_test[] = |
| { |
| { njs_str("@"), |
| njs_str("SyntaxError: Unexpected token \"@\" in 1") }, |
| |
| { njs_str("}"), |
| njs_str("SyntaxError: Unexpected token \"}\" in 1") }, |
| |
| { njs_str("1}"), |
| njs_str("SyntaxError: Unexpected token \"}\" in 1") }, |
| |
| { njs_str("/***/1/*\n**/"), |
| njs_str("1") }, |
| |
| { njs_str("/***/1// "), |
| njs_str("1") }, |
| |
| { njs_str(">"), |
| njs_str("SyntaxError: Unexpected token \">\" in 1") }, |
| |
| { njs_str(">>"), |
| njs_str("SyntaxError: Unexpected token \">>\" in 1") }, |
| |
| { njs_str(">>>"), |
| njs_str("SyntaxError: Unexpected token \">>>\" in 1") }, |
| |
| { njs_str("=="), |
| njs_str("SyntaxError: Unexpected token \"==\" in 1") }, |
| |
| { njs_str("?"), |
| njs_str("SyntaxError: Unexpected token \"?\" in 1") }, |
| |
| /* Variable declarations. */ |
| |
| { njs_str("var x"), |
| njs_str("undefined") }, |
| |
| { njs_str("var x;"), |
| njs_str("undefined") }, |
| |
| { njs_str("var x;;"), |
| njs_str("undefined") }, |
| |
| { njs_str("var x = 0"), |
| njs_str("undefined") }, |
| |
| { njs_str("var x = 0;"), |
| njs_str("undefined") }, |
| |
| { njs_str("var x = 0;;"), |
| njs_str("undefined") }, |
| |
| { njs_str("var; a"), |
| njs_str("SyntaxError: Unexpected token \";\" in 1") }, |
| |
| { njs_str("var + a"), |
| njs_str("SyntaxError: Unexpected token \"+\" in 1") }, |
| |
| { njs_str("//\r\n; var + a"), |
| njs_str("SyntaxError: Unexpected token \"+\" in 2") }, |
| |
| { njs_str("/*\n*/; var + a"), |
| njs_str("SyntaxError: Unexpected token \"+\" in 2") }, |
| |
| { njs_str("var \n a \n = 1; a"), |
| njs_str("1") }, |
| |
| { njs_str("var \n a, \n b; b"), |
| njs_str("undefined") }, |
| |
| { njs_str("var from = 2; from + 2"), |
| njs_str("4") }, |
| |
| { njs_str("var a / ="), |
| njs_str("SyntaxError: Unexpected token \"/\" in 1") }, |
| |
| { njs_str("var a = 1; var b; a"), |
| njs_str("1") }, |
| |
| { njs_str("a = 1;for(;a;a--)var a; a"), |
| njs_str("0") }, |
| |
| { njs_str("if(1)if(0){0?0:0}else\nvar a\nelse\nvar b"), |
| njs_str("undefined") }, |
| |
| { njs_str("var a = 1; var a; a"), |
| njs_str("1") }, |
| |
| { njs_str("(function (x) {if (x) { var a = 3; return a} else { var a = 4; return a}})(1)"), |
| njs_str("3") }, |
| |
| { njs_str("(function (x) {if (x) { var a = 3; return a} else { var a = 4; return a}})(0)"), |
| njs_str("4") }, |
| |
| { njs_str("function f(){return 2}; var f; f()"), |
| njs_str("2") }, |
| |
| { njs_str("function f(){return 2}; var f = 1; f()"), |
| njs_str("TypeError: number is not a function") }, |
| |
| { njs_str("function f(){return 1}; function f(){return 2}; f()"), |
| njs_str("2") }, |
| |
| { njs_str("var f = 1; function f() {}; f"), |
| njs_str("1") }, |
| |
| { njs_str("var f = 1; function f() {}; f"), |
| njs_str("1") }, |
| |
| { njs_str("function f(a) {return function (x) {return a(x)}} f(1)(0)"), |
| njs_str("TypeError: number is not a function") }, |
| |
| { njs_str("var x = 0;" |
| "" |
| "function f1() {" |
| " function f2() {" |
| " return x;" |
| " };" |
| "" |
| " return f2();" |
| "" |
| " var x = 1;" |
| "}" |
| "" |
| "f1() === undefined"), |
| njs_str("true") }, |
| |
| { njs_str("var fn = function fn() {return fn.test}; fn.test = 'test'; fn()"), |
| njs_str("test") }, |
| |
| { njs_str("var body;" |
| "var n = 'outside';" |
| "var before = function() {return n};" |
| "" |
| "var func = function n() {" |
| " var n;" |
| " body = function() {return n};" |
| "};" |
| "" |
| "func();" |
| "" |
| "[before(), body()]"), |
| njs_str("outside,") }, |
| |
| { njs_str("var func = function x(x) {return x}; func()"), |
| njs_str("undefined") }, |
| |
| #if 0 /* TODO */ |
| { njs_str("var a; Object.getOwnPropertyDescriptor(this, 'a').value"), |
| njs_str("undefined") }, |
| #endif |
| |
| { njs_str("f() = 1"), |
| njs_str("ReferenceError: Invalid left-hand side in assignment in 1") }, |
| |
| { njs_str("f.a() = 1"), |
| njs_str("ReferenceError: Invalid left-hand side in assignment in 1") }, |
| |
| { njs_str("++f()"), |
| njs_str("ReferenceError: Invalid left-hand side in prefix operation in 1") }, |
| |
| { njs_str("f()++"), |
| njs_str("ReferenceError: Invalid left-hand side in postfix operation in 1") }, |
| |
| /* Numbers. */ |
| |
| { njs_str("0"), |
| njs_str("0") }, |
| |
| { njs_str("-0"), |
| njs_str("-0") }, |
| |
| { njs_str(".0"), |
| njs_str("0") }, |
| |
| { njs_str("0.1"), |
| njs_str("0.1") }, |
| |
| { njs_str(".9"), |
| njs_str("0.9") }, |
| |
| { njs_str("-.0_1"), |
| njs_str("-0.01") }, |
| |
| { njs_str("0.000_001"), |
| njs_str("0.000001") }, |
| |
| { njs_str("0.00000_123456"), |
| njs_str("0.00000123456") }, |
| |
| { njs_str("0.0000001"), |
| njs_str("1e-7") }, |
| |
| { njs_str("1.1000000"), |
| njs_str("1.1") }, |
| |
| { njs_str("1_0"), |
| njs_str("10") }, |
| |
| { njs_str("99_999_999_999_999_999_999"), |
| njs_str("100000000000000000000") }, |
| |
| { njs_str("9999999999999999999_9.1_1_1"), |
| njs_str("100000000000000000000") }, |
| |
| { njs_str("999999999999999999999"), |
| njs_str("1e+21") }, |
| |
| { njs_str("9223372036854775808"), |
| njs_str("9223372036854776000") }, |
| |
| { njs_str("18446744073709551616"), |
| njs_str("18446744073709552000") }, |
| |
| { njs_str("1.79769313_48623157E+3_0_8"), |
| njs_str("1.7976931348623157e+308") }, |
| |
| { njs_str("+1"), |
| njs_str("1") }, |
| |
| { njs_str("+1\n"), |
| njs_str("1") }, |
| |
| { njs_str("."), |
| njs_str("SyntaxError: Unexpected token \".\" in 1") }, |
| |
| { njs_str("0_1"), |
| njs_str("SyntaxError: Unexpected token \"0_\" in 1") }, |
| |
| { njs_str("1_"), |
| njs_str("SyntaxError: Unexpected token \"_\" in 1") }, |
| |
| { njs_str("1__0"), |
| njs_str("SyntaxError: Unexpected token \"__0\" in 1") }, |
| |
| { njs_str("._1"), |
| njs_str("SyntaxError: Unexpected token \".\" in 1") }, |
| |
| { njs_str(".1_"), |
| njs_str("SyntaxError: Unexpected token \"_\" in 1") }, |
| |
| { njs_str("1_.1"), |
| njs_str("SyntaxError: Unexpected token \"_\" in 1") }, |
| |
| { njs_str(".0__1"), |
| njs_str("SyntaxError: Unexpected token \"__1\" in 1") }, |
| |
| { njs_str("1e_1"), |
| njs_str("SyntaxError: Unexpected token \"_1\" in 1") }, |
| |
| { njs_str("1e-_1"), |
| njs_str("SyntaxError: Unexpected token \"_1\" in 1") }, |
| |
| { njs_str("1E1__0"), |
| njs_str("SyntaxError: Unexpected token \"__0\" in 1") }, |
| |
| { njs_str("1_e1"), |
| njs_str("SyntaxError: Unexpected token \"_e1\" in 1") }, |
| |
| { njs_str("1e1_"), |
| njs_str("SyntaxError: Unexpected token \"_\" in 1") }, |
| |
| { njs_str("-_1"), |
| njs_str("ReferenceError: \"_1\" is not defined") }, |
| |
| { njs_str("_1"), |
| njs_str("ReferenceError: \"_1\" is not defined") }, |
| |
| /* Octal Numbers. */ |
| |
| { njs_str("0o0"), |
| njs_str("0") }, |
| |
| { njs_str("0O10"), |
| njs_str("8") }, |
| |
| { njs_str("0o011"), |
| njs_str("9") }, |
| |
| { njs_str("-0O7_7_7"), |
| njs_str("-511") }, |
| |
| { njs_str("0o"), |
| njs_str("SyntaxError: Unexpected token \"0o\" in 1") }, |
| |
| { njs_str("0O778"), |
| njs_str("SyntaxError: Unexpected token \"0O778\" in 1") }, |
| |
| { njs_str("0O_7"), |
| njs_str("SyntaxError: Unexpected token \"_7\" in 1") }, |
| |
| { njs_str("0o7_"), |
| njs_str("SyntaxError: Unexpected token \"_\" in 1") }, |
| |
| { njs_str("0o7__7"), |
| njs_str("SyntaxError: Unexpected token \"__7\" in 1") }, |
| |
| /* Legacy Octal Numbers are deprecated. */ |
| |
| { njs_str("00"), |
| njs_str("SyntaxError: Unexpected token \"00\" in 1") }, |
| |
| { njs_str("08"), |
| njs_str("SyntaxError: Unexpected token \"08\" in 1") }, |
| |
| { njs_str("09"), |
| njs_str("SyntaxError: Unexpected token \"09\" in 1") }, |
| |
| { njs_str("0011"), |
| njs_str("SyntaxError: Unexpected token \"00\" in 1") }, |
| |
| { njs_str("0_"), |
| njs_str("SyntaxError: Unexpected token \"0_\" in 1") }, |
| |
| { njs_str("0_1"), |
| njs_str("SyntaxError: Unexpected token \"0_\" in 1") }, |
| |
| { njs_str("00_1"), |
| njs_str("SyntaxError: Unexpected token \"00\" in 1") }, |
| |
| /* Binary Numbers. */ |
| |
| { njs_str("0b0"), |
| njs_str("0") }, |
| |
| { njs_str("0B10"), |
| njs_str("2") }, |
| |
| { njs_str("0b0_1_0_1"), |
| njs_str("5") }, |
| |
| { njs_str("-0B1111_1111"), |
| njs_str("-255") }, |
| |
| { njs_str("0b"), |
| njs_str("SyntaxError: Unexpected token \"0b\" in 1") }, |
| |
| { njs_str("0B12"), |
| njs_str("SyntaxError: Unexpected token \"0B12\" in 1") }, |
| |
| { njs_str("0b_11"), |
| njs_str("SyntaxError: Unexpected token \"_11\" in 1") }, |
| |
| { njs_str("0B1__1"), |
| njs_str("SyntaxError: Unexpected token \"__1\" in 1") }, |
| |
| { njs_str("0b11_"), |
| njs_str("SyntaxError: Unexpected token \"_\" in 1") }, |
| |
| /* Hex Numbers. */ |
| |
| { njs_str("0x0"), |
| njs_str("0") }, |
| |
| { njs_str("-0x1"), |
| njs_str("-1") }, |
| |
| { njs_str("0xffFF"), |
| njs_str("65535") }, |
| |
| { njs_str("0X00_00_BE_EF"), |
| njs_str("48879") }, |
| |
| { njs_str("0x"), |
| njs_str("SyntaxError: Unexpected token \"0x\" in 1") }, |
| |
| { njs_str("0xffff."), |
| njs_str("SyntaxError: Unexpected end of input in 1") }, |
| |
| { njs_str("0x12g"), |
| njs_str("SyntaxError: Unexpected token \"g\" in 1") }, |
| |
| { njs_str("0X_ff"), |
| njs_str("SyntaxError: Unexpected token \"_ff\" in 1") }, |
| |
| { njs_str("0xff_"), |
| njs_str("SyntaxError: Unexpected token \"_\" in 1") }, |
| |
| { njs_str("0Xf__f"), |
| njs_str("SyntaxError: Unexpected token \"__f\" in 1") }, |
| |
| { njs_str(""), |
| njs_str("undefined") }, |
| |
| { njs_str("\n"), |
| njs_str("undefined") }, |
| |
| { njs_str(";"), |
| njs_str("undefined") }, |
| |
| { njs_str("\n +1"), |
| njs_str("1") }, |
| |
| /* Scientific notation. */ |
| |
| { njs_str("0e0"), |
| njs_str("0") }, |
| |
| { njs_str("0.0e0"), |
| njs_str("0") }, |
| |
| { njs_str("1e0"), |
| njs_str("1") }, |
| |
| { njs_str("1e1"), |
| njs_str("10") }, |
| |
| { njs_str("1.e01"), |
| njs_str("10") }, |
| |
| { njs_str("5.7e1"), |
| njs_str("57") }, |
| |
| { njs_str("5.7e-1"), |
| njs_str("0.57") }, |
| |
| { njs_str("-5.7e-1"), |
| njs_str("-0.57") }, |
| |
| { njs_str("1.1e-01"), |
| njs_str("0.11") }, |
| |
| { njs_str("5.7e-2"), |
| njs_str("0.057") }, |
| |
| { njs_str("1.1e+01"), |
| njs_str("11") }, |
| |
| { njs_str("-.01e-01"), |
| njs_str("-0.001") }, |
| |
| { njs_str("1e9"), |
| njs_str("1000000000") }, |
| |
| { njs_str("1.0e308"), |
| njs_str("1e+308") }, |
| |
| { njs_str("0e309"), |
| njs_str("0") }, |
| |
| { njs_str("0e-309"), |
| njs_str("0") }, |
| |
| { njs_str("1e309"), |
| njs_str("Infinity") }, |
| |
| { njs_str("-1e309"), |
| njs_str("-Infinity") }, |
| |
| { njs_str("1e"), |
| njs_str("SyntaxError: Unexpected token \"e\" in 1") }, |
| |
| { njs_str("1.e"), |
| njs_str("SyntaxError: Unexpected token \"e\" in 1") }, |
| |
| { njs_str("1e+"), |
| njs_str("SyntaxError: Unexpected token \"e\" in 1") }, |
| |
| { njs_str("1.e-"), |
| njs_str("SyntaxError: Unexpected token \"e\" in 1") }, |
| |
| { njs_str("1eZ"), |
| njs_str("SyntaxError: Unexpected token \"eZ\" in 1") }, |
| |
| { njs_str(".e1"), |
| njs_str("SyntaxError: Unexpected token \".\" in 1") }, |
| |
| { njs_str("Number.prototype.X = function(){return 123;};" |
| "(1).X()"), |
| njs_str("123") }, |
| |
| /* Indices. */ |
| |
| { njs_str("var a = []; a[-1] = 2; a[-1] == a['-1']"), |
| njs_str("true") }, |
| |
| { njs_str("var a = []; a[Infinity] = 2; a[Infinity] == a['Infinity']"), |
| njs_str("true") }, |
| |
| { njs_str("var a = []; a[NaN] = 2; a[NaN] == a['NaN']"), |
| njs_str("true") }, |
| |
| #define NJS_NOT_CANONICAL_INDICES "['+0', '-0', '1.', '0.', '0.0', '4294967295', " \ |
| " '4294967296', '-1', '1.1', '9223372036854775808']" |
| |
| { njs_str("var a = [1,2]; " |
| NJS_NOT_CANONICAL_INDICES |
| ".every(v=>(a[v] === undefined))"), |
| njs_str("true") }, |
| |
| { njs_str("var a = [1,2]; " |
| NJS_NOT_CANONICAL_INDICES |
| ".every(v=>{a[v] = 'a'; return a[v] === 'a'})"), |
| njs_str("true") }, |
| |
| /* Number.toString(radix) method. */ |
| |
| { njs_str("0..toString(2)"), |
| njs_str("0") }, |
| |
| { njs_str("(1234.567).toString(3)"), |
| njs_str("1200201.120022100021001021021002202") }, |
| |
| { njs_str("(1234.567).toString(5)"), |
| njs_str("14414.240414141414141414") }, |
| |
| { njs_str("(1234.567).toString(17)"), |
| njs_str("44a.9aeb6faa0da") }, |
| |
| { njs_str("(1234.567).toString(36)"), |
| njs_str("ya.kety9sifl") }, |
| |
| { njs_str("Number(-1.1).toString(36)"), |
| njs_str("-1.3llllllllm") }, |
| |
| { njs_str("Math.pow(-2, 1023).toString(2).length"), |
| njs_str("1025") }, |
| |
| { njs_str("8.0625.toString(2)"), |
| njs_str("1000.0001") }, |
| |
| { njs_str("(1/3).toString(2)"), |
| njs_str("0.010101010101010101010101010101010101010101010101010101") }, |
| |
| { njs_str("9999..toString(3)"), |
| njs_str("111201100") }, |
| |
| { njs_str("-9999..toString(3)"), |
| njs_str("-111201100") }, |
| |
| { njs_str("81985529216486895..toString(16)"), |
| njs_str("123456789abcdf0") }, |
| |
| { njs_str("0xffff.toString(16)"), |
| njs_str("ffff") }, |
| |
| { njs_str("30520..toString(36)"), |
| njs_str("njs") }, |
| |
| { njs_str("Infinity.toString()"), |
| njs_str("Infinity") }, |
| |
| { njs_str("Infinity.toString(2)"), |
| njs_str("Infinity") }, |
| |
| { njs_str("Infinity.toString(10)"), |
| njs_str("Infinity") }, |
| |
| { njs_str("Infinity.toString(NaN)"), |
| njs_str("RangeError") }, |
| |
| { njs_str("Infinity.toString({})"), |
| njs_str("RangeError") }, |
| |
| { njs_str("Infinity.toString(Infinity)"), |
| njs_str("RangeError") }, |
| |
| { njs_str("NaN.toString()"), |
| njs_str("NaN") }, |
| |
| { njs_str("NaN.toString(2)"), |
| njs_str("NaN") }, |
| |
| { njs_str("NaN.toString(10)"), |
| njs_str("NaN") }, |
| |
| { njs_str("NaN.toString(Infinity)"), |
| njs_str("RangeError") }, |
| |
| { njs_str("NaN.toString({})"), |
| njs_str("RangeError") }, |
| |
| { njs_str("NaN.toString(NaN)"), |
| njs_str("RangeError") }, |
| |
| { njs_str("1.2312313132.toString(14)"), |
| njs_str("1.3346da6d5d455c") }, |
| |
| { njs_str("7.799999999999999.toString(14)"), |
| njs_str("7.b2b2b2b2b2b2a5") }, |
| |
| #ifndef NJS_SUNC |
| { njs_str("1e20.toString(14)"), |
| njs_str("33cb3bb449c2a92000") }, |
| |
| { njs_str("1.7976931348623157E+308.toString(36) == ('1a1e4vngaiqo' + '0'.repeat(187))"), |
| njs_str("true") }, |
| |
| /* Largest positive double (prev_double(INFINITY)). */ |
| { njs_str("1.7976931348623157E+308.toString(2) == ('1'.repeat(53) + '0'.repeat(971))"), |
| njs_str("true") }, |
| |
| { njs_str("Array(5).fill().map((n, i) => i + 10).map((v)=>(1.2312313132).toString(v))"), |
| njs_str("1.2312313132,1.25a850416057383,1.293699002749414,1.3010274cab0288,1.3346da6d5d455c") }, |
| |
| { njs_str("Array(5).fill().map((n, i) => 36 - i).map((v)=>(1e23).toString(v))"), |
| njs_str("ga894a06abs0000,o5hlsorok4y0000,128fpsprqld20000,1m1s0ajv6cmo0000,2kmg5hv19br00000") }, |
| #endif |
| |
| /* Number.prototype.toFixed(frac) method. */ |
| |
| { njs_str("(900.1).toFixed(1)"), |
| njs_str("900.1") }, |
| |
| { njs_str("(0).toFixed(0)"), |
| njs_str("0") }, |
| |
| { njs_str("(0).toFixed(3)"), |
| njs_str("0.000") }, |
| |
| { njs_str("(7).toFixed()"), |
| njs_str("7") }, |
| |
| { njs_str("(7).toFixed(0)"), |
| njs_str("7") }, |
| |
| { njs_str("(7).toFixed(2)"), |
| njs_str("7.00") }, |
| |
| { njs_str("(-900.1).toFixed(3.3)"), |
| njs_str("-900.100") }, |
| |
| { njs_str("(900.123).toFixed(5)"), |
| njs_str("900.12300") }, |
| |
| { njs_str("(1/3).toFixed(5)"), |
| njs_str("0.33333") }, |
| |
| { njs_str("(new Number(1/3)).toFixed(5)"), |
| njs_str("0.33333") }, |
| |
| { njs_str("(new Number(1/3)).toFixed(5)"), |
| njs_str("0.33333") }, |
| |
| { njs_str("(1/3).toFixed({toString(){return '5'}})"), |
| njs_str("0.33333") }, |
| |
| { njs_str("(1/3).toFixed(100)"), |
| njs_str("0.3333333333333333148296162562473909929394721984863281250000000000000000000000000000000000000000000000") }, |
| |
| { njs_str("(1.23e+20).toFixed(2)"), |
| njs_str("123000000000000000000.00") }, |
| |
| { njs_str("(1.23e-10).toFixed(2)"), |
| njs_str("0.00") }, |
| |
| { njs_str("(1.23e-10).toFixed(15)"), |
| njs_str("0.000000000123000") }, |
| |
| { njs_str("(1.23e-10).toFixed(100)"), |
| njs_str("0.0000000001229999999999999888422768137255427361997917046210204716771841049194335937500000000000000000") }, |
| |
| { njs_str("NaN.toFixed(1)"), |
| njs_str("NaN") }, |
| |
| #if 0 /* FIXME: bignum support is requred to support frac >= 20 */ |
| { njs_str("(2 ** -100).toFixed(100)"), |
| njs_str("0.0000000000000000000000000000007888609052210118054117285652827862296732064351090230047702789306640625") }, |
| #endif |
| |
| /* Number.prototype.toPrecision(prec) method. */ |
| |
| { njs_str("Array(4).fill().map((n, i) => i+1).map((v)=>(1/7).toPrecision(v))"), |
| njs_str("0.1,0.14,0.143,0.1429") }, |
| |
| { njs_str("Array(4).fill().map((n, i) => i+1).map((v)=>(0).toPrecision(v))"), |
| njs_str("0,0.0,0.00,0.000") }, |
| |
| { njs_str("Array(4).fill().map((n, i) => i+1).map((v)=>(1/2).toPrecision(v))"), |
| njs_str("0.5,0.50,0.500,0.5000") }, |
| |
| { njs_str("Array(6).fill().map((n, i) => i+2).map((v)=>(1/v).toPrecision(5))"), |
| njs_str("0.50000,0.33333,0.25000,0.20000,0.16667,0.14286") }, |
| |
| { njs_str("Array(6).fill().map((n, i) => i+2).map((v)=>(1/(v*100)).toPrecision(5))"), |
| njs_str("0.0050000,0.0033333,0.0025000,0.0020000,0.0016667,0.0014286") }, |
| |
| { njs_str("Array(6).fill().map((n, i) => i+1).map((v)=>(10*v/7).toPrecision(5))"), |
| njs_str("1.4286,2.8571,4.2857,5.7143,7.1429,8.5714") }, |
| |
| { njs_str("Array(6).fill().map((n, i) => i+1).map((v)=>(v/3).toPrecision(5))"), |
| njs_str("0.33333,0.66667,1.0000,1.3333,1.6667,2.0000") }, |
| |
| { njs_str("Array(6).fill().map((n, i) => i+1).map((v)=>((Math.pow(-1,v))*(2*v)/3).toPrecision(5))"), |
| njs_str("-0.66667,1.3333,-2.0000,2.6667,-3.3333,4.0000") }, |
| |
| { njs_str("Array(12).fill().map((n, i) => i-3).map((v)=>(2**v).toPrecision(6))"), |
| njs_str("0.125000,0.250000,0.500000,1.00000,2.00000,4.00000,8.00000,16.0000,32.0000,64.0000,128.000,256.000") }, |
| |
| { njs_str("Array(5).fill().map((n, i) => i+16).map((v)=>(4.1).toPrecision(v))"), |
| njs_str("4.100000000000000,4.0999999999999996,4.09999999999999964,4.099999999999999644,4.0999999999999996447") }, |
| |
| { njs_str("Array(3).fill().map((n, i) => i + 19).map((v)=>(2**(-v)).toPrecision(20))"), |
| njs_str("0.0000019073486328125000000,9.5367431640625000000e-7,4.7683715820312500000e-7") }, |
| |
| { njs_str("Array(3).fill().map((n, i) => i + 32).map((v)=>(2**(v)+0.1).toPrecision(10))"), |
| njs_str("4294967296,8589934592,1.717986918e+10") }, |
| |
| #if 0 /* FIXME: bignum support is requred to support prec >= 20 */ |
| { njs_str("(1/7).toPrecision(100)"), |
| njs_str("0.1428571428571428492126926812488818541169166564941406250000000000000000000000000000000000000000000000") }, |
| |
| { njs_str("(2**128).toPrecision(40)"), |
| njs_str("340282366920938463463374607431768211456.0") }, |
| #endif |
| |
| { njs_str("(2**128).toPrecision(1)"), |
| njs_str("3e+38") }, |
| |
| { njs_str("(2**128).toPrecision(2)"), |
| njs_str("3.4e+38") }, |
| |
| { njs_str("(2**128).toPrecision(40)"), |
| njs_str("340282366920938463490000000000000000000.0") }, |
| |
| { njs_str("(123).toPrecision(0)"), |
| njs_str("RangeError: precision argument must be between 1 and 100") }, |
| |
| { njs_str("(123).toPrecision(2.4)"), |
| njs_str("1.2e+2") }, |
| |
| { njs_str("(123).toPrecision(101)"), |
| njs_str("RangeError: precision argument must be between 1 and 100") }, |
| |
| { njs_str("(2**10000).toPrecision()"), |
| njs_str("Infinity") }, |
| |
| { njs_str("(-(2**10000)).toPrecision()"), |
| njs_str("-Infinity") }, |
| |
| { njs_str("var v = parseFloat('9'.repeat(98));" |
| "[98,100].map(p=>v.toPrecision(p).length)"), |
| njs_str("98,101") }, |
| |
| { njs_str("(-0).toPrecision(2)"), |
| njs_str("0.0") }, |
| |
| { njs_str("NaN.toPrecision()"), |
| njs_str("NaN") }, |
| |
| { njs_str("NaN.toPrecision(0)"), |
| njs_str("NaN") }, |
| |
| { njs_str("(10**22).toPrecision()"), |
| njs_str("1e+22") }, |
| |
| { njs_str("Number.prototype.toPrecision.call('12')"), |
| njs_str("TypeError: unexpected value type:string") }, |
| |
| { njs_str("(1000000000000000128).toString()"), |
| njs_str("1000000000000000100") }, |
| |
| { njs_str("(1000000000000000128).toFixed(0)"), |
| njs_str("1000000000000000128") }, |
| |
| { njs_str("(1e21).toFixed(1)"), |
| njs_str("1e+21") }, |
| |
| { njs_str("Number.prototype.toFixed.call({})"), |
| njs_str("TypeError: unexpected value type:object") }, |
| |
| { njs_str("(0).toFixed(-1)"), |
| njs_str("RangeError: digits argument must be between 0 and 100") }, |
| |
| { njs_str("(0).toFixed(101)"), |
| njs_str("RangeError: digits argument must be between 0 and 100") }, |
| |
| /* Number.prototype.toExponential(frac) method. */ |
| |
| { njs_str("Array(3).fill().map((n, i) => i + 1).map((v)=>(0).toExponential(v))"), |
| njs_str("0.0e+0,0.00e+0,0.000e+0") }, |
| |
| { njs_str("Array(6).fill().map((n, i) => i + 1).map((v)=>((Math.pow(-1,v))*(2*v)/3).toExponential(5))"), |
| njs_str("-6.66667e-1,1.33333e+0,-2.00000e+0,2.66667e+0,-3.33333e+0,4.00000e+0") }, |
| |
| { njs_str("Array(5).fill().map((n, i) => i + 1).map((v)=>((Math.pow(-1,v))*(2*v)/3).toExponential())"), |
| njs_str("-6.666666666666666e-1,1.3333333333333333e+0,-2e+0,2.6666666666666667e+0,-3.3333333333333337e+0") }, |
| |
| { njs_str("1.7976931348623157e+308.toExponential()"), |
| njs_str("1.7976931348623157e+308") }, |
| |
| #if 0 /* FIXME: bignum support is requred to support prec >= 20 */ |
| { njs_str("(1/7).toExponential(100)"), |
| njs_str("1.4285714285714284921269268124888185411691665649414062500000000000000000000000000000000000000000000000e-1") }, |
| #endif |
| |
| { njs_str("var v = 1.7976931348623157e+308; Number(v.toExponential()) == v"), |
| njs_str("true") }, |
| |
| { njs_str("(123).toExponential(-1)"), |
| njs_str("RangeError: digits argument must be between 0 and 100") }, |
| |
| { njs_str("(123).toExponential(2.4)"), |
| njs_str("1.23e+2") }, |
| |
| { njs_str("(123).toExponential(101)"), |
| njs_str("RangeError: digits argument must be between 0 and 100") }, |
| |
| { njs_str("[2**10000,-(2**10000),NaN].map((v)=>v.toExponential())"), |
| njs_str("Infinity,-Infinity,NaN") }, |
| |
| { njs_str("[2**10000,-(2**10000),NaN].map((v)=>v.toExponential(1000))"), |
| njs_str("Infinity,-Infinity,NaN") }, |
| |
| { njs_str("Number.prototype.toExponential.call('12')"), |
| njs_str("TypeError: unexpected value type:string") }, |
| |
| /* An object "valueOf/toString" methods. */ |
| |
| { njs_str("var a = { valueOf: function() { return 1 } }; +a"), |
| njs_str("1") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } }; +a"), |
| njs_str("1") }, |
| |
| { njs_str("var a = { valueOf: 2," |
| " toString: function() { return '1' } }; +a"), |
| njs_str("1") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1 } }; ''+a"), |
| njs_str("1") }, |
| |
| { njs_str("var a = { valueOf: function() { return [] }," |
| " toString: function() { return '1' } }; +a"), |
| njs_str("1") }, |
| |
| { njs_str("var a = { toString: function() { return 'a' } };" |
| "var b = { toString: function() { return a+'b' } }; '0'+b"), |
| njs_str("0ab") }, |
| |
| { njs_str("({valueOf:()=>'4'}) / ({valueOf:()=>2})"), |
| njs_str("2") }, |
| |
| { njs_str("({valueOf:()=>{throw 'x'}}) / ({valueOf:()=>{throw 'y'}});" |
| "var e; try { x/y } catch(ex) {e = ex}; ex"), |
| njs_str("x") }, |
| |
| { njs_str("({valueOf:()=>{ try {throw 'x'} catch (ex) {return 6} } }) / 2"), |
| njs_str("3") }, |
| |
| { njs_str("({valueOf:()=>2}) / ({valueOf:()=>{throw 'y'}});" |
| "var e; try { x/y } catch(ex) {e = ex}; ex"), |
| njs_str("y") }, |
| |
| { njs_str("({valueOf:()=>'4'}) % ({valueOf:()=>3})"), |
| njs_str("1") }, |
| |
| { njs_str("({valueOf:()=>9}) >>> ({valueOf:()=>2})"), |
| njs_str("2") }, |
| |
| { njs_str("({valueOf:()=>0x1f}) & ({valueOf:()=>0xf})"), |
| njs_str("15") }, |
| |
| { njs_str("({valueOf:()=>0x1f}) ^ ({valueOf:()=>0xf})"), |
| njs_str("16") }, |
| |
| { njs_str("({valueOf:()=>0xf}) == ({valueOf:()=>0xf})"), |
| njs_str("false") }, |
| |
| { njs_str("var e; try {({valueOf: String.prototype.valueOf}) == 1} " |
| "catch (ex) { e = ex}; e"), |
| njs_str("TypeError: unexpected value type:object") }, |
| |
| { njs_str("({valueOf:()=>0xf}) == 0xf"), |
| njs_str("true") }, |
| |
| { njs_str("0xf == ({valueOf:()=>0xf})"), |
| njs_str("true") }, |
| |
| { njs_str("({valueOf:()=>'0xf'}) == 0xf"), |
| njs_str("true") }, |
| |
| { njs_str("0xf == ({valueOf:()=>'0xf'})"), |
| njs_str("true") }, |
| |
| { njs_str("({valueOf:()=>0xf}) == '0xf'"), |
| njs_str("true") }, |
| |
| { njs_str("'0xf' == ({valueOf:()=>0xf})"), |
| njs_str("true") }, |
| /**/ |
| |
| { njs_str("1 + undefined"), |
| njs_str("NaN") }, |
| |
| { njs_str("1 + ''"), |
| njs_str("1") }, |
| |
| { njs_str("0xA + ''"), |
| njs_str("10") }, |
| |
| { njs_str("undefined + undefined"), |
| njs_str("NaN") }, |
| |
| { njs_str("var undefined"), |
| njs_str("undefined") }, |
| |
| { njs_str("1.2 + 5.7"), |
| njs_str("6.9") }, |
| |
| { njs_str("0xf + 1"), |
| njs_str("16") }, |
| |
| { njs_str("1 + 1 + '2' + 1 + 1"), |
| njs_str("2211") }, |
| |
| { njs_str("'gg' + -0"), |
| njs_str("gg0") }, |
| |
| { njs_str("1.2 - '5.7'"), |
| njs_str("-4.5") }, |
| |
| { njs_str("1.2 + -'5.7'"), |
| njs_str("-4.5") }, |
| |
| { njs_str("1.2 - '-5.7'"), |
| njs_str("6.9") }, |
| |
| { njs_str("5 - ' \t 12 \t'"), |
| njs_str("-7") }, |
| |
| { njs_str("5 - '12zz'"), |
| njs_str("NaN") }, |
| |
| { njs_str("5 - '0x2'"), |
| njs_str("3") }, |
| |
| { njs_str("5 - '-0x2'"), |
| njs_str("7") }, |
| |
| { njs_str("5 - '\t 0x2 \t'"), |
| njs_str("3") }, |
| |
| { njs_str("5 - '\t\\u000c0x2 \t'"), |
| njs_str("3") }, |
| |
| { njs_str("5 - '0x2 z'"), |
| njs_str("NaN") }, |
| |
| { njs_str("12 - '5.7e1'"), |
| njs_str("-45") }, |
| |
| { njs_str("12 - '5.e1'"), |
| njs_str("-38") }, |
| |
| { njs_str("12 - '5.7e+01'"), |
| njs_str("-45") }, |
| |
| { njs_str("12 - '5.7e-01'"), |
| njs_str("11.43") }, |
| |
| { njs_str("12 - ' 5.7e1 '"), |
| njs_str("-45") }, |
| |
| { njs_str("12 - '5.7e'"), |
| njs_str("NaN") }, |
| |
| { njs_str("12 - '5.7e+'"), |
| njs_str("NaN") }, |
| |
| { njs_str("12 - '5.7e-'"), |
| njs_str("NaN") }, |
| |
| { njs_str("12 - ' 5.7e1 z'"), |
| njs_str("NaN") }, |
| |
| { njs_str("5 - '0x'"), |
| njs_str("NaN") }, |
| |
| { njs_str("1 + +'3'"), |
| njs_str("4") }, |
| |
| { njs_str("1 - undefined"), |
| njs_str("NaN") }, |
| |
| { njs_str("1 - ''"), |
| njs_str("1") }, |
| |
| { njs_str("undefined - undefined"), |
| njs_str("NaN") }, |
| |
| /* String.toString() method. */ |
| |
| { njs_str("'A'.toString()"), |
| njs_str("A") }, |
| |
| { njs_str("'A'.toBytes().toString('latin1')"), |
| njs_str("TypeError: Unknown encoding: \"latin1\"") }, |
| |
| { njs_str("'ABCD'.toBytes().toString('hex')"), |
| njs_str("41424344") }, |
| |
| { njs_str("'\\x00\\xAA\\xBB\\xFF'.toBytes().toString('hex')"), |
| njs_str("00aabbff") }, |
| |
| { njs_str("'\\x00\\xAA\\xBB\\xFF'.toBytes().toString('base64')"), |
| njs_str("AKq7/w==") }, |
| |
| { njs_str("'ABCD'.toBytes().toString('base64')"), |
| njs_str("QUJDRA==") }, |
| |
| { njs_str("'ABC'.toBytes().toString('base64')"), |
| njs_str("QUJD") }, |
| |
| { njs_str("'AB'.toBytes().toString('base64')"), |
| njs_str("QUI=") }, |
| |
| { njs_str("'A'.toBytes().toString('base64')"), |
| njs_str("QQ==") }, |
| |
| { njs_str("''.toBytes().toString('base64')"), |
| njs_str("") }, |
| |
| { njs_str("'\\x00\\xAA\\xBB\\xFF'.toBytes().toString('base64url')"), |
| njs_str("AKq7_w") }, |
| |
| { njs_str("'ABCD'.toBytes().toString('base64url')"), |
| njs_str("QUJDRA") }, |
| |
| { njs_str("'ABC'.toBytes().toString('base64url')"), |
| njs_str("QUJD") }, |
| |
| { njs_str("'AB'.toBytes().toString('base64url')"), |
| njs_str("QUI") }, |
| |
| { njs_str("'A'.toBytes().toString('base64url')"), |
| njs_str("QQ") }, |
| |
| { njs_str("''.toBytes().toString('base64url')"), |
| njs_str("") }, |
| |
| /* Assignment. */ |
| |
| { njs_str("var a, b = (a = [2]) * (3 * 4); a +' '+ b"), |
| njs_str("2 24") }, |
| |
| { njs_str("var a = 1; var b = a += 1; b"), |
| njs_str("2") }, |
| |
| { njs_str("var a = 1; var b = a -= 1; b"), |
| njs_str("0") }, |
| |
| { njs_str("var a = 1; var b = a <<= 1; b"), |
| njs_str("2") }, |
| |
| /* 3 address operation and side effect. */ |
| |
| { njs_str("var a = 1; function f(x) { a = x; return 2 }; a+f(5)+' '+a"), |
| njs_str("3 5") }, |
| |
| { njs_str("var a = 1; function f(x) { a = x; return 2 }; a += f(5)"), |
| njs_str("3") }, |
| |
| { njs_str("var x; x in (x = 1, [1, 2, 3])"), |
| njs_str("false") }, |
| |
| /* Exponentiation. */ |
| |
| { njs_str("2 ** 3 ** 2"), |
| njs_str("512") }, |
| |
| { njs_str("2 ** (3 ** 2)"), |
| njs_str("512") }, |
| |
| { njs_str("(2 ** 3) ** 2"), |
| njs_str("64") }, |
| |
| { njs_str("3 ** 2 - 9"), |
| njs_str("0") }, |
| |
| { njs_str("-9 + 3 ** 2"), |
| njs_str("0") }, |
| |
| { njs_str("-3 ** 2"), |
| njs_str("SyntaxError: Either left-hand side or entire exponentiation " |
| "must be parenthesized in 1") }, |
| |
| { njs_str("-(3) ** 2"), |
| njs_str("SyntaxError: Either left-hand side or entire exponentiation " |
| "must be parenthesized in 1") }, |
| |
| { njs_str("-(3 ** 2)"), |
| njs_str("-9") }, |
| |
| { njs_str("(-3) ** 2"), |
| njs_str("9") }, |
| |
| { njs_str("1 ** NaN"), |
| njs_str("NaN") }, |
| |
| { njs_str("'a' ** -0"), |
| njs_str("1") }, |
| |
| { njs_str("1.1 ** Infinity"), |
| njs_str("Infinity") }, |
| |
| { njs_str("(-1.1) ** -Infinity"), |
| njs_str("0") }, |
| |
| { njs_str("(-1) ** Infinity"), |
| njs_str("NaN") }, |
| |
| { njs_str("1 ** -Infinity"), |
| njs_str("NaN") }, |
| |
| { njs_str("(-0.9) ** Infinity"), |
| njs_str("0") }, |
| |
| { njs_str("0.9 ** -Infinity"), |
| njs_str("Infinity") }, |
| |
| { njs_str("'Infinity' ** 0.1"), |
| njs_str("Infinity") }, |
| |
| { njs_str("Infinity ** '-0.1'"), |
| njs_str("0") }, |
| |
| { njs_str("(-Infinity) ** 3"), |
| njs_str("-Infinity") }, |
| |
| { njs_str("'-Infinity' ** '3.1'"), |
| njs_str("Infinity") }, |
| |
| { njs_str("(-Infinity) ** '-3'"), |
| njs_str("-0") }, |
| |
| { njs_str("'-Infinity' ** -2"), |
| njs_str("0") }, |
| |
| { njs_str("'0' ** 0.1"), |
| njs_str("0") }, |
| |
| #ifndef __NetBSD__ /* NetBSD 7: pow(0, negative) == -Infinity. */ |
| { njs_str("0 ** '-0.1'"), |
| njs_str("Infinity") }, |
| #endif |
| |
| { njs_str("(-0) ** 3"), |
| njs_str("-0") }, |
| |
| { njs_str("'-0' ** '3.1'"), |
| njs_str("0") }, |
| |
| { njs_str("(-0) ** '-3'"), |
| njs_str("-Infinity") }, |
| |
| #ifndef __NetBSD__ /* NetBSD 7: pow(0, negative) == -Infinity. */ |
| { njs_str("'-0' ** -2"), |
| njs_str("Infinity") }, |
| #endif |
| |
| { njs_str("(-3) ** 0.1"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = 0.1; a **= -2"), |
| njs_str("99.99999999999999") }, |
| |
| { njs_str("var a = 1; a **= NaN"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = 'a'; a **= -0"), |
| njs_str("1") }, |
| |
| { njs_str("var a = 1.1; a **= Infinity"), |
| njs_str("Infinity") }, |
| |
| { njs_str("var a = -1.1; a **= -Infinity"), |
| njs_str("0") }, |
| |
| { njs_str("var a = -1; a **= Infinity"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = 1; a **= -Infinity"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = -0.9; a **= Infinity"), |
| njs_str("0") }, |
| |
| { njs_str("var a = 0.9; a **= -Infinity"), |
| njs_str("Infinity") }, |
| |
| { njs_str("var a = 'Infinity'; a **= 0.1"), |
| njs_str("Infinity") }, |
| |
| { njs_str("var a = Infinity; a **= '-0.1'"), |
| njs_str("0") }, |
| |
| { njs_str("var a = -Infinity; a **= 3"), |
| njs_str("-Infinity") }, |
| |
| { njs_str("var a = '-Infinity'; a **= '3.1'"), |
| njs_str("Infinity") }, |
| |
| { njs_str("var a = -Infinity; a **= '-3'"), |
| njs_str("-0") }, |
| |
| { njs_str("var a = '-Infinity'; a **= -2"), |
| njs_str("0") }, |
| |
| { njs_str("var a = '0'; a **= 0.1"), |
| njs_str("0") }, |
| |
| #ifndef __NetBSD__ /* NetBSD 7: pow(0, negative) == -Infinity. */ |
| { njs_str("var a = 0; a **= '-0.1'"), |
| njs_str("Infinity") }, |
| #endif |
| |
| { njs_str("var a = -0; a **= 3"), |
| njs_str("-0") }, |
| |
| { njs_str("var a = '-0'; a **= '3.1'"), |
| njs_str("0") }, |
| |
| { njs_str("var a = -0; a **= '-3'"), |
| njs_str("-Infinity") }, |
| |
| #ifndef __NetBSD__ /* NetBSD 7: pow(0, negative) == -Infinity. */ |
| { njs_str("var a = '-0'; a **= -2"), |
| njs_str("Infinity") }, |
| #endif |
| |
| { njs_str("var a = -3; a **= 0.1"), |
| njs_str("NaN") }, |
| |
| /**/ |
| |
| { njs_str("12 | 6"), |
| njs_str("14") }, |
| |
| { njs_str("12 | 'abc'"), |
| njs_str("12") }, |
| |
| { njs_str("-1 | 0"), |
| njs_str("-1") }, |
| |
| { njs_str("-2147483648 | 0"), |
| njs_str("-2147483648") }, |
| |
| { njs_str("1024.9 | 0"), |
| njs_str("1024") }, |
| |
| { njs_str("-1024.9 | 0"), |
| njs_str("-1024") }, |
| |
| { njs_str("9007199254740991 | 0"), |
| njs_str("-1") }, |
| |
| { njs_str("9007199254740992 | 0"), |
| njs_str("0") }, |
| |
| { njs_str("9007199254740993 | 0"), |
| njs_str("0") }, |
| |
| #if 0 |
| { njs_str("9223372036854775808 | 0"), |
| njs_str("0") }, |
| #endif |
| |
| { njs_str("9223372036854777856 | 0"), |
| njs_str("2048") }, |
| |
| { njs_str("-9223372036854777856 | 0"), |
| njs_str("-2048") }, |
| |
| { njs_str("NaN | 0"), |
| njs_str("0") }, |
| |
| { njs_str("-NaN | 0"), |
| njs_str("0") }, |
| |
| { njs_str("Infinity | 0"), |
| njs_str("0") }, |
| |
| { njs_str("-Infinity | 0"), |
| njs_str("0") }, |
| |
| { njs_str("+0 | 0"), |
| njs_str("0") }, |
| |
| { njs_str("-0 | 0"), |
| njs_str("0") }, |
| |
| { njs_str("32.5 << 2.4"), |
| njs_str("128") }, |
| |
| { njs_str("32.5 << 'abc'"), |
| njs_str("32") }, |
| |
| { njs_str("'abc' << 2"), |
| njs_str("0") }, |
| |
| { njs_str("-1 << 0"), |
| njs_str("-1") }, |
| |
| { njs_str("-1 << -1"), |
| njs_str("-2147483648") }, |
| |
| { njs_str("-2147483648 << 0"), |
| njs_str("-2147483648") }, |
| |
| #if 0 |
| { njs_str("9223372036854775808 << 0"), |
| njs_str("0") }, |
| #endif |
| |
| { njs_str("9223372036854777856 << 0"), |
| njs_str("2048") }, |
| |
| { njs_str("-9223372036854777856 << 0"), |
| njs_str("-2048") }, |
| |
| { njs_str("NaN << 0"), |
| njs_str("0") }, |
| |
| { njs_str("32.5 >> 2.4"), |
| njs_str("8") }, |
| |
| { njs_str("-1 >> 30"), |
| njs_str("-1") }, |
| |
| { njs_str("'abc' >> 2"), |
| njs_str("0") }, |
| |
| { njs_str("-1 >> 0"), |
| njs_str("-1") }, |
| |
| { njs_str("-1 >> -1"), |
| njs_str("-1") }, |
| |
| { njs_str("-2147483648 >> 0"), |
| njs_str("-2147483648") }, |
| |
| { njs_str("-2147483648 >> -1"), |
| njs_str("-1") }, |
| |
| #if 0 |
| { njs_str("9223372036854775808 >> 0"), |
| njs_str("0") }, |
| #endif |
| |
| { njs_str("9223372036854777856 >> 0"), |
| njs_str("2048") }, |
| |
| { njs_str("-9223372036854777856 >> 0"), |
| njs_str("-2048") }, |
| |
| { njs_str("NaN >> 0"), |
| njs_str("0") }, |
| |
| { njs_str("-1 >>> 30"), |
| njs_str("3") }, |
| |
| { njs_str("NaN >>> 1"), |
| njs_str("0") }, |
| |
| #if 0 |
| { njs_str("9223372036854775808 >>> 1"), |
| njs_str("0") }, |
| #endif |
| |
| { njs_str("-1 >>> 0"), |
| njs_str("4294967295") }, |
| |
| { njs_str("-1 >>> -1"), |
| njs_str("1") }, |
| |
| { njs_str("-2147483648 >>> 0"), |
| njs_str("2147483648") }, |
| |
| { njs_str("-2147483648 >>> -1"), |
| njs_str("1") }, |
| |
| #if 0 |
| { njs_str("9223372036854775808 >>> 0"), |
| njs_str("0") }, |
| #endif |
| |
| { njs_str("9223372036854777856 >>> 0"), |
| njs_str("2048") }, |
| |
| { njs_str("-9223372036854777856 >>> 0"), |
| njs_str("4294965248") }, |
| |
| { njs_str("NaN >>> 0"), |
| njs_str("0") }, |
| |
| { njs_str("!2"), |
| njs_str("false") }, |
| |
| /**/ |
| |
| { njs_str("var a = { valueOf: function() { return 1 } }; ~a"), |
| njs_str("-2") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } }; ~a"), |
| njs_str("-2") }, |
| |
| /**/ |
| |
| { njs_str("1 || 2"), |
| njs_str("1") }, |
| |
| { njs_str("var a = 1; 1 || (a = 2); a"), |
| njs_str("1") }, |
| |
| { njs_str("var x; x = 0 || x; x"), |
| njs_str("undefined") }, |
| |
| { njs_str("var x; x = 1 && x; x"), |
| njs_str("undefined") }, |
| |
| { njs_str("1 || 2 || 3"), |
| njs_str("1") }, |
| |
| { njs_str("1 || (2 + 2) || 3"), |
| njs_str("1") }, |
| |
| { njs_str("1 && 2"), |
| njs_str("2") }, |
| |
| { njs_str("1 && 2 && 3"), |
| njs_str("3") }, |
| |
| { njs_str("var a = 1; 0 && (a = 2); a"), |
| njs_str("1") }, |
| |
| { njs_str("false && true || true"), |
| njs_str("true") }, |
| |
| { njs_str("false && (true || true)"), |
| njs_str("false") }, |
| |
| { njs_str("true && (null ?? true)"), |
| njs_str("true") }, |
| |
| { njs_str("(null || undefined) ?? (true && true)"), |
| njs_str("true") }, |
| |
| { njs_str("undefined ?? null ?? false ?? true"), |
| njs_str("false") }, |
| |
| { njs_str("1 && 1 ?? true"), |
| njs_str("SyntaxError: Unexpected token \"??\" in 1") }, |
| |
| { njs_str("null ?? 0 || 1"), |
| njs_str("SyntaxError: Unexpected token \"||\" in 1") }, |
| |
| { njs_str("var a = true; a = -~!a"), |
| njs_str("1") }, |
| |
| { njs_str("12 & 6"), |
| njs_str("4") }, |
| |
| { njs_str("-1 & 65536"), |
| njs_str("65536") }, |
| |
| { njs_str("-2147483648 & 65536"), |
| njs_str("0") }, |
| |
| #if 0 |
| { njs_str("9223372036854775808 & 65536"), |
| njs_str("0") }, |
| #endif |
| |
| { njs_str("NaN & 65536"), |
| njs_str("0") }, |
| |
| { njs_str("12 ^ 6"), |
| njs_str("10") }, |
| |
| { njs_str("-1 ^ 65536"), |
| njs_str("-65537") }, |
| |
| { njs_str("-2147483648 ^ 65536"), |
| njs_str("-2147418112") }, |
| |
| #if 0 |
| { njs_str("9223372036854775808 ^ 65536"), |
| njs_str("65536") }, |
| #endif |
| |
| { njs_str("NaN ^ 65536"), |
| njs_str("65536") }, |
| |
| { njs_str("var x = '1'; +x + 2"), |
| njs_str("3") }, |
| |
| /* Weird things. */ |
| |
| { njs_str("'3' -+-+-+ '1' + '1' / '3' * '6' + '2'"), |
| njs_str("42") }, |
| |
| { njs_str("((+!![])+(+!![])+(+!![])+(+!![])+[])+((+!![])+(+!![])+[])"), |
| njs_str("42") }, |
| |
| { njs_str("1+[[]+[]]-[]+[[]-[]]-1"), |
| njs_str("9") }, |
| |
| { njs_str("[[]+[]]-[]+[[]-[]]"), |
| njs_str("00") }, |
| |
| { njs_str("!--[][1]"), |
| njs_str("true") }, |
| |
| { njs_str("[].concat[1,2,3]"), |
| njs_str("undefined") }, |
| |
| /**/ |
| |
| { njs_str("'true' == true"), |
| njs_str("false") }, |
| |
| { njs_str("null == false"), |
| njs_str("false") }, |
| |
| { njs_str("0 == null"), |
| njs_str("false") }, |
| |
| { njs_str("!null"), |
| njs_str("true") }, |
| |
| { njs_str("0 === -0"), |
| njs_str("true") }, |
| |
| { njs_str("1/-0"), |
| njs_str("-Infinity") }, |
| |
| { njs_str("1/0 === 1/-0"), |
| njs_str("false") }, |
| |
| { njs_str("1 == true"), |
| njs_str("true") }, |
| |
| { njs_str("NaN === NaN"), |
| njs_str("false") }, |
| |
| { njs_str("NaN !== NaN"), |
| njs_str("true") }, |
| |
| { njs_str("NaN == NaN"), |
| njs_str("false") }, |
| |
| { njs_str("NaN != NaN"), |
| njs_str("true") }, |
| |
| { njs_str("NaN == false"), |
| njs_str("false") }, |
| |
| { njs_str("Infinity == Infinity"), |
| njs_str("true") }, |
| |
| { njs_str("-Infinity == -Infinity"), |
| njs_str("true") }, |
| |
| { njs_str("-Infinity < Infinity"), |
| njs_str("true") }, |
| |
| { njs_str("Infinity - Infinity"), |
| njs_str("NaN") }, |
| |
| { njs_str("Infinity - -Infinity"), |
| njs_str("Infinity") }, |
| |
| { njs_str("undefined == 0"), |
| njs_str("false") }, |
| |
| { njs_str("undefined == null"), |
| njs_str("true") }, |
| |
| { njs_str("'1' == 1"), |
| njs_str("true") }, |
| |
| { njs_str("'1a' == '1'"), |
| njs_str("false") }, |
| |
| { njs_str("'abc' == 'abc'"), |
| njs_str("true") }, |
| |
| { njs_str("'abc' < 'abcde'"), |
| njs_str("true") }, |
| |
| { njs_str("0 == ''"), |
| njs_str("true") }, |
| |
| { njs_str("0 == ' '"), |
| njs_str("true") }, |
| |
| { njs_str("0 == ' '"), |
| njs_str("true") }, |
| |
| { njs_str("0 == '0'"), |
| njs_str("true") }, |
| |
| { njs_str("0 == ' 0 '"), |
| njs_str("true") }, |
| |
| { njs_str("0 == '000'"), |
| njs_str("true") }, |
| |
| { njs_str("'0' == ''"), |
| njs_str("false") }, |
| |
| { njs_str("1 < 2"), |
| njs_str("true") }, |
| |
| { njs_str("NaN < NaN"), |
| njs_str("false") }, |
| |
| { njs_str("NaN > NaN"), |
| njs_str("false") }, |
| |
| { njs_str("undefined < 1"), |
| njs_str("false") }, |
| |
| { njs_str("[] == false"), |
| njs_str("true") }, |
| |
| { njs_str("[0] == false"), |
| njs_str("true") }, |
| |
| { njs_str("[0,0] == false"), |
| njs_str("false") }, |
| |
| { njs_str("({}) == false"), |
| njs_str("false") }, |
| |
| { njs_str("new Number(1) == new String('1')"), |
| njs_str("false") }, |
| |
| { njs_str("var a = Object; a == Object"), |
| njs_str("true") }, |
| |
| { njs_str("'1' == new Number(1)"), |
| njs_str("true") }, |
| |
| { njs_str("new Number(null) + ''"), |
| njs_str("0") }, |
| |
| { njs_str("new String('abc') == 'abc'"), |
| njs_str("true") }, |
| |
| { njs_str("false == new String('0')"), |
| njs_str("true") }, |
| |
| { njs_str("var a = { valueOf: function() { return 5 } }; a == 5"), |
| njs_str("true") }, |
| |
| { njs_str("var a = { valueOf: function() { return '5' } }; a == 5"), |
| njs_str("true") }, |
| |
| { njs_str("var a = { valueOf: function() { return '5' } }; a == '5'"), |
| njs_str("true") }, |
| |
| { njs_str("var a = { valueOf: function() { return 5 } }; a == '5'"), |
| njs_str("true") }, |
| |
| { njs_str("var a = { toString: function() { return true } }; '1' == a"), |
| njs_str("true") }, |
| |
| { njs_str("var a = { valueOf: function() { return 'b' }," |
| " toString: function() { return 'a' } }; a == 'a'"), |
| njs_str("false") }, |
| |
| /* Comparisions. */ |
| |
| { njs_str("1 < 2"), |
| njs_str("true") }, |
| |
| { njs_str("1 < 1"), |
| njs_str("false") }, |
| |
| { njs_str("1 <= 1"), |
| njs_str("true") }, |
| |
| { njs_str("1 <= 2"), |
| njs_str("true") }, |
| |
| { njs_str("2 > 1"), |
| njs_str("true") }, |
| |
| { njs_str("1 > 2"), |
| njs_str("false") }, |
| |
| { njs_str("1 > 1"), |
| njs_str("false") }, |
| |
| { njs_str("1 >= 1"), |
| njs_str("true") }, |
| |
| { njs_str("2 >= 1"), |
| njs_str("true") }, |
| |
| { njs_str("1 >= 2"), |
| njs_str("false") }, |
| |
| /**/ |
| |
| { njs_str("null === null"), |
| njs_str("true") }, |
| |
| { njs_str("null !== null"), |
| njs_str("false") }, |
| |
| { njs_str("null == null"), |
| njs_str("true") }, |
| |
| { njs_str("null != null"), |
| njs_str("false") }, |
| |
| { njs_str("null < null"), |
| njs_str("false") }, |
| |
| { njs_str("null > null"), |
| njs_str("false") }, |
| |
| { njs_str("null <= null"), |
| njs_str("true") }, |
| |
| { njs_str("null >= null"), |
| njs_str("true") }, |
| |
| /**/ |
| |
| { njs_str("null === undefined"), |
| njs_str("false") }, |
| |
| { njs_str("null !== undefined"), |
| njs_str("true") }, |
| |
| { njs_str("null == undefined"), |
| njs_str("true") }, |
| |
| { njs_str("null != undefined"), |
| njs_str("false") }, |
| |
| { njs_str("null < undefined"), |
| njs_str("false") }, |
| |
| { njs_str("null > undefined"), |
| njs_str("false") }, |
| |
| { njs_str("null <= undefined"), |
| njs_str("false") }, |
| |
| { njs_str("null >= undefined"), |
| njs_str("false") }, |
| |
| /**/ |
| |
| { njs_str("null === false"), |
| njs_str("false") }, |
| |
| { njs_str("null !== false"), |
| njs_str("true") }, |
| |
| { njs_str("null == false"), |
| njs_str("false") }, |
| |
| { njs_str("null != false"), |
| njs_str("true") }, |
| |
| { njs_str("null < false"), |
| njs_str("false") }, |
| |
| { njs_str("null > false"), |
| njs_str("false") }, |
| |
| { njs_str("null <= false"), |
| njs_str("true") }, |
| |
| { njs_str("null >= false"), |
| njs_str("true") }, |
| |
| /**/ |
| |
| { njs_str("null === true"), |
| njs_str("false") }, |
| |
| { njs_str("null !== true"), |
| njs_str("true") }, |
| |
| { njs_str("null == true"), |
| njs_str("false") }, |
| |
| { njs_str("null != true"), |
| njs_str("true") }, |
| |
| { njs_str("null < true"), |
| njs_str("true") }, |
| |
| { njs_str("null > true"), |
| njs_str("false") }, |
| |
| { njs_str("null <= true"), |
| njs_str("true") }, |
| |
| { njs_str("null >= true"), |
| njs_str("false") }, |
| |
| /**/ |
| |
| { njs_str("Infinity === Infinity"), |
| njs_str("true") }, |
| |
| { njs_str("Infinity !== Infinity"), |
| njs_str("false") }, |
| |
| { njs_str("Infinity == Infinity"), |
| njs_str("true") }, |
| |
| { njs_str("Infinity != Infinity"), |
| njs_str("false") }, |
| |
| { njs_str("Infinity < Infinity"), |
| njs_str("false") }, |
| |
| { njs_str("Infinity > Infinity"), |
| njs_str("false") }, |
| |
| { njs_str("Infinity <= Infinity"), |
| njs_str("true") }, |
| |
| { njs_str("Infinity >= Infinity"), |
| njs_str("true") }, |
| |
| /**/ |
| |
| { njs_str("-Infinity === Infinity"), |
| njs_str("false") }, |
| |
| { njs_str("-Infinity !== Infinity"), |
| njs_str("true") }, |
| |
| { njs_str("-Infinity == Infinity"), |
| njs_str("false") }, |
| |
| { njs_str("-Infinity != Infinity"), |
| njs_str("true") }, |
| |
| { njs_str("-Infinity < Infinity"), |
| njs_str("true") }, |
| |
| { njs_str("-Infinity > Infinity"), |
| njs_str("false") }, |
| |
| { njs_str("-Infinity <= Infinity"), |
| njs_str("true") }, |
| |
| { njs_str("-Infinity >= Infinity"), |
| njs_str("false") }, |
| |
| { njs_str("Boolean(Infinity)"), |
| njs_str("true") }, |
| |
| { njs_str("!Infinity === false"), |
| njs_str("true") }, |
| |
| { njs_str("var Infinity"), |
| njs_str("undefined") }, |
| |
| #if 0 /* ES5FIX */ |
| { njs_str("Infinity = 1"), |
| njs_str("TypeError: Cannot assign to read-only property "Infinity" of object") }, |
| #endif |
| |
| /**/ |
| |
| { njs_str("NaN === NaN"), |
| njs_str("false") }, |
| |
| { njs_str("NaN !== NaN"), |
| njs_str("true") }, |
| |
| { njs_str("NaN == NaN"), |
| njs_str("false") }, |
| |
| { njs_str("NaN != NaN"), |
| njs_str("true") }, |
| |
| { njs_str("NaN < NaN"), |
| njs_str("false") }, |
| |
| { njs_str("NaN > NaN"), |
| njs_str("false") }, |
| |
| { njs_str("NaN >= NaN"), |
| njs_str("false") }, |
| |
| { njs_str("NaN <= NaN"), |
| njs_str("false") }, |
| |
| { njs_str("var NaN"), |
| njs_str("undefined") }, |
| |
| #if 0 /* ES5FIX */ |
| { njs_str("NaN = 1"), |
| njs_str("TypeError: Cannot assign to read-only property "NaN" of object") }, |
| #endif |
| |
| /**/ |
| |
| { njs_str("null < 0"), |
| njs_str("false") }, |
| |
| { njs_str("null < 1"), |
| njs_str("true") }, |
| |
| { njs_str("null < NaN"), |
| njs_str("false") }, |
| |
| { njs_str("null < -Infinity"), |
| njs_str("false") }, |
| |
| { njs_str("null < Infinity"), |
| njs_str("true") }, |
| |
| { njs_str("null < 'null'"), |
| njs_str("false") }, |
| |
| { njs_str("null < '1'"), |
| njs_str("true") }, |
| |
| { njs_str("null < [1]"), |
| njs_str("true") }, |
| |
| { njs_str("null < ({})"), |
| njs_str("false") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1 } }; null < a"), |
| njs_str("true") }, |
| |
| { njs_str("var a = { valueOf: function() { return 'null' } };null < a"), |
| njs_str("false") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } }; null < a"), |
| njs_str("true") }, |
| |
| { njs_str("1 < {valueOf: ()=>{throw 'x'}}"), |
| njs_str("x") }, |
| |
| { njs_str("({valueOf: ()=>{throw 'x'}}) <= ({valueOf:()=>{throw 'y'}})"), |
| njs_str("x") }, |
| |
| { njs_str("({valueOf:()=>{throw 'x'}}) > ({valueOf:()=>{throw 'y'}})"), |
| njs_str("x") }, |
| |
| /**/ |
| |
| { njs_str("undefined == undefined"), |
| njs_str("true") }, |
| |
| { njs_str("undefined != undefined"), |
| njs_str("false") }, |
| |
| { njs_str("undefined === undefined"), |
| njs_str("true") }, |
| |
| { njs_str("undefined !== undefined"), |
| njs_str("false") }, |
| |
| { njs_str("undefined < undefined"), |
| njs_str("false") }, |
| |
| { njs_str("undefined < null"), |
| njs_str("false") }, |
| |
| { njs_str("undefined < false"), |
| njs_str("false") }, |
| |
| { njs_str("undefined < true"), |
| njs_str("false") }, |
| |
| { njs_str("undefined < 0"), |
| njs_str("false") }, |
| |
| { njs_str("undefined < 1"), |
| njs_str("false") }, |
| |
| { njs_str("undefined < NaN"), |
| njs_str("false") }, |
| |
| { njs_str("undefined < -Infinity"), |
| njs_str("false") }, |
| |
| { njs_str("undefined < Infinity"), |
| njs_str("false") }, |
| |
| { njs_str("undefined < 'undefined'"), |
| njs_str("false") }, |
| |
| { njs_str("undefined < '1'"), |
| njs_str("false") }, |
| |
| { njs_str("undefined < [1]"), |
| njs_str("false") }, |
| |
| { njs_str("undefined < ({})"), |
| njs_str("false") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1 } }; undefined < a"), |
| njs_str("false") }, |
| |
| { njs_str("var a = { valueOf: function() { return 'undefined' } };" |
| "undefined < a"), |
| njs_str("false") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } };" |
| "undefined < a"), |
| njs_str("false") }, |
| |
| /**/ |
| |
| { njs_str("false < 1"), |
| njs_str("true") }, |
| |
| { njs_str("true < 1"), |
| njs_str("false") }, |
| |
| { njs_str("-1 < 1"), |
| njs_str("true") }, |
| |
| { njs_str("-1 < '1'"), |
| njs_str("true") }, |
| |
| { njs_str("NaN < NaN"), |
| njs_str("false") }, |
| |
| { njs_str("-Infinity < Infinity"), |
| njs_str("true") }, |
| |
| { njs_str("Infinity < -Infinity"), |
| njs_str("false") }, |
| |
| { njs_str("1 < 'abc'"), |
| njs_str("false") }, |
| |
| /**/ |
| |
| { njs_str("[] === []"), |
| njs_str("false") }, |
| |
| { njs_str("[] !== []"), |
| njs_str("true") }, |
| |
| { njs_str("[] == []"), |
| njs_str("false") }, |
| |
| { njs_str("[] != []"), |
| njs_str("true") }, |
| |
| { njs_str("[] < []"), |
| njs_str("false") }, |
| |
| { njs_str("[] > []"), |
| njs_str("false") }, |
| |
| { njs_str("[] >= []"), |
| njs_str("true") }, |
| |
| { njs_str("[] <= []"), |
| njs_str("true") }, |
| |
| /**/ |
| |
| { njs_str("({}) === ({})"), |
| njs_str("false") }, |
| |
| { njs_str("({}) !== ({})"), |
| njs_str("true") }, |
| |
| { njs_str("({}) == ({})"), |
| njs_str("false") }, |
| |
| { njs_str("({}) != ({})"), |
| njs_str("true") }, |
| |
| { njs_str("({}) > ({})"), |
| njs_str("false") }, |
| |
| { njs_str("({}) <= ({})"), |
| njs_str("true") }, |
| |
| { njs_str("({}) >= ({})"), |
| njs_str("true") }, |
| |
| /**/ |
| |
| { njs_str("[0] == ({})"), |
| njs_str("false") }, |
| |
| { njs_str("[0] != ({})"), |
| njs_str("true") }, |
| |
| { njs_str("[0] <= ({})"), |
| njs_str("true") }, |
| |
| { njs_str("[0] >= ({})"), |
| njs_str("false") }, |
| |
| /**/ |
| { njs_str("new String('1') > new Number(1)"), |
| njs_str("false") }, |
| |
| { njs_str("new Boolean(true) > '1'"), |
| njs_str("false") }, |
| |
| { njs_str("'0' >= new Number(1)"), |
| njs_str("false") }, |
| |
| { njs_str("'1' >= new Number(1)"), |
| njs_str("true") }, |
| |
| { njs_str("new String('1') < new Number(1)"), |
| njs_str("false") }, |
| |
| { njs_str("new Boolean(true) < '1'"), |
| njs_str("false") }, |
| |
| { njs_str("new String('1') <= new Number(1)"), |
| njs_str("true") }, |
| |
| { njs_str("new Boolean(true) <= '1'"), |
| njs_str("true") }, |
| |
| { njs_str("'-1' < {valueOf: function() {return -2}}"), |
| njs_str("false") }, |
| |
| { njs_str("new 0[isNaN]"), |
| njs_str("TypeError: (intermediate value)[\"[object Function]\"] is not a function") }, |
| |
| { njs_str("new 0[undefined]"), |
| njs_str("TypeError: (intermediate value)[\"undefined\"] is not a function") }, |
| |
| /**/ |
| |
| { njs_str("var a; a = 1 ? 2 : 3"), |
| njs_str("2") }, |
| |
| { njs_str("var a; a = 1 ? 2 : 3 ? 4 : 5"), |
| njs_str("2") }, |
| |
| { njs_str("var a; a = 0 ? 2 : 3 ? 4 : 5"), |
| njs_str("4") }, |
| |
| { njs_str("0 ? 2 ? 3 : 4 : 5"), |
| njs_str("5") }, |
| |
| { njs_str("1 ? 2 ? 3 : 4 : 5"), |
| njs_str("3") }, |
| |
| { njs_str("1 ? 0 ? 3 : 4 : 5"), |
| njs_str("4") }, |
| |
| { njs_str("(1 ? 0 : 3) ? 4 : 5"), |
| njs_str("5") }, |
| |
| { njs_str("var a; a = (1 + 2) ? 2 ? 3 + 4 : 5 : 6"), |
| njs_str("7") }, |
| |
| { njs_str("var a; a = (1 ? 2 : 3) + 4"), |
| njs_str("6") }, |
| |
| { njs_str("var a, b; a = 1 ? b = 2 + 4 : b = 3"), |
| njs_str("6") }, |
| |
| { njs_str("var a; a = 1 ? [1,2] : []"), |
| njs_str("1,2") }, |
| |
| /**/ |
| |
| { njs_str("var a = { valueOf: function() { return 1 } }; +a"), |
| njs_str("1") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } }; +a"), |
| njs_str("1") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1 } }; -a"), |
| njs_str("-1") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } }; -a"), |
| njs_str("-1") }, |
| |
| /* Increment. */ |
| |
| { njs_str("var a = 1; ++a"), |
| njs_str("2") }, |
| |
| { njs_str("var a = '1'; ++a"), |
| njs_str("2") }, |
| |
| { njs_str("var a = [1]; ++a"), |
| njs_str("2") }, |
| |
| { njs_str("var a = {}; ++a"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = [1,2,3]; var b = 1; b = ++a[b]; b + ' '+ a"), |
| njs_str("3 1,3,3") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1 } };" |
| "++a +' '+ a +' '+ typeof a"), |
| njs_str("2 2 number") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } };" |
| "++a +' '+ a +' '+ typeof a"), |
| njs_str("2 2 number") }, |
| |
| { njs_str("var a = { valueOf: function() { return [1] } };" |
| "++a +' '+ a +' '+ typeof a"), |
| njs_str("NaN NaN number") }, |
| |
| { njs_str("var a = { valueOf: function() { return {} } };" |
| "++a +' '+ a +' '+ typeof a"), |
| njs_str("NaN NaN number") }, |
| |
| /**/ |
| |
| { njs_str("var a = 1; a = ++a"), |
| njs_str("2") }, |
| |
| { njs_str("var a = '1'; a = ++a"), |
| njs_str("2") }, |
| |
| { njs_str("var a = [1]; a = ++a"), |
| njs_str("2") }, |
| |
| { njs_str("var a = {}; a = ++a"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1 } }; a = ++a"), |
| njs_str("2") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } }; a = ++a"), |
| njs_str("2") }, |
| |
| { njs_str("var a = { valueOf: function() { return [1] } }; a = ++a"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return {} } }; a = ++a"), |
| njs_str("NaN") }, |
| |
| /**/ |
| |
| { njs_str("var a = 1; var b = ++a; a +' '+ b"), |
| njs_str("2 2") }, |
| |
| { njs_str("var a = '1'; var b = ++a; a +' '+ b"), |
| njs_str("2 2") }, |
| |
| { njs_str("var a = [1]; var b = ++a; a +' '+ b"), |
| njs_str("2 2") }, |
| |
| { njs_str("var a = {}; var b = ++a; a +' '+ b"), |
| njs_str("NaN NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1 } };" |
| "var b = ++a; a +' '+ b"), |
| njs_str("2 2") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } };" |
| "var b = ++a; a +' '+ b"), |
| njs_str("2 2") }, |
| |
| { njs_str("var a = { valueOf: function() { return [1] } };" |
| "var b = ++a; a +' '+ b"), |
| njs_str("NaN NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return {} } };" |
| "var b = ++a; a +' '+ b"), |
| njs_str("NaN NaN") }, |
| |
| { njs_str("var a = 0; a = a + ++a; a"), |
| njs_str("1") }, |
| |
| { njs_str("var a = 0; a += a + ++a; a"), |
| njs_str("1") }, |
| |
| { njs_str("var i = 0, arr = ['a', 'b'];" |
| "arr[i] = arr[i] + arr[++i]; arr"), |
| njs_str("ab,b") }, |
| |
| { njs_str("var i = 0, arr = ['a', 'b'];" |
| "arr[i] += arr[i] + arr[++i]; arr"), |
| njs_str("aab,b") }, |
| |
| /* Post increment. */ |
| |
| { njs_str("var a = 1; a++"), |
| njs_str("1") }, |
| |
| { njs_str("var a = '1'; a++"), |
| njs_str("1") }, |
| |
| { njs_str("var a = [1]; a++"), |
| njs_str("1") }, |
| |
| { njs_str("var a = {}; a++"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1 } }; a++"), |
| njs_str("1") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } }; a++"), |
| njs_str("1") }, |
| |
| { njs_str("var a = { valueOf: function() { return [1] } }; a++"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return {} } }; a++"), |
| njs_str("NaN") }, |
| |
| /**/ |
| |
| { njs_str("var a = 1; a = a++"), |
| njs_str("1") }, |
| |
| { njs_str("var a = '1'; a = a++"), |
| njs_str("1") }, |
| |
| { njs_str("var a = [1]; a = a++"), |
| njs_str("1") }, |
| |
| { njs_str("var a = {}; a = a++"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1 } }; a = a++"), |
| njs_str("1") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } }; a = a++"), |
| njs_str("1") }, |
| |
| { njs_str("var a = { valueOf: function() { return [1] } }; a = a++"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return {} } }; a = a++"), |
| njs_str("NaN") }, |
| |
| /**/ |
| |
| { njs_str("var a = 1; var b = a++; a +' '+ b"), |
| njs_str("2 1") }, |
| |
| { njs_str("var a = '1'; var b = a++; a +' '+ b"), |
| njs_str("2 1") }, |
| |
| { njs_str("var a = [1]; var b = a++; a +' '+ b"), |
| njs_str("2 1") }, |
| |
| { njs_str("var a = {}; var b = a++; a +' '+ b"), |
| njs_str("NaN NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1 } };" |
| "var b = a++; a +' '+ b"), |
| njs_str("2 1") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } };" |
| "var b = a++; a +' '+ b"), |
| njs_str("2 1") }, |
| |
| { njs_str("var a = { valueOf: function() { return [1] } };" |
| "var b = a++; a +' '+ b"), |
| njs_str("NaN NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return {} } };" |
| "var b = a++; a +' '+ b"), |
| njs_str("NaN NaN") }, |
| |
| { njs_str("var a = 0; a = a + a++; a"), |
| njs_str("0") }, |
| |
| { njs_str("var a = 0; a += a + a++; a"), |
| njs_str("0") }, |
| |
| { njs_str("var i = 1, arr = ['a', 'b'];" |
| "arr[i] = arr[i] + arr[i++]; arr"), |
| njs_str("a,bb") }, |
| |
| { njs_str("var i = 1, arr = ['a', 'b'];" |
| "arr[i] += arr[i] + arr[i++]; arr"), |
| njs_str("a,bbb") }, |
| |
| /* Decrement. */ |
| |
| { njs_str("var a = 1; --a"), |
| njs_str("0") }, |
| |
| { njs_str("var a = '1'; --a"), |
| njs_str("0") }, |
| |
| { njs_str("var a = [1]; --a"), |
| njs_str("0") }, |
| |
| { njs_str("var a = {}; --a"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1} }; --a"), |
| njs_str("0") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1'} }; --a"), |
| njs_str("0") }, |
| |
| { njs_str("var a = { valueOf: function() { return [1]} }; --a"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return {} } }; --a"), |
| njs_str("NaN") }, |
| |
| /**/ |
| |
| { njs_str("var a = 1; a = --a"), |
| njs_str("0") }, |
| |
| { njs_str("var a = '1'; a = --a"), |
| njs_str("0") }, |
| |
| { njs_str("var a = [1]; a = --a"), |
| njs_str("0") }, |
| |
| { njs_str("var a = {}; a = --a"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1} }; a = --a"), |
| njs_str("0") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1'} }; a = --a"), |
| njs_str("0") }, |
| |
| { njs_str("var a = { valueOf: function() { return [1]} }; a = --a"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return {} } }; a = --a"), |
| njs_str("NaN") }, |
| |
| /**/ |
| |
| { njs_str("var a = 1; var b = --a; a +' '+ b"), |
| njs_str("0 0") }, |
| |
| { njs_str("var a = '1'; var b = --a; a +' '+ b"), |
| njs_str("0 0") }, |
| |
| { njs_str("var a = [1]; var b = --a; a +' '+ b"), |
| njs_str("0 0") }, |
| |
| { njs_str("var a = {}; var b = --a; a +' '+ b"), |
| njs_str("NaN NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1 } };" |
| "var b = --a; a +' '+ b"), |
| njs_str("0 0") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } };" |
| "var b = --a; a +' '+ b"), |
| njs_str("0 0") }, |
| |
| { njs_str("var a = { valueOf: function() { return [1] } };" |
| "var b = --a; a +' '+ b"), |
| njs_str("NaN NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return {} } };" |
| "var b = --a; a +' '+ b"), |
| njs_str("NaN NaN") }, |
| |
| { njs_str("var a = 0; a = a + --a; a"), |
| njs_str("-1") }, |
| |
| { njs_str("var a = 0; a -= a + --a; a"), |
| njs_str("1") }, |
| |
| { njs_str("var i = 1, arr = ['a', 'b'];" |
| "arr[i] = arr[i] + arr[--i]; arr"), |
| njs_str("a,ba") }, |
| |
| { njs_str("var i = 1, arr = ['a', 'b'];" |
| "arr[i] += arr[i] + arr[--i]; arr"), |
| njs_str("a,bba") }, |
| |
| /* Post decrement. */ |
| |
| { njs_str("var a = 1; a--"), |
| njs_str("1") }, |
| |
| { njs_str("var a = '1'; a--"), |
| njs_str("1") }, |
| |
| { njs_str("var a = [1]; a--"), |
| njs_str("1") }, |
| |
| { njs_str("var a = {}; a--"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1 } }; a--"), |
| njs_str("1") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } }; a--"), |
| njs_str("1") }, |
| |
| { njs_str("var a = { valueOf: function() { return [1] } }; a--"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return {} } }; a--"), |
| njs_str("NaN") }, |
| |
| /**/ |
| |
| { njs_str("var a = 1; a = a--"), |
| njs_str("1") }, |
| |
| { njs_str("var a = '1'; a = a--"), |
| njs_str("1") }, |
| |
| { njs_str("var a = [1]; a = a--"), |
| njs_str("1") }, |
| |
| { njs_str("var a = {}; a = a--"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1 } }; a = a--"), |
| njs_str("1") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } }; a = a--"), |
| njs_str("1") }, |
| |
| { njs_str("var a = { valueOf: function() { return [1] } }; a = a--"), |
| njs_str("NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return {} } }; a = a--"), |
| njs_str("NaN") }, |
| |
| /**/ |
| |
| { njs_str("var a = 1; var b = a--; a +' '+ b"), |
| njs_str("0 1") }, |
| |
| { njs_str("var a = '1'; var b = a--; a +' '+ b"), |
| njs_str("0 1") }, |
| |
| { njs_str("var a = [1]; var b = a--; a +' '+ b"), |
| njs_str("0 1") }, |
| |
| { njs_str("var a = {}; var b = a--; a +' '+ b"), |
| njs_str("NaN NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return 1 } };" |
| "var b = a--; a +' '+ b"), |
| njs_str("0 1") }, |
| |
| { njs_str("var a = { valueOf: function() { return '1' } };" |
| "var b = a--; a +' '+ b"), |
| njs_str("0 1") }, |
| |
| { njs_str("var a = { valueOf: function() { return [1] } };" |
| "var b = a--; a +' '+ b"), |
| njs_str("NaN NaN") }, |
| |
| { njs_str("var a = { valueOf: function() { return {} } };" |
| "var b = a--; a +' '+ b"), |
| njs_str("NaN NaN") }, |
| |
| { njs_str("var a = 0; a = a + a--; a"), |
| njs_str("0") }, |
| |
| { njs_str("var a = 0; a += a + a--; a"), |
| njs_str("0") }, |
| |
| { njs_str("var i = 1, arr = ['a', 'b'];" |
| "arr[i] = arr[i] + arr[i--]; arr"), |
| njs_str("a,bb") }, |
| |
| { njs_str("var i = 1, arr = ['a', 'b'];" |
| "arr[i] += arr[i] + arr[i--]; arr"), |
| njs_str("a,bbb") }, |
| |
| /**/ |
| |
| { njs_str("var a, b; a = 2; b = ++a + ++a; a + ' ' + b"), |
| njs_str("4 7") }, |
| |
| { njs_str("var a, b; a = 2; b = a++ + a++; a + ' ' + b"), |
| njs_str("4 5") }, |
| |
| { njs_str("var a, b; a = b = 7; a +' '+ b"), |
| njs_str("7 7") }, |
| |
| { njs_str("var a, b, c; a = b = c = 5; a +' '+ b +' '+ c"), |
| njs_str("5 5 5") }, |
| |
| { njs_str("var a, b, c; a = b = (c = 5) + 2; a +' '+ b +' '+ c"), |
| njs_str("7 7 5") }, |
| |
| { njs_str("1, 2 + 5, 3"), |
| njs_str("3") }, |
| |
| { njs_str("var a, b; a = 1 /* YES */\n b = a + 2 \n \n + 1 \n + 3"), |
| njs_str("7") }, |
| |
| { njs_str("var a, b; a = 1 // YES \n b = a + 2 \n \n + 1 \n + 3"), |
| njs_str("7") }, |
| |
| { njs_str("var a; a = 0; ++ \n a"), |
| njs_str("1") }, |
| |
| { njs_str("var a; a = 0\n ++a"), |
| njs_str("1") }, |
| |
| { njs_str("a = 0; a \n ++"), |
| njs_str("SyntaxError: Unexpected end of input in 2") }, |
| |
| { njs_str("a = 0; a \n --"), |
| njs_str("SyntaxError: Unexpected end of input in 2") }, |
| |
| { njs_str("var a = 0; a \n + 1"), |
| njs_str("1") }, |
| |
| { njs_str("var a = 0; a \n +\n 1"), |
| njs_str("1") }, |
| |
| { njs_str("var a; a = 1 ? 2 \n : 3"), |
| njs_str("2") }, |
| |
| { njs_str("var a, b, c;" |
| "a = 0 / 0; b = 1 / 0; c = -1 / 0; a +' '+ b +' '+ c"), |
| njs_str("NaN Infinity -Infinity") }, |
| |
| { njs_str("var a, b; a = (b = 7) + 5; var c; a +' '+ b +' '+ c"), |
| njs_str("12 7 undefined") }, |
| |
| { njs_str("var a, b = 1, c; a +' '+ b +' '+ c"), |
| njs_str("undefined 1 undefined") }, |
| |
| { njs_str("var a = 1, b = a + 1; a +' '+ b"), |
| njs_str("1 2") }, |
| |
| { njs_str("var a; a = a = 1"), |
| njs_str("1") }, |
| |
| { njs_str("var a = 1, \n b; a +' '+ b"), |
| njs_str("1 undefined") }, |
| |
| { njs_str("var a; a = b + 1; var b; a +' '+ b"), |
| njs_str("NaN undefined") }, |
| |
| { njs_str("var a += 1"), |
| njs_str("SyntaxError: Unexpected token \"+=\" in 1") }, |
| |
| { njs_str("var a = a + 1"), |
| njs_str("undefined") }, |
| |
| { njs_str("var a; a = b + 1; var b = 1; a +' '+ b"), |
| njs_str("NaN 1") }, |
| |
| { njs_str("var a; (a) = 1"), |
| njs_str("1") }, |
| |
| { njs_str("a"), |
| njs_str("ReferenceError: \"a\" is not defined") }, |
| |
| { njs_str("\na"), |
| njs_str("ReferenceError: \"a\" is not defined") }, |
| |
| { njs_str("\n\na"), |
| njs_str("ReferenceError: \"a\" is not defined") }, |
| |
| { njs_str("a + a"), |
| njs_str("ReferenceError: \"a\" is not defined") }, |
| |
| { njs_str("a = b + 1"), |
| njs_str("ReferenceError: \"a\" is not defined") }, |
| |
| { njs_str("a = a + 1"), |
| njs_str("ReferenceError: \"a\" is not defined") }, |
| |
| { njs_str("a += 1"), |
| njs_str("ReferenceError: \"a\" is not defined") }, |
| |
| { njs_str("a += 1; var a = 2"), |
| njs_str("undefined") }, |
| |
| { njs_str("var a = 1"), |
| njs_str("undefined") }, |
| |
| { njs_str("var a = 1; a = (a = 2) + a"), |
| njs_str("4") }, |
| |
| { njs_str("var a = 1; a = a + (a = 2)"), |
| njs_str("3") }, |
| |
| { njs_str("var a = 1; a += (a = 2)"), |
| njs_str("3") }, |
| |
| { njs_str("var a = b = 1; var b; a +' '+ b"), |
| njs_str("1 1") }, |
| |
| { njs_str("var a \n if (!a) a = 3; a"), |
| njs_str("3") }, |
| |
| /* automatic semicolon insertion. */ |
| |
| { njs_str("(a\n--"), |
| njs_str("SyntaxError: Unexpected token \"--\" in 2") }, |
| |
| { njs_str("(a\n++"), |
| njs_str("SyntaxError: Unexpected token \"++\" in 2") }, |
| |
| { njs_str("var x = 0, y = 2; x\n--\ny; [x,y]"), |
| njs_str("0,1") }, |
| |
| { njs_str("function f() {return\n}"), |
| njs_str("undefined") }, |
| |
| /* if. */ |
| |
| { njs_str("if (0);"), |
| njs_str("undefined") }, |
| |
| { njs_str("if (0) {}"), |
| njs_str("undefined") }, |
| |
| { njs_str("if (0);else;"), |
| njs_str("undefined") }, |
| |
| { njs_str("var a = 1; if (true); else a = 2; a"), |
| njs_str("1") }, |
| |
| { njs_str("var a = 1; if (false); else a = 2; a"), |
| njs_str("2") }, |
| |
| { njs_str("var a = 1; if (true) a = 2; else a = 3; a"), |
| njs_str("2") }, |
| |
| { njs_str("var a = 3; if (true) if (false); else a = 2; a"), |
| njs_str("2") }, |
| |
| { njs_str("var a = 3; if (true) if (false); else; a = 2; a"), |
| njs_str("2") }, |
| |
| { njs_str("var a = [3], b; if (1==1||2==2) { b = '1'+'2'+a[0] }; b"), |
| njs_str("123") }, |
| |
| { njs_str("(function(){ if(true) return 1 else return 0; })()"), |
| njs_str("SyntaxError: Unexpected token \"else\" in 1") }, |
| |
| { njs_str("(function(){ if(true) return 1; else return 0; })()"), |
| njs_str("1") }, |
| |
| { njs_str("(function(){ if(true) return 1;; else return 0; })()"), |
| njs_str("SyntaxError: Unexpected token \"else\" in 1") }, |
| |
| { njs_str("(function(){ if(true) return 1\n else return 0; })()"), |
| njs_str("1") }, |
| |
| { njs_str("(function(){ if(true) return 1\n;\n else return 0; })()"), |
| njs_str("1") }, |
| |
| { njs_str("function f(n) {if (n) throw 'foo' else return 1}; f(0)"), |
| njs_str("SyntaxError: Unexpected token \"else\" in 1") }, |
| |
| { njs_str("function f(n) {if (n)\n throw 'foo'\nelse return 1}; f(0)"), |
| njs_str("1") }, |
| |
| { njs_str("function f(n) {if (n)\n throw 'foo'\nelse return 1}; f(1)"), |
| njs_str("foo") }, |
| |
| { njs_str("function f(n) {if (n == 1) throw 'foo'\nelse if (n == 2) return 1}; f(2)"), |
| njs_str("1") }, |
| |
| { njs_str("(function(){ for (var p in [1] ){ if (1) break else return 0; }})()"), |
| njs_str("SyntaxError: Unexpected token \"else\" in 1") }, |
| |
| { njs_str("(function(){ for (var p in [1] ){ if (1) break\n else return 0; }})()"), |
| njs_str("undefined") }, |
| |
| { njs_str("(function(){ for (var p in [1] ){ if (1) break; else return 0; }})()"), |
| njs_str("undefined") }, |
| |
| { njs_str("(function(){ for (var p in [1] ){ if (1) continue else return 0; }})()"), |
| njs_str("SyntaxError: Unexpected token \"else\" in 1") }, |
| |
| { njs_str("(function(){ for (var p in [1] ){ if (1) continue\n else return 0; }})()"), |
| njs_str("undefined") }, |
| |
| { njs_str("(function(){ for (var p in [1] ){ if (1) continue; else return 0; }})()"), |
| njs_str("undefined") }, |
| |
| { njs_str("(function(x){ if\n(x) return -1; else return 0; })(0)"), |
| njs_str("0") }, |
| |
| { njs_str("(function(x){ if\n(\nx) return -1; else return 0; })(0)"), |
| njs_str("0") }, |
| |
| { njs_str("(function(x){ if\n(\nx)\nreturn -1; else return 0; })(0)"), |
| njs_str("0") }, |
| |
| { njs_str("(function(x){ if\n(\nx)\nreturn -1\n else return 0; })(0)"), |
| njs_str("0") }, |
| |
| { njs_str("(function(x){ if\n(\nx)\nreturn -1\n else\nreturn 0; })(0)"), |
| njs_str("0") }, |
| |
| /* do while. */ |
| |
| { njs_str("do { break } if (false)"), |
| njs_str("SyntaxError: Unexpected token \"if\" in 1") }, |
| |
| /* for in. */ |
| |
| { njs_str("for (null in undefined);"), |
| njs_str("ReferenceError: Invalid left-hand side \"null\" in for-in statement in 1") }, |
| |
| { njs_str("for (var a, b in []);"), |
| njs_str("SyntaxError: Unexpected token \"in\" in 1") }, |
| |
| { njs_str("var s = ''; for (var p in [1,2]) {s += p}; s"), |
| njs_str("01") }, |
| |
| { njs_str("var s; for (var p in [1]) {s = typeof(p)}; s"), |
| njs_str("string") }, |
| |
| { njs_str("var s = ''; for (var p in {a:1, b:2}) {s += p}; s"), |
| njs_str("ab") }, |
| |
| { njs_str("var s = '';" |
| "var o = Object.defineProperty({}, 'x', {value:1});" |
| "Object.defineProperty(o, 'y', {value:2, enumerable:true});" |
| "for (var p in o) {s += p}; s"), |
| njs_str("y") }, |
| |
| { njs_str("var o = {a:1, b:2}; var arr = []; " |
| "for (var a in o) {arr.push(a)}; arr"), |
| njs_str("a,b") }, |
| |
| { njs_str("var o = {a:1, b:2}; var arr = []; delete o.a; " |
| "for (var a in o) {arr.push(a)}; arr"), |
| njs_str("b") }, |
| |
| { njs_str("var a = []; for (var k in new Uint8Array([1,2,3])) { a.push(k); }; a"), |
| njs_str("0,1,2") }, |
| |
| /* switch. */ |
| |
| { njs_str("switch"), |
| njs_str("SyntaxError: Unexpected end of input in 1") }, |
| |
| { njs_str("switch (1);"), |
| njs_str("SyntaxError: Unexpected token \";\" in 1") }, |
| |
| { njs_str("switch (1) { do { } while (1) }"), |
| njs_str("SyntaxError: Unexpected token \"do\" in 1") }, |
| |
| { njs_str("switch (1) {}"), |
| njs_str("undefined") }, |
| |
| { njs_str("switch (1) {default:}"), |
| njs_str("undefined") }, |
| |
| { njs_str("switch (1) {case 0:}"), |
| njs_str("undefined") }, |
| |
| { njs_str("switch (1) {default:;}"), |
| njs_str("undefined") }, |
| |
| { njs_str("switch (1) {default:; default:}"), |
| njs_str("SyntaxError: More than one default clause in switch statement in 1") }, |
| |
| { njs_str("switch (1) {case 0:;}"), |
| njs_str("undefined") }, |
| |
| { njs_str("var a = 'A'; switch (a) {" |
| "case 0: a += '0';" |
| "case 1: a += '1';" |
| "}; a"), |
| njs_str("A") }, |
| |
| { njs_str("var a = 'A'; switch (0) {" |
| "case 0: a += '0';" |
| "case 1: a += '1';" |
| "}; a"), |
| njs_str("A01") }, |
| |
| { njs_str("var a = 'A'; switch (0) {" |
| "case 0: a += '0'; break;" |
| "case 1: a += '1';" |
| "}; a"), |
| njs_str("A0") }, |
| |
| { njs_str("var a = 'A'; switch (1) {" |
| "case 0: a += '0';" |
| "case 1: a += '1';" |
| "}; a"), |
| njs_str("A1") }, |
| |
| { njs_str("var a = 'A'; switch (2) {" |
| "case 0: a += '0';" |
| "case 1: a += '1';" |
| "default: a += 'D';" |
| "}; a"), |
| njs_str("AD") }, |
| |
| { njs_str("var a = 'A'; switch (2) {" |
| "case 0: a += '0';" |
| "default: a += 'D';" |
| "case 1: a += '1';" |
| "}; a"), |
| njs_str("AD1") }, |
| |
| { njs_str("var a = 'A'; function f(x) { a += x; return 0 }" |
| "switch (a) {" |
| "case f(1):" |
| "default:" |
| "case f(2): a += 'D';" |
| "case f(3): a += 'T';" |
| "} a"), |
| njs_str("A123DT") }, |
| |
| { njs_str("[isNaN, undefined, isFinite]." |
| "map((v)=>{switch(v) { case isNaN: return 1; default: return 0;}})"), |
| njs_str("1,0,0") }, |
| |
| { njs_str("switch (1) {case 1: ii > 1; ii => default:}"), |
| njs_str("SyntaxError: Unexpected token \"default\" in 1") }, |
| |
| { njs_str("switch (1) {case 1: ii > 1; var a = functin () {default:}"), |
| njs_str("SyntaxError: Unexpected token \"{\" in 1") }, |
| |
| { njs_str("switch (1) {default: ii > 1; ii => case 2:}"), |
| njs_str("SyntaxError: Unexpected token \"case\" in 1") }, |
| |
| { njs_str("switch (1) {default: ii > 1; var a = functin () {case 2:}"), |
| njs_str("SyntaxError: Unexpected token \"{\" in 1") }, |
| |
| { njs_str("switch (1) {case 1: ii > 1; ii => case 2:}"), |
| njs_str("SyntaxError: Unexpected token \"case\" in 1") }, |
| |
| { njs_str("switch (1) {case 1: ii > 1; var a = functin () {case 2:}"), |
| njs_str("SyntaxError: Unexpected token \"{\" in 1") }, |
| |
| /* continue. */ |
| |
| { njs_str("continue"), |
| njs_str("SyntaxError: Illegal continue statement in 1") }, |
| |
| { njs_str("\n{\ncontinue;\n}"), |
| njs_str("SyntaxError: Illegal continue statement in 3") }, |
| |
| { njs_str("do continue while (false)"), |
| njs_str("SyntaxError: Unexpected token \"while\" in 1") }, |
| |
| { njs_str("do continue; while (false)"), |
| njs_str("undefined") }, |
| |
| { njs_str("do { continue } while (false)"), |
| njs_str("undefined") }, |
| |
| { njs_str("var i = 0; do if (i++ > 9) continue; while (i < 100); i"), |
| njs_str("100") }, |
| |
| { njs_str("while (false) continue"), |
| njs_str("undefined") }, |
| |
| { njs_str("while (false) continue;"), |
| njs_str("undefined") }, |
| |
| { njs_str("while (false) { continue }"), |
| njs_str("undefined") }, |
| |
| { njs_str("var i = 0; while (i < 100) if (i++ > 9) continue; i"), |
| njs_str("100") }, |
| |
| { njs_str("for ( ;null; ) continue"), |
| njs_str("undefined") }, |
| |
| { njs_str("for ( ;null; ) continue;"), |
| njs_str("undefined") }, |
| |
| { njs_str("for ( ;null; ) { continue }"), |
| njs_str("undefined") }, |
| |
| { njs_str("var i; for (i = 0; i < 100; i++) if (i > 9) continue; i"), |
| njs_str("100") }, |
| |
| { njs_str("var a = [], i; for (i in a) continue"), |
| njs_str("undefined") }, |
| |
| { njs_str("var a = [], i; for (i in a) continue;"), |
| njs_str("undefined") }, |
| |
| { njs_str("var a = [], i; for (i in a) { continue }"), |
| njs_str("undefined") }, |
| |
| { njs_str("var a = [1,2,3,4,5]; var s = 0, i;" |
| "for (i in a) { if (a[i] > 4) continue; else s += a[i] } s"), |
| njs_str("10") }, |
| |
| { njs_str("var a = [1,2,3,4,5]; var s = 0, i;" |
| "for (i in a) { if (a[i] > 4) continue; s += a[i] } s"), |
| njs_str("10") }, |
| |
| { njs_str("var a; for (a = 1; a; a--) switch (a) { case 0: continue }"), |
| njs_str("undefined") }, |
| |
| { njs_str("var a = [1,2,3], i; for (i in a) {Object.seal({})}"), |
| njs_str("undefined") }, |
| |
| { njs_str("var i; for (i in [1,2,3]) {Object.seal({});}"), |
| njs_str("undefined") }, |
| |
| { njs_str("while (0) {continue\n}"), |
| njs_str("undefined") }, |
| |
| /* break. */ |
| |
| { njs_str("break"), |
| njs_str("SyntaxError: Illegal break statement in 1") }, |
| |
| { njs_str("{break}"), |
| njs_str("SyntaxError: Illegal break statement in 1") }, |
| |
| { njs_str("\nbreak"), |
| njs_str("SyntaxError: Illegal break statement in 2") }, |
| |
| { njs_str("do break while (true)"), |
| njs_str("SyntaxError: Unexpected token \"while\" in 1") }, |
| |
| { njs_str("do break; while (true)"), |
| njs_str("undefined") }, |
| |
| { njs_str("do { break } while (true)"), |
| njs_str("undefined") }, |
| |
| { njs_str("var i = 0; do if (i++ > 9) break; while (i < 100); i"), |
| njs_str("11") }, |
| |
| { njs_str("while (true) break"), |
| njs_str("undefined") }, |
| |
| { njs_str("while (true) break;"), |
| njs_str("undefined") }, |
| |
| { njs_str("while (true) { break }"), |
| njs_str("undefined") }, |
| |
| { njs_str("var i = 0; while (i < 100) if (i++ > 9) break; i"), |
| njs_str("11") }, |
| |
| { njs_str("for ( ;; ) break"), |
| njs_str("undefined") }, |
| |
| { njs_str("for ( ;; ) break;"), |
| njs_str("undefined") }, |
| |
| { njs_str("for ( ;; ) { break }"), |
| njs_str("undefined") }, |
| |
| { njs_str("var i; for (i = 0; i < 100; i++) if (i > 9) break; i"), |
| njs_str("10") }, |
| |
| { njs_str("var a = [], i; for (i in a) break"), |
| njs_str("undefined") }, |
| |
| { njs_str("var a = [], i; for (i in a) break;"), |
| njs_str("undefined") }, |
| |
| { njs_str("var a = [], i; for (i in a) { break }"), |
| njs_str("undefined") }, |
| |
| { njs_str("var a = [1,2,3,4,5]; var s = 0, i;" |
| "for (i in a) { if (a[i] > 4) break; else s += a[i] } s"), |
| njs_str("10") }, |
| |
| { njs_str("var a = [1,2,3,4,5]; var s = 0, i;" |
| "for (i in a) { if (a[i] > 4) break; s += a[i] } s"), |
| njs_str("10") }, |
| |
| { njs_str("var a = [1,2,3,4,5]; var s = 0, i;" |
| "for (i in a) if (a[i] > 4) break; s += a[i]; s"), |
| njs_str("5") }, |
| |
| { njs_str("while (0) {break\n}"), |
| njs_str("undefined") }, |
| |
| /* Labels. */ |
| |
| { njs_str("var n = 0; a:{n++}; a:{n++}; n"), |
| njs_str("2") }, |
| |
| { njs_str("a: throw 'a'"), |
| njs_str("a") }, |
| |
| { njs_str("a\n:\n1"), |
| njs_str("1") }, |
| |
| { njs_str("a\n\n:1"), |
| njs_str("1") }, |
| |
| { njs_str("a:\n\n1"), |
| njs_str("1") }, |
| |
| { njs_str("a:\n\n"), |
| njs_str("SyntaxError: Unexpected end of input in 3") }, |
| |
| { njs_str("a : var n = 0; b :++n"), |
| njs_str("1") }, |
| |
| { njs_str("a:{a:1}"), |
| njs_str("SyntaxError: Label \"a\" has already been declared in 1") }, |
| |
| { njs_str("for (var i in [1]) {break b}"), |
| njs_str("SyntaxError: Undefined label \"b\" in 1") }, |
| |
| { njs_str("for (var i in [1]) {continue b}"), |
| njs_str("SyntaxError: Undefined label \"b\" in 1") }, |
| |
| { njs_str("a:{break b}"), |
| njs_str("SyntaxError: Undefined label \"b\" in 1") }, |
| |
| { njs_str("a:{continue b}"), |
| njs_str("SyntaxError: Undefined label \"b\" in 1") }, |
| |
| { njs_str("a:function name() {}"), |
| njs_str("SyntaxError: In strict mode code, functions can only be declared at top level or inside a block.") }, |
| |
| #if 0 /* TODO */ |
| { njs_str("a:{1; break a}"), |
| njs_str("1") }, |
| #endif |
| |
| { njs_str("var a = 0; a:{a++}; a"), |
| njs_str("1") }, |
| |
| { njs_str("var a = 0; a:{break a; a++}; a"), |
| njs_str("0") }, |
| |
| { njs_str("var r = 0; " |
| "out: for (var i in [1,2,3]) { if (i == 2) {break out;}; r++}; r"), |
| njs_str("2") }, |
| |
| { njs_str("var r = 0; " |
| "out: for (var i = 0; i < 5; i++) { if (i == 2) {break out;}; r++}; r"), |
| njs_str("2") }, |
| |
| { njs_str("var l1 = 0, l2 = 0; " |
| "out: " |
| "for (var i in [1,2,3]) { " |
| " for (var j in [1,2,3]) { " |
| " if (i == 1 && j == 1) {break;}" |
| " l2++;" |
| " }" |
| " l1++;" |
| "}; [l1, l2]"), |
| njs_str("3,7") }, |
| |
| { njs_str("var l1 = 0, l2 = 0; " |
| "out: " |
| "for (var i in [1,2,3]) { " |
| " for (var j in [1,2,3]) { " |
| " if (i == 1 && j == 1) {break out;}" |
| " l2++;" |
| " }" |
| " l1++;" |
| "}; [l1, l2]"), |
| njs_str("1,4") }, |
| |
| { njs_str("var l1 = 0, l2 = 0; " |
| "out: " |
| "for (var i in [1,2,3]) { " |
| " for (var j in [1,2,3]) { " |
| " if (i == 1 && j == 1) {continue out;}" |
| " l2++;" |
| " }" |
| " l1++;" |
| "}; [l1, l2]"), |
| njs_str("2,7") }, |
| |
| { njs_str("var l1 = 0, l2 = 0; " |
| "out: " |
| "for (var i in [1,2,3]) { " |
| " l1++;" |
| " switch (i) { " |
| " case '1':" |
| " break out;" |
| " default:" |
| " }" |
| " l2++;" |
| "}; [l1, l2]"), |
| njs_str("2,1") }, |
| |
| { njs_str("var l1 = 0, l2 = 0; " |
| "out: " |
| "for (var i in [1,2,3]) { " |
| " l1++;" |
| " switch (i) { " |
| " case '1':" |
| " continue out;" |
| " default:" |
| " }" |
| " l2++;" |
| "}; [l1, l2]"), |
| njs_str("3,2") }, |
| |
| { njs_str("var l1 = 0, l2 = 0, i = 0, j; " |
| "out: " |
| "while (i < 3) { " |
| " j = 0;" |
| " while (j < 3) { " |
| " if (i == 1 && j == 1) {break out;}" |
| " l2++;" |
| " j++;" |
| " }" |
| " l1++;" |
| " i++;" |
| "}; [l1, l2]"), |
| njs_str("1,4") }, |
| |
| { njs_str("var l1 = 0, l2 = 0, i = 0, j; " |
| "out: " |
| "while (i < 3) { " |
| " j = 0;" |
| " while (j < 3) { " |
| " if (i == 1 && j == 1) {i++; continue out;}" |
| " l2++;" |
| " j++;" |
| " }" |
| " l1++;" |
| " i++;" |
| "}; [l1, l2]"), |
| njs_str("2,7") }, |
| |
| { njs_str("var l1 = 0, l2 = 0, i = 0, j; " |
| "out: " |
| "do { " |
| " j = 0;" |
| " do { " |
| " if (i == 1 && j == 1) {break out;}" |
| " l2++;" |
| " j++;" |
| " } while (j < 3)" |
| " l1++;" |
| " i++;" |
| "} while (i < 3); [l1, l2]"), |
| njs_str("1,4") }, |
| |
| { njs_str("var l1 = 0, l2 = 0, i = 0, j; " |
| "out: " |
| "do { " |
| " j = 0;" |
| " do { " |
| " if (i == 1 && j == 1) {i++; continue out;}" |
| " l2++;" |
| " j++;" |
| " } while (j < 3)" |
| " l1++;" |
| " i++;" |
| "} while (i < 3); [l1, l2]"), |
| njs_str("2,7") }, |
| |
| { njs_str("out1: while (1) { out2: while (1) { " |
| " try { break out1; break out2; } catch (e) {}" |
| "}}"), |
| njs_str("InternalError: break/return instructions with different labels " |
| "(\"out1\" vs \"out2\") from try-catch block are not supported") }, |
| |
| { njs_str("out1: while (1) { out2: while (1) { " |
| " try { } catch (e) {break out1; break out2;} finally {}" |
| "}}"), |
| njs_str("InternalError: break/return instructions with different labels " |
| "(\"out1\" vs \"out2\") from try-catch block are not supported") }, |
| |
| { njs_str("out1: while (1) { out2: while (1) { " |
| " try { break out1; } catch (e) {break out2;} finally {}" |
| "}}"), |
| njs_str("InternalError: try break/return instructions with different labels " |
| "(\"out1\" vs \"out2\") from try-catch block are not supported") }, |
| |
| { njs_str("out1: while (1) { out2: while (1) { " |
| " try { break out1; break out2; } finally {}" |
| "}}"), |
| njs_str("InternalError: break/return instructions with different labels " |
| "(\"out1\" vs \"out2\") from try-catch block are not supported") }, |
| |
| { njs_str("out1: while (1) { out2: while (1) { " |
| " try { continue out1; continue out2; } catch (e) {}" |
| "}}"), |
| njs_str("InternalError: continue instructions with different labels " |
| "(\"out1\" vs \"out2\") from try-catch block are not supported") }, |
| |
| { njs_str("out1: while (1) { out2: while (1) { " |
| " try { continue out1; } catch (e) {continue out2;} finally {}" |
| "}}"), |
| njs_str("InternalError: try continue instructions with different labels " |
| "(\"out1\" vs \"out2\") from try-catch block are not supported") }, |
| |
|