diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/compress/async.js | 218 | ||||
-rw-r--r-- | test/mocha/async.js | 23 | ||||
-rw-r--r-- | test/reduce.js | 2 | ||||
-rw-r--r-- | test/sandbox.js | 5 | ||||
-rw-r--r-- | test/ufuzz/index.js | 43 |
5 files changed, 276 insertions, 15 deletions
diff --git a/test/compress/async.js b/test/compress/async.js new file mode 100644 index 00000000..2e4698d2 --- /dev/null +++ b/test/compress/async.js @@ -0,0 +1,218 @@ +await_await: { + input: { + (async function() { + console.log("PASS"); + await await 42; + })(); + } + expect: { + (async function() { + console.log("PASS"); + await await 42; + })(); + } + expect_stdout: "PASS" + node_version: ">=8" +} + +defun_name: { + input: { + async function await() { + console.log("PASS"); + } + await(); + } + expect: { + async function await() { + console.log("PASS"); + } + await(); + } + expect_stdout: "PASS" + node_version: ">=8" +} + +nested_await: { + input: { + (async function() { + console.log(function(await) { + return await; + }("PASS")); + })(); + } + expect: { + (async function() { + console.log(function(await) { + return await; + }("PASS")); + })(); + } + expect_stdout: "PASS" + node_version: ">=8" +} + +reduce_single_use_defun: { + options = { + reduce_vars: true, + toplevel: true, + unused: true, + } + input: { + async function f(a) { + console.log(a); + } + f("PASS"); + } + expect: { + (async function(a) { + console.log(a); + })("PASS"); + } + expect_stdout: "PASS" + node_version: ">=8" +} + +dont_inline: { + options = { + inline: true, + } + input: { + (async function() { + A; + })().catch(function() {}); + console.log("PASS"); + } + expect: { + (async function() { + A; + })().catch(function() {}); + console.log("PASS"); + } + expect_stdout: "PASS" + node_version: ">=8" +} + +evaluate: { + options = { + evaluate: true, + reduce_vars: true, + toplevel: true, + unused: true, + } + input: { + var a = async function() {}(); + console.log(typeof a); + } + expect: { + var a = async function() {}(); + console.log(typeof a); + } + expect_stdout: "object" + node_version: ">=8" +} + +negate: { + options = { + side_effects: true, + } + input: { + console && async function() {} && console.log("PASS"); + } + expect: { + console && async function() {} && console.log("PASS"); + } + expect_stdout: "PASS" + node_version: ">=8" +} + +negate_iife: { + options = { + negate_iife: true, + } + input: { + (async function() { + console.log("PASS"); + })(); + } + expect: { + !async function() { + console.log("PASS"); + }(); + } + expect_stdout: "PASS" + node_version: ">=8" +} + +collapse_vars_1: { + options = { + collapse_vars: true, + } + input: { + var a = "FAIL"; + (async function() { + a = "PASS"; + await 42; + return "PASS"; + })(); + console.log(a); + } + expect: { + var a = "FAIL"; + (async function() { + a = "PASS"; + await 42; + return "PASS"; + })(); + console.log(a); + } + expect_stdout: "PASS" + node_version: ">=8" +} + +collapse_vars_2: { + options = { + collapse_vars: true, + } + input: { + var a = "FAIL"; + (async function() { + await (a = "PASS"); + return "PASS"; + })(); + console.log(a); + } + expect: { + var a = "FAIL"; + (async function() { + await (a = "PASS"); + return "PASS"; + })(); + console.log(a); + } + expect_stdout: "PASS" + node_version: ">=8" +} + +collapse_vars_3: { + options = { + collapse_vars: true, + } + input: { + var a = "FAIL"; + (async function() { + await (a = "PASS", 42); + return "PASS"; + })(); + console.log(a); + } + expect: { + var a = "FAIL"; + (async function() { + await (a = "PASS", 42); + return "PASS"; + })(); + console.log(a); + } + expect_stdout: "PASS" + node_version: ">=8" +} diff --git a/test/mocha/async.js b/test/mocha/async.js new file mode 100644 index 00000000..dc1aa2f4 --- /dev/null +++ b/test/mocha/async.js @@ -0,0 +1,23 @@ +var assert = require("assert"); +var UglifyJS = require("../node"); + +describe("async", function() { + it("Should reject `await` as symbol name within async functions only", function() { + [ + "function await() {}", + "function(await) {}", + "function() { await; }", + "function() { await:{} }", + "function() { var await; }", + "function() { function await() {} }", + "function() { try {} catch (await) {} }", + ].forEach(function(code) { + UglifyJS.parse("(" + code + ")();"); + assert.throws(function() { + UglifyJS.parse("(async " + code + ")();"); + }, function(e) { + return e instanceof UglifyJS.JS_Parse_Error; + }, code); + }); + }); +}); diff --git a/test/reduce.js b/test/reduce.js index cda79f8a..3cd7f67d 100644 --- a/test/reduce.js +++ b/test/reduce.js @@ -618,7 +618,7 @@ function is_timed_out(result) { } function is_statement(node) { - return node instanceof U.AST_Statement && !(node instanceof U.AST_Function); + return node instanceof U.AST_Statement && !(node instanceof U.AST_AsyncFunction || node instanceof U.AST_Function); } function merge_sequence(array, node) { diff --git a/test/sandbox.js b/test/sandbox.js index c1575783..46b1a410 100644 --- a/test/sandbox.js +++ b/test/sandbox.js @@ -32,11 +32,12 @@ function createContext() { function safe_log(arg, level) { if (arg) switch (typeof arg) { - case "function": + case "function": return arg.toString(); - case "object": + case "object": if (arg === global) return "[object global]"; if (/Error$/.test(arg.name)) return arg.toString(); + if (typeof arg.then == "function") return "[object Promise]"; arg.constructor.toString(); if (level--) for (var key in arg) { var desc = Object.getOwnPropertyDescriptor(arg, key); diff --git a/test/ufuzz/index.js b/test/ufuzz/index.js index 7c76b348..e47e5410 100644 --- a/test/ufuzz/index.js +++ b/test/ufuzz/index.js @@ -298,6 +298,8 @@ var VAR_NAMES = [ "arguments", "Math", "parseInt", + "async", + "await", ]; var INITIAL_NAMES_LEN = VAR_NAMES.length; @@ -317,6 +319,7 @@ var TYPEOF_OUTCOMES = [ var avoid_vars = []; var block_vars = []; var unique_vars = []; +var async = false; var loops = 0; var funcs = 0; var called = Object.create(null); @@ -335,6 +338,7 @@ function createTopLevelCode() { VAR_NAMES.length = INITIAL_NAMES_LEN; // prune any previous names still in the list block_vars.length = 0; unique_vars.length = 0; + async = false; loops = 0; funcs = 0; called = Object.create(null); @@ -393,7 +397,7 @@ function createArgs(recurmax, stmtDepth, canThrow) { return args.join(", "); } -function createAssignmentPairs(recurmax, noComma, stmtDepth, canThrow, varNames, maybe, dontStore) { +function createAssignmentPairs(recurmax, noComma, stmtDepth, canThrow, varNames, was_async) { var avoid = []; var len = unique_vars.length; var pairs = createPairs(recurmax); @@ -403,7 +407,10 @@ function createAssignmentPairs(recurmax, noComma, stmtDepth, canThrow, varNames, function createAssignmentValue(recurmax) { var current = VAR_NAMES; VAR_NAMES = (varNames || VAR_NAMES).slice(); + var save_async = async; + if (was_async != null) async = was_async; var value = varNames && rng(2) ? createValue() : createExpression(recurmax, noComma, stmtDepth, canThrow); + async = save_async; VAR_NAMES = current; return value; } @@ -429,7 +436,7 @@ function createAssignmentPairs(recurmax, noComma, stmtDepth, canThrow, varNames, } if (i < m) { unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity"); - var name = createVarName(maybe, dontStore); + var name = createVarName(MANDATORY); unique_vars.length -= 6; avoid.push(name); unique_vars.push(name); @@ -490,7 +497,7 @@ function createAssignmentPairs(recurmax, noComma, stmtDepth, canThrow, varNames, break; default: unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity"); - var name = createVarName(maybe, dontStore); + var name = createVarName(MANDATORY); unique_vars.length -= 6; avoid.push(name); unique_vars.push(name); @@ -572,12 +579,18 @@ function createBlockVariables(recurmax, stmtDepth, canThrow, fn) { } } +function makeFunction(name) { + return (async ? "async function " : "function ") + name; +} + function createFunction(recurmax, allowDefun, canThrow, stmtDepth) { if (--recurmax < 0) { return ";"; } if (!STMT_COUNT_FROM_GLOBAL) stmtDepth = 0; var s = []; var name, args; var varNames = VAR_NAMES.slice(); + var save_async = async; + async = rng(50) == 0; createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) { if (allowDefun || rng(5) > 0) { name = "f" + funcs++; @@ -589,13 +602,13 @@ function createFunction(recurmax, allowDefun, canThrow, stmtDepth) { var params; if ((!allowDefun || !(name in called)) && rng(2)) { called[name] = false; - var pairs = createAssignmentPairs(recurmax, COMMA_OK, stmtDepth, canThrow, varNames, MANDATORY); + var pairs = createAssignmentPairs(recurmax, COMMA_OK, stmtDepth, canThrow, varNames, save_async); params = pairs.names.join(", "); args = pairs.values.join(", "); } else { params = createParams(); } - s.push("function " + name + "(" + params + "){", strictMode()); + s.push(makeFunction(name) + "(" + params + "){", strictMode()); s.push(defns()); if (rng(5) === 0) { // functions with functions. lower the recursion to prevent a mess. @@ -607,6 +620,7 @@ function createFunction(recurmax, allowDefun, canThrow, stmtDepth) { s.push("}", ""); s = filterDirective(s).join("\n"); }); + async = save_async; VAR_NAMES = varNames; if (!allowDefun) { @@ -733,7 +747,7 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn return "switch (" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + ") { " + createSwitchParts(recurmax, 4, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + "}"; case STMT_VAR: if (!rng(20)) { - var pairs = createAssignmentPairs(recurmax, NO_COMMA, stmtDepth, canThrow, null, MANDATORY); + var pairs = createAssignmentPairs(recurmax, NO_COMMA, stmtDepth, canThrow); return "var " + pairs.names.map(function(name, index) { return index in pairs.values ? name + " = " + pairs.values[index] : name; }).join(", ") + ";"; @@ -853,7 +867,8 @@ function createExpression(recurmax, noComma, stmtDepth, canThrow) { case 2: return "((c = c + 1) + (" + _createExpression(recurmax, noComma, stmtDepth, canThrow) + "))"; // c only gets incremented default: - return "(" + _createExpression(recurmax, noComma, stmtDepth, canThrow) + ")"; + var expr = "(" + _createExpression(recurmax, noComma, stmtDepth, canThrow) + ")"; + return async && rng(50) == 0 ? "(await" + expr + ")" : expr; } } @@ -909,6 +924,8 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) { case p++: case p++: var nameLenBefore = VAR_NAMES.length; + var save_async = async; + async = rng(50) == 0; unique_vars.push("c"); var name = createVarName(MAYBE); // note: this name is only accessible from _within_ the function. and immutable at that. unique_vars.pop(); @@ -916,7 +933,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) { switch (rng(5)) { case 0: s.push( - "(function " + name + "(){", + "(" + makeFunction(name) + "(){", strictMode(), createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth), rng(2) == 0 ? "})" : "})()" @@ -924,7 +941,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) { break; case 1: s.push( - "+function " + name + "(){", + "+" + makeFunction(name) + "(){", strictMode(), createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth), "}()" @@ -932,7 +949,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) { break; case 2: s.push( - "!function " + name + "(){", + "!" + makeFunction(name) + "(){", strictMode(), createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth), "}()" @@ -940,13 +957,14 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) { break; case 3: s.push( - "void function " + name + "(){", + "void " + makeFunction(name) + "(){", strictMode(), createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth), "}()" ); break; default: + async = false; createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) { var instantiate = rng(4) ? "new " : ""; s.push( @@ -965,6 +983,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) { }); break; } + async = save_async; VAR_NAMES.length = nameLenBefore; return filterDirective(s).join("\n"); case p++: @@ -1361,7 +1380,7 @@ function createVarName(maybe, dontStore) { do { name = VAR_NAMES[rng(VAR_NAMES.length)]; if (suffix) name += "_" + suffix; - } while (unique_vars.indexOf(name) >= 0 || block_vars.indexOf(name) >= 0); + } while (unique_vars.indexOf(name) >= 0 || block_vars.indexOf(name) >= 0 || async && name == "await"); if (suffix && !dontStore) VAR_NAMES.push(name); return name; } |