improve --reduce-test (#3719)
- cover missing cases when eliminating unreferenced labels - format multi-line outputs correctly
This commit is contained in:
9
test/input/reduce/label.js
Normal file
9
test/input/reduce/label.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
var o = this;
|
||||||
|
|
||||||
|
for (var k in o) L17060: {
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var a;
|
||||||
|
|
||||||
|
console.log(k);
|
||||||
16
test/input/reduce/label.reduced.js
Normal file
16
test/input/reduce/label.reduced.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
var o = this;
|
||||||
|
|
||||||
|
for (var k in o) {
|
||||||
|
0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var a;
|
||||||
|
|
||||||
|
console.log(k);
|
||||||
|
// output: a
|
||||||
|
//
|
||||||
|
// minify: k
|
||||||
|
//
|
||||||
|
// options: {
|
||||||
|
// "mangle": false
|
||||||
|
// }
|
||||||
@@ -11,5 +11,12 @@ var a_1 = f0();
|
|||||||
|
|
||||||
console.log(b);
|
console.log(b);
|
||||||
// output: -19
|
// output: -19
|
||||||
|
//
|
||||||
// minify: -4
|
// minify: -4
|
||||||
// options: {"compress":{"unsafe_math":true},"mangle":false}
|
//
|
||||||
|
// options: {
|
||||||
|
// "compress": {
|
||||||
|
// "unsafe_math": true
|
||||||
|
// },
|
||||||
|
// "mangle": false
|
||||||
|
// }
|
||||||
@@ -8,9 +8,9 @@ function read(path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe("test/reduce.js", function() {
|
describe("test/reduce.js", function() {
|
||||||
|
this.timeout(60000);
|
||||||
it("Should reduce test case", function() {
|
it("Should reduce test case", function() {
|
||||||
this.timeout(60000);
|
var result = reduce_test(read("test/input/reduce/unsafe_math.js"), {
|
||||||
var result = reduce_test(read("test/input/reduce/input.js"), {
|
|
||||||
compress: {
|
compress: {
|
||||||
unsafe_math: true,
|
unsafe_math: true,
|
||||||
},
|
},
|
||||||
@@ -19,7 +19,16 @@ describe("test/reduce.js", function() {
|
|||||||
verbose: false,
|
verbose: false,
|
||||||
});
|
});
|
||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code, read("test/input/reduce/output.js"));
|
assert.strictEqual(result.code, read("test/input/reduce/unsafe_math.reduced.js"));
|
||||||
|
});
|
||||||
|
it("Should eliminate unreferenced labels", function() {
|
||||||
|
var result = reduce_test(read("test/input/reduce/label.js"), {
|
||||||
|
mangle: false,
|
||||||
|
}, {
|
||||||
|
verbose: false,
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, read("test/input/reduce/label.reduced.js"));
|
||||||
});
|
});
|
||||||
it("Should handle test cases with --toplevel", function() {
|
it("Should handle test cases with --toplevel", function() {
|
||||||
var result = reduce_test([
|
var result = reduce_test([
|
||||||
@@ -31,7 +40,9 @@ describe("test/reduce.js", function() {
|
|||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code, [
|
assert.strictEqual(result.code, [
|
||||||
"// Can't reproduce test failure with minify options provided:",
|
"// Can't reproduce test failure with minify options provided:",
|
||||||
'// {"toplevel":true}',
|
"// {",
|
||||||
|
'// "toplevel": true',
|
||||||
|
"// }",
|
||||||
"",
|
"",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
});
|
});
|
||||||
@@ -40,7 +51,10 @@ describe("test/reduce.js", function() {
|
|||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code, [
|
assert.strictEqual(result.code, [
|
||||||
"// Can't reproduce test failure with minify options provided:",
|
"// Can't reproduce test failure with minify options provided:",
|
||||||
'// {"compress":{},"mangle":false}',
|
"// {",
|
||||||
|
'// "compress": {},',
|
||||||
|
'// "mangle": false',
|
||||||
|
"// }",
|
||||||
"",
|
"",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
});
|
});
|
||||||
@@ -61,8 +75,15 @@ describe("test/reduce.js", function() {
|
|||||||
" return f.length;",
|
" return f.length;",
|
||||||
"}());",
|
"}());",
|
||||||
"// output: 1",
|
"// output: 1",
|
||||||
|
"// ",
|
||||||
"// minify: 0",
|
"// minify: 0",
|
||||||
'// options: {"compress":{"keep_fargs":false},"mangle":false}',
|
"// ",
|
||||||
|
"// options: {",
|
||||||
|
'// "compress": {',
|
||||||
|
'// "keep_fargs": false',
|
||||||
|
"// },",
|
||||||
|
'// "mangle": false',
|
||||||
|
"// }",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
});
|
});
|
||||||
it("Should fail when invalid option is supplied", function() {
|
it("Should fail when invalid option is supplied", function() {
|
||||||
@@ -81,4 +102,38 @@ describe("test/reduce.js", function() {
|
|||||||
assert.ok(err instanceof Error);
|
assert.ok(err instanceof Error);
|
||||||
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Name expected");
|
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Name expected");
|
||||||
});
|
});
|
||||||
|
it("Should format multi-line output correctly", function() {
|
||||||
|
var code = [
|
||||||
|
"var a = 0;",
|
||||||
|
"",
|
||||||
|
"for (var b in [ 1, 2, 3 ]) {",
|
||||||
|
" a = +a + 1 - .2;",
|
||||||
|
" console.log(a);",
|
||||||
|
"}",
|
||||||
|
].join("\n");
|
||||||
|
var result = reduce_test(code, {
|
||||||
|
compress: {
|
||||||
|
unsafe_math: true,
|
||||||
|
},
|
||||||
|
mangle: false,
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, [
|
||||||
|
code,
|
||||||
|
"// output: 0.8",
|
||||||
|
"// 1.6",
|
||||||
|
"// 2.4",
|
||||||
|
"// ",
|
||||||
|
"// minify: 0.8",
|
||||||
|
"// 1.6",
|
||||||
|
"// 2.4000000000000004",
|
||||||
|
"// ",
|
||||||
|
"// options: {",
|
||||||
|
'// "compress": {',
|
||||||
|
'// "unsafe_math": true',
|
||||||
|
"// },",
|
||||||
|
'// "mangle": false',
|
||||||
|
"// }",
|
||||||
|
].join("\n"));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
var max_iterations = reduce_options.max_iterations || 1000;
|
var max_iterations = reduce_options.max_iterations || 1000;
|
||||||
var max_timeout = reduce_options.max_timeout || 15000;
|
var max_timeout = reduce_options.max_timeout || 15000;
|
||||||
var verbose = reduce_options.verbose;
|
var verbose = reduce_options.verbose;
|
||||||
var minify_options_json = JSON.stringify(minify_options);
|
var minify_options_json = JSON.stringify(minify_options, null, 2);
|
||||||
var timeout = 1000; // start with a low timeout
|
var timeout = 1000; // start with a low timeout
|
||||||
var differs;
|
var differs;
|
||||||
|
|
||||||
@@ -256,6 +256,15 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return node.expression;
|
return node.expression;
|
||||||
}
|
}
|
||||||
|
else if (node instanceof U.AST_LabeledStatement) {
|
||||||
|
if (node.body instanceof U.AST_Statement
|
||||||
|
&& !has_loopcontrol(node.body, node.body, node)) {
|
||||||
|
// replace labelled statement with its non-labelled body
|
||||||
|
node.start._permute = REPLACEMENTS.length;
|
||||||
|
CHANGED = true;
|
||||||
|
return node.body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (in_list) {
|
if (in_list) {
|
||||||
// special case to drop object properties and switch branches
|
// special case to drop object properties and switch branches
|
||||||
@@ -268,14 +277,6 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
|
|
||||||
// replace or skip statement
|
// replace or skip statement
|
||||||
if (node instanceof U.AST_Statement) {
|
if (node instanceof U.AST_Statement) {
|
||||||
if (node instanceof U.AST_LabeledStatement
|
|
||||||
&& node.body instanceof U.AST_Statement
|
|
||||||
&& !has_loopcontrol(node.body, node.body, node)) {
|
|
||||||
// replace labelled statement with its non-labelled body
|
|
||||||
node.start._permute = REPLACEMENTS.length;
|
|
||||||
CHANGED = true;
|
|
||||||
return node.body;
|
|
||||||
}
|
|
||||||
node.start._permute++;
|
node.start._permute++;
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return List.skip;
|
return List.skip;
|
||||||
@@ -379,13 +380,13 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
console.error("// reduce test pass " + pass + ": " + testcase.length + " bytes");
|
console.error("// reduce test pass " + pass + ": " + testcase.length + " bytes");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
testcase += "\n// output: " + differs.unminified_result
|
testcase += "\n// output: " + to_comment(differs.unminified_result)
|
||||||
+ "\n// minify: " + differs.minified_result
|
+ "\n// minify: " + to_comment(differs.minified_result)
|
||||||
+ "\n// options: " + minify_options_json;
|
+ "\n// options: " + to_comment(minify_options_json);
|
||||||
} else {
|
} else {
|
||||||
// same stdout result produced when minified
|
// same stdout result produced when minified
|
||||||
testcase = "// Can't reproduce test failure with minify options provided:"
|
testcase = "// Can't reproduce test failure with minify options provided:"
|
||||||
+ "\n// " + minify_options_json;
|
+ "\n// " + to_comment(minify_options_json);
|
||||||
}
|
}
|
||||||
var result = U.minify(testcase.replace(/\u001b\[\d+m/g, ""), {
|
var result = U.minify(testcase.replace(/\u001b\[\d+m/g, ""), {
|
||||||
compress: false,
|
compress: false,
|
||||||
@@ -399,6 +400,10 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function to_comment(value) {
|
||||||
|
return ("" + value).replace(/\n/g, "\n// ");
|
||||||
|
}
|
||||||
|
|
||||||
function has_loopcontrol(body, loop, label) {
|
function has_loopcontrol(body, loop, label) {
|
||||||
var found = false;
|
var found = false;
|
||||||
var tw = new U.TreeWalker(function(node) {
|
var tw = new U.TreeWalker(function(node) {
|
||||||
|
|||||||
Reference in New Issue
Block a user