diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2021-02-08 20:28:23 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-09 04:28:23 +0800 |
commit | e13d1e996909f68ee643df17fd7d87773c3e82a5 (patch) | |
tree | b519e7a0cd2c3150de25964aaa3399be135eaa7a /test | |
parent | aedc1e7fc9cab772734d559e149c0b4f70454321 (diff) | |
download | tracifyjs-e13d1e996909f68ee643df17fd7d87773c3e82a5.tar.gz tracifyjs-e13d1e996909f68ee643df17fd7d87773c3e82a5.zip |
support `for [await]...of` statements (#4627)
Diffstat (limited to 'test')
-rw-r--r-- | test/compress/loops.js | 15 | ||||
-rw-r--r-- | test/compress/yields.js | 42 | ||||
-rw-r--r-- | test/mocha/cli.js | 4 | ||||
-rw-r--r-- | test/reduce.js | 6 | ||||
-rw-r--r-- | test/ufuzz/index.js | 72 |
5 files changed, 118 insertions, 21 deletions
diff --git a/test/compress/loops.js b/test/compress/loops.js index a6d0277b..3217afd4 100644 --- a/test/compress/loops.js +++ b/test/compress/loops.js @@ -828,6 +828,21 @@ empty_for_in_prop_init: { ] } +for_of: { + input: { + var async = [ "PASS", 42 ]; + async.p = "FAIL"; + for (async of (null, async)) + console.log(async); + } + expect_exact: 'var async=["PASS",42];async.p="FAIL";for(async of(null,async))console.log(async);' + expect_stdout: [ + "PASS", + "42", + ] + node_version: ">=0.12" +} + issue_3631_1: { options = { dead_code: true, diff --git a/test/compress/yields.js b/test/compress/yields.js index 2d29c9b6..d799c194 100644 --- a/test/compress/yields.js +++ b/test/compress/yields.js @@ -96,6 +96,48 @@ pause_resume: { node_version: ">=4" } +for_of: { + input: { + function* f() { + if (yield "PASS") yield "FAIL 1"; + yield 42; + return "FAIL 2"; + } + for (var a of f()) + console.log(a); + } + expect_exact: 'function*f(){if(yield"PASS")yield"FAIL 1";yield 42;return"FAIL 2"}for(var a of f())console.log(a);' + expect_stdout: [ + "PASS", + "42", + ] + node_version: ">=4" +} + +for_await_of: { + input: { + async function* f() { + if (yield "PASS") yield "FAIL 1"; + yield { + then: function(r) { + r(42); + }, + }; + return "FAIL 2"; + } + (async function(a) { + for await (a of f()) + console.log(a); + })(); + } + expect_exact: 'async function*f(){if(yield"PASS")yield"FAIL 1";yield{then:function(r){r(42)}};return"FAIL 2"}(async function(a){for await(a of f())console.log(a)})();' + expect_stdout: [ + "PASS", + "42", + ] + node_version: ">=10" +} + collapse_vars_1: { options = { collapse_vars: true, diff --git a/test/mocha/cli.js b/test/mocha/cli.js index 475eae65..af1ed1f8 100644 --- a/test/mocha/cli.js +++ b/test/mocha/cli.js @@ -624,7 +624,7 @@ describe("bin/uglifyjs", function() { "Parse error at test/input/invalid/for-in_1.js:2,5", "for (1, 2, a in b) {", " ^", - "ERROR: Invalid left-hand side in for..in loop" + "ERROR: Invalid left-hand side in for..in/of loop" ].join("\n")); done(); }); @@ -638,7 +638,7 @@ describe("bin/uglifyjs", function() { "Parse error at test/input/invalid/for-in_2.js:2,5", "for (var a, b in c) {", " ^", - "ERROR: Only one variable declaration allowed in for..in loop" + "ERROR: Only one variable declaration allowed in for..in/of loop" ].join("\n")); done(); }); diff --git a/test/reduce.js b/test/reduce.js index bfc0c173..d5758ccc 100644 --- a/test/reduce.js +++ b/test/reduce.js @@ -134,8 +134,8 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options) if (parent instanceof U.AST_VarDef && parent.name === node) return; // preserve for (var xxx; ...) if (parent instanceof U.AST_For && parent.init === node && node instanceof U.AST_Definitions) return node; - // preserve for (xxx in ...) - if (parent instanceof U.AST_ForIn && parent.init === node) return node; + // preserve for (xxx in/of ...) + if (parent instanceof U.AST_ForEnumeration && parent.init === node) return node; // node specific permutations with no parent logic @@ -303,7 +303,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options) return to_statement(expr); } } - else if (node instanceof U.AST_ForIn) { + else if (node instanceof U.AST_ForEnumeration) { var expr; switch ((node.start._permute * steps | 0) % 3) { case 0: diff --git a/test/ufuzz/index.js b/test/ufuzz/index.js index cfe35afd..b4a26272 100644 --- a/test/ufuzz/index.js +++ b/test/ufuzz/index.js @@ -27,7 +27,7 @@ var STMT_IF_ELSE = STMT_("ifelse"); var STMT_DO_WHILE = STMT_("dowhile"); var STMT_WHILE = STMT_("while"); var STMT_FOR_LOOP = STMT_("forloop"); -var STMT_FOR_IN = STMT_("forin"); +var STMT_FOR_ENUM = STMT_("forenum"); var STMT_SEMI = STMT_("semi"); var STMT_EXPR = STMT_("expr"); var STMT_SWITCH = STMT_("switch"); @@ -142,6 +142,8 @@ var SUPPORT = function(matrix) { default_value: "[ a = 0 ] = [];", destructuring: "[] = [];", exponentiation: "0 ** 0", + for_await_of: "async function f(a) { for await (a of []); }", + for_of: "for (var a of []);", generator: "function* f(){}", let: "let a;", rest: "var [...a] = [];", @@ -901,21 +903,58 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn canBreak = label.break || enableLoopControl(canBreak, CAN_BREAK); canContinue = label.continue || enableLoopControl(canContinue, CAN_CONTINUE); return label.target + "for (var brake" + loop + " = 5; " + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + " && brake" + loop + " > 0; --brake" + loop + ")" + createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth); - case STMT_FOR_IN: + case STMT_FOR_ENUM: var label = createLabel(canBreak, canContinue); canBreak = label.break || enableLoopControl(canBreak, CAN_BREAK); canContinue = label.continue || enableLoopControl(canContinue, CAN_CONTINUE); var key = rng(10) ? "key" + loop : getVarName(NO_CONST); - return [ - "{var expr" + loop + " = " + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "; ", - label.target + " for (", - !/^key/.test(key) ? rng(10) ? "" : "var " : !SUPPORT.let || rng(10) ? "var " : rng(2) ? "let " : "const ", - !SUPPORT.destructuring || rng(10) ? key : rng(5) ? "[ " + key + " ]" : "{ length: " + key + " }", - " in expr" + loop + ") {", - rng(5) > 1 ? "c = 1 + c; var " + createVarName(MANDATORY) + " = expr" + loop + "[" + key + "]; " : "", - createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth), - "}}", - ].join(""); + var of = SUPPORT.for_of && rng(20) == 0; + var init = ""; + if (!/^key/.test(key)) { + if (!(of && bug_for_of_var) && rng(10) == 0) init = "var "; + } else if (!SUPPORT.let || !(of && bug_for_of_var) && rng(10)) { + init = "var "; + } else if (rng(2)) { + init = "let "; + } else { + init = "const "; + } + if (!SUPPORT.destructuring || of && !(canThrow && rng(10) == 0) || rng(10)) { + init += key; + } else if (rng(5)) { + init += "[ " + key + " ]"; + } else { + init += "{ length: " + key + " }"; + } + var s = "var expr" + loop + " = "; + if (of) { + var await = SUPPORT.for_await_of && async && rng(20) == 0; + if (SUPPORT.generator && rng(20) == 0) { + var gen = getVarName(); + if (canThrow && rng(10) == 0) { + s += gen + "; "; + } else { + s += gen + " && typeof " + gen + "[Symbol."; + s += await ? "asyncIterator" : "iterator"; + s += '] == "function" ? ' + gen + " : " + createArrayLiteral(recurmax, stmtDepth, canThrow) + "; "; + } + } else if (rng(5)) { + s += createArrayLiteral(recurmax, stmtDepth, canThrow) + "; "; + } else if (canThrow && rng(10) == 0) { + s += createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "; "; + } else { + s += '"" + (' + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "); "; + } + s += label.target + " for "; + if (await) s += "await "; + s += "(" + init + " of expr" + loop + ") {"; + } else { + s += createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "; "; + s += label.target + " for (" + init + " in expr" + loop + ") {"; + } + if (rng(3)) s += "c = 1 + c; var " + createVarName(MANDATORY) + " = expr" + loop + "[" + key + "]; "; + s += createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "}"; + return "{" + s + "}"; case STMT_SEMI: return use_strict && rng(20) === 0 ? '"use strict";' : ";"; case STMT_EXPR: @@ -2048,12 +2087,13 @@ if (typeof sandbox.run_code("A:if (0) B:; else B:;") != "string") { if (o.mangle) o.mangle.v8 = true; }); } -var is_bug_async_arrow_rest = function() {}; +var bug_async_arrow_rest = function() {}; if (SUPPORT.arrow && SUPPORT.async && SUPPORT.rest && typeof sandbox.run_code("async (a = f(...[], b)) => 0;") != "string") { - is_bug_async_arrow_rest = function(ex) { + bug_async_arrow_rest = function(ex) { return ex.name == "SyntaxError" && ex.message == "Rest parameter must be last formal parameter"; }; } +var bug_for_of_var = SUPPORT.for_of && SUPPORT.let && typeof sandbox.run_code("try {} catch (e) { for (var e of []); }") != "string"; if (SUPPORT.destructuring && typeof sandbox.run_code("console.log([ 1 ], {} = 2);") != "string") { beautify_options.output.v8 = true; minify_options.forEach(function(o) { @@ -2083,7 +2123,7 @@ for (var round = 1; round <= num_iterations; round++) { println(result); println(); // ignore v8 parser bug - return is_bug_async_arrow_rest(result); + return bug_async_arrow_rest(result); })) continue; minify_options.forEach(function(options) { var o = JSON.parse(options); @@ -2097,7 +2137,7 @@ for (var round = 1; round <= num_iterations; round++) { uglify_result = sandbox.run_code(uglify_code, toplevel); ok = sandbox.same_stdout(original_result, uglify_result); // ignore v8 parser bug - if (!ok && is_bug_async_arrow_rest(uglify_result)) ok = true; + if (!ok && bug_async_arrow_rest(uglify_result)) ok = true; // ignore declaration order of global variables if (!ok && !toplevel) { ok = sandbox.same_stdout(sandbox.run_code(sort_globals(original_code)), sandbox.run_code(sort_globals(uglify_code))); |