aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-12-05 21:19:31 +0000
committerGitHub <noreply@github.com>2020-12-06 05:19:31 +0800
commit1e4985ed9e0822118ad01313af09008af1e9f036 (patch)
treea30030887031071c32dce0a37841732fe8c66cf5 /test
parentd2d56e301ecd8f6af056ccd355f940e11c851bd5 (diff)
downloadtracifyjs-1e4985ed9e0822118ad01313af09008af1e9f036.tar.gz
tracifyjs-1e4985ed9e0822118ad01313af09008af1e9f036.zip
support spread syntax (#4328)
Diffstat (limited to 'test')
-rw-r--r--test/compress/spread.js371
-rw-r--r--test/reduce.js13
-rw-r--r--test/ufuzz/index.js63
3 files changed, 431 insertions, 16 deletions
diff --git a/test/compress/spread.js b/test/compress/spread.js
new file mode 100644
index 00000000..b7a6f753
--- /dev/null
+++ b/test/compress/spread.js
@@ -0,0 +1,371 @@
+collapse_vars_1: {
+ options = {
+ collapse_vars: true,
+ }
+ input: {
+ var a;
+ [ ...a = "PASS", "PASS"].slice();
+ console.log(a);
+ }
+ expect: {
+ var a;
+ [ ...a = "PASS", "PASS"].slice();
+ console.log(a);
+ }
+ expect_stdout: "PASS"
+ node_version: ">=6"
+}
+
+collapse_vars_2: {
+ options = {
+ collapse_vars: true,
+ }
+ input: {
+ var a = "FAIL";
+ try {
+ a = "PASS";
+ [ ...42, "PASS"].slice();
+ } catch (e) {
+ console.log(a);
+ }
+ }
+ expect: {
+ var a = "FAIL";
+ try {
+ a = "PASS";
+ [ ...42, "PASS"].slice();
+ } catch (e) {
+ console.log(a);
+ }
+ }
+ expect_stdout: "PASS"
+ node_version: ">=6"
+}
+
+collapse_vars_3: {
+ options = {
+ collapse_vars: true,
+ }
+ input: {
+ var a = "FAIL";
+ try {
+ [ ...(a = "PASS", 42), "PASS"].slice();
+ } catch (e) {
+ console.log(a);
+ }
+ }
+ expect: {
+ var a = "FAIL";
+ try {
+ [ ...(a = "PASS", 42), "PASS"].slice();
+ } catch (e) {
+ console.log(a);
+ }
+ }
+ expect_stdout: "PASS"
+ node_version: ">=6"
+}
+
+collapse_vars_4: {
+ options = {
+ collapse_vars: true,
+ unused: true,
+ }
+ input: {
+ console.log(function(a) {
+ return a;
+ }(...[ "PASS", "FAIL" ]));
+ }
+ expect: {
+ console.log(function(a) {
+ return a;
+ }(...[ "PASS", "FAIL" ]));
+ }
+ expect_stdout: "PASS"
+ node_version: ">=6"
+}
+
+dont_inline: {
+ options = {
+ inline: true,
+ }
+ input: {
+ console.log(function(a) {
+ return a;
+ }(...[ "PASS", "FAIL" ]));
+ }
+ expect: {
+ console.log(function(a) {
+ return a;
+ }(...[ "PASS", "FAIL" ]));
+ }
+ expect_stdout: "PASS"
+ node_version: ">=6"
+}
+
+do_inline: {
+ options = {
+ properties: true,
+ inline: true,
+ }
+ input: {
+ console.log(function(a) {
+ return a;
+ }(...[ "PASS", "FAIL" ]));
+ }
+ expect: {
+ console.log(("FAIL", "PASS"));
+ }
+ expect_stdout: "PASS"
+ node_version: ">=6"
+}
+
+drop_empty_call_1: {
+ options = {
+ side_effects: true,
+ }
+ input: {
+ try {
+ (function() {})(...null);
+ } catch (e) {
+ console.log("PASS");
+ }
+ }
+ expect: {
+ try {
+ [ ...null ];
+ } catch (e) {
+ console.log("PASS");
+ }
+ }
+ expect_stdout: "PASS"
+ node_version: ">=6"
+}
+
+drop_empty_call_2: {
+ options = {
+ properties: true,
+ side_effects: true,
+ }
+ input: {
+ (function() {})(...[ console.log("PASS") ]);
+ }
+ expect: {
+ console.log("PASS");
+ }
+ expect_stdout: "PASS"
+ node_version: ">=6"
+}
+
+convert_hole: {
+ options = {
+ properties: true,
+ }
+ input: {
+ console.log(...[ "PASS", , 42 ]);
+ }
+ expect: {
+ console.log("PASS", void 0, 42);
+ }
+ expect_stdout: "PASS undefined 42"
+ node_version: ">=6"
+}
+
+keep_property_access: {
+ options = {
+ properties: true,
+ side_effects: true,
+ }
+ input: {
+ console.log(function() {
+ return [ ..."foo" ][0];
+ }());
+ }
+ expect: {
+ console.log(function() {
+ return [ ..."foo" ][0];
+ }());
+ }
+ expect_stdout: "f"
+ node_version: ">=6"
+}
+
+keep_fargs: {
+ options = {
+ keep_fargs: "strict",
+ unused: true,
+ }
+ input: {
+ var a = [ "PASS" ];
+ (function(b, c) {
+ console.log(c);
+ })(console, ...a);
+ }
+ expect: {
+ var a = [ "PASS" ];
+ (function(b, c) {
+ console.log(c);
+ })(console, ...a);
+ }
+ expect_stdout: "PASS"
+ node_version: ">=6"
+}
+
+reduce_vars_1: {
+ options = {
+ reduce_vars: true,
+ unused: true,
+ }
+ input: {
+ console.log(function(b, c) {
+ return c ? "PASS" : "FAIL";
+ }(..."foo"));
+ }
+ expect: {
+ console.log(function(b, c) {
+ return c ? "PASS" : "FAIL";
+ }(..."foo"));
+ }
+ expect_stdout: "PASS"
+ node_version: ">=6"
+}
+
+reduce_vars_2: {
+ options = {
+ conditionals: true,
+ evaluate: true,
+ reduce_vars: true,
+ }
+ input: {
+ console.log(function(b, c) {
+ return c ? "PASS" : "FAIL";
+ }(..."foo"));
+ }
+ expect: {
+ console.log(function(b, c) {
+ return c ? "PASS" : "FAIL";
+ }(..."foo"));
+ }
+ expect_stdout: "PASS"
+ node_version: ">=6"
+}
+
+drop_object: {
+ options = {
+ side_effects: true,
+ }
+ input: {
+ ({ ...console.log("PASS") });
+ }
+ expect: {
+ console.log("PASS");
+ }
+ expect_stdout: "PASS"
+ node_version: ">=8"
+}
+
+keep_getter: {
+ options = {
+ side_effects: true,
+ }
+ input: {
+ ({
+ ...{
+ get p() {
+ console.log("PASS");
+ },
+ },
+ get q() {
+ console.log("FAIL");
+ },
+ });
+ }
+ expect: {
+ ({
+ ...{
+ get p() {
+ console.log("PASS");
+ },
+ },
+ });
+ }
+ expect_stdout: "PASS"
+ node_version: ">=8"
+}
+
+keep_accessor: {
+ options = {
+ properties: true,
+ }
+ input: {
+ var o = {
+ ...{
+ get p() {
+ console.log("GET");
+ return this.r;
+ },
+ set q(v) {
+ console.log("SET", v);
+ },
+ r: 42,
+ },
+ r: null,
+ };
+ for (var k in o)
+ console.log(k, o[k]);
+ }
+ expect: {
+ var o = {
+ ...{
+ get p() {
+ console.log("GET");
+ return this.r;
+ },
+ set q(v) {
+ console.log("SET", v);
+ },
+ r: 42,
+ },
+ r: null,
+ };
+ for (var k in o)
+ console.log(k, o[k]);
+ }
+ expect_stdout: [
+ "GET",
+ "p 42",
+ "q undefined",
+ "r null",
+ ]
+ node_version: ">=8"
+}
+
+unused_var_side_effects: {
+ options = {
+ unused: true,
+ }
+ input: {
+ (function f(a) {
+ var b = {
+ ...a,
+ };
+ })({
+ get p() {
+ console.log("PASS");
+ },
+ });
+ }
+ expect: {
+ (function(a) {
+ ({
+ ...a,
+ });
+ })({
+ get p() {
+ console.log("PASS");
+ },
+ });
+ }
+ expect_stdout: "PASS"
+ node_version: ">=8"
+}
diff --git a/test/reduce.js b/test/reduce.js
index 2b1b42e7..cda79f8a 100644
--- a/test/reduce.js
+++ b/test/reduce.js
@@ -135,7 +135,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
if (expr && !(expr instanceof U.AST_Hole)) {
node.start._permute++;
CHANGED = true;
- return expr;
+ return expr instanceof U.AST_Spread ? expr.expression : expr;
}
}
else if (node instanceof U.AST_Binary) {
@@ -164,7 +164,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
][ ((node.start._permute += step) * steps | 0) % 3 ];
if (expr) {
CHANGED = true;
- return expr;
+ return expr instanceof U.AST_Spread ? expr.expression : expr;
}
if (node.expression instanceof U.AST_Function) {
// hoist and return expressions from the IIFE function expression
@@ -381,9 +381,8 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
}
if (in_list) {
- // special case to drop object properties and switch branches
- if (parent instanceof U.AST_Object
- || parent instanceof U.AST_Switch && parent.expression != node) {
+ // drop switch branches
+ if (parent instanceof U.AST_Switch && parent.expression != node) {
node.start._permute++;
CHANGED = true;
return List.skip;
@@ -404,7 +403,9 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
}
// skip element/property from (destructured) array/object
- if (parent instanceof U.AST_Array || parent instanceof U.AST_Destructured || parent instanceof AST_Object) {
+ if (parent instanceof U.AST_Array
+ || parent instanceof U.AST_Destructured
+ || parent instanceof U.AST_Object) {
node.start._permute++;
CHANGED = true;
return List.skip;
diff --git a/test/ufuzz/index.js b/test/ufuzz/index.js
index 0e56bb1d..7c76b348 100644
--- a/test/ufuzz/index.js
+++ b/test/ufuzz/index.js
@@ -371,9 +371,24 @@ function createParams(noDuplicate) {
}
function createArgs(recurmax, stmtDepth, canThrow) {
+ recurmax--;
var args = [];
- for (var n = rng(4); --n >= 0;) {
- args.push(rng(2) ? createValue() : createExpression(recurmax - 1, COMMA_OK, stmtDepth, canThrow));
+ for (var n = rng(4); --n >= 0;) switch (rng(50)) {
+ case 0:
+ case 1:
+ var name = getVarName();
+ if (canThrow && rng(8) === 0) {
+ args.push("..." + name);
+ } else {
+ args.push('...("" + ' + name + ")");
+ }
+ break;
+ case 2:
+ args.push("..." + createArrayLiteral(recurmax, stmtDepth, canThrow));
+ break;
+ default:
+ args.push(rng(2) ? createValue() : createExpression(recurmax, COMMA_OK, stmtDepth, canThrow));
+ break;
}
return args.join(", ");
}
@@ -1044,13 +1059,30 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
function createArrayLiteral(recurmax, stmtDepth, canThrow) {
recurmax--;
- var arr = "[";
- for (var i = rng(6); --i >= 0;) {
+ var arr = [];
+ for (var i = rng(6); --i >= 0;) switch (rng(50)) {
+ case 0:
+ case 1:
// in rare cases produce an array hole element
- var element = rng(20) ? createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) : "";
- arr += element + ", ";
+ arr.push("");
+ break;
+ case 2:
+ case 3:
+ var name = getVarName();
+ if (canThrow && rng(8) === 0) {
+ arr.push("..." + name);
+ } else {
+ arr.push('...("" + ' + name + ")");
+ }
+ break;
+ case 4:
+ arr.push("..." + createArrayLiteral(recurmax, stmtDepth, canThrow));
+ break;
+ default:
+ arr.push(createExpression(recurmax, COMMA_OK, stmtDepth, canThrow));
+ break;
}
- return arr + "]";
+ return "[" + arr.join(", ") + "]";
}
var SAFE_KEYS = [
@@ -1135,13 +1167,20 @@ function createObjectFunction(recurmax, stmtDepth, canThrow) {
function createObjectLiteral(recurmax, stmtDepth, canThrow) {
recurmax--;
var obj = ["({"];
- for (var i = rng(6); --i >= 0;) switch (rng(30)) {
+ for (var i = rng(6); --i >= 0;) switch (rng(50)) {
case 0:
- obj.push(createObjectFunction(recurmax, stmtDepth, canThrow));
- break;
case 1:
obj.push(getVarName() + ",");
break;
+ case 2:
+ obj.push(createObjectFunction(recurmax, stmtDepth, canThrow));
+ break;
+ case 3:
+ obj.push("..." + getVarName() + ",");
+ break;
+ case 4:
+ obj.push("..." + createObjectLiteral(recurmax, stmtDepth, canThrow) + ",");
+ break;
default:
obj.push(createObjectKey(recurmax, stmtDepth, canThrow) + ":(" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "),");
break;
@@ -1591,6 +1630,9 @@ function patch_try_catch(orig, toplevel) {
} else if (result.name == "TypeError" && /'in'/.test(result.message)) {
index = result.ufuzz_catch;
return orig.slice(0, index) + result.ufuzz_var + ' = new Error("invalid `in`");' + orig.slice(index);
+ } else if (result.name == "TypeError" && /not iterable/.test(result.message)) {
+ index = result.ufuzz_catch;
+ return orig.slice(0, index) + result.ufuzz_var + ' = new Error("spread not iterable");' + orig.slice(index);
} else if (result.name == "RangeError" && result.message == "Maximum call stack size exceeded") {
index = result.ufuzz_try;
return orig.slice(0, index) + 'throw new Error("skipping infinite recursion");' + orig.slice(index);
@@ -1656,6 +1698,7 @@ for (var round = 1; round <= num_iterations; round++) {
ok = sandbox.same_stdout(orig_result[toplevel ? 3 : 2], uglify_result);
}
// ignore difference in error message caused by `in`
+ // ignore difference in error message caused by spread syntax
// ignore difference in depth of termination caused by infinite recursion
if (!ok) {
var orig_skipped = patch_try_catch(original_code, toplevel);