fix corner case in --reduce-test (#3819)

This commit is contained in:
Alex Lam S.L
2020-04-24 23:49:50 +01:00
committed by GitHub
parent 44d6912a55
commit 94f33570e3
4 changed files with 33 additions and 25 deletions

View File

@@ -237,7 +237,10 @@ function run() {
// load on demand - assumes dev tree checked out // load on demand - assumes dev tree checked out
var reduce_test = require("../test/reduce"); var reduce_test = require("../test/reduce");
var testcase = files[0] || files[Object.keys(files)[0]]; var testcase = files[0] || files[Object.keys(files)[0]];
var result = reduce_test(testcase, options, {verbose: true}); var result = reduce_test(testcase, options, {
log: print_error,
verbose: true,
});
} }
else { else {
var result = UglifyJS.minify(files, options); var result = UglifyJS.minify(files, options);

View File

@@ -1,7 +1,7 @@
var assert = require("assert"); var assert = require("assert");
var readFileSync = require("fs").readFileSync; var readFileSync = require("fs").readFileSync;
var run_code = require("../sandbox").run_code; var run_code = require("../sandbox").run_code;
var UglifyJS = require("../../"); var UglifyJS = require("../..");
function read(path) { function read(path) {
return readFileSync(path, "utf8"); return readFileSync(path, "utf8");

View File

@@ -252,7 +252,8 @@ describe("test/reduce.js", function() {
"try{", "try{",
"null[function(){}]", "null[function(){}]",
"}catch(e){", "}catch(e){",
"for(var i in e.toString())a++", "for(var i in e.toString())",
"a++,console.log()",
"}", "}",
"console.log(a);", "console.log(a);",
].join(""); ].join("");
@@ -264,6 +265,7 @@ describe("test/reduce.js", function() {
}, },
}); });
if (result.error) throw result.error; if (result.error) throw result.error;
assert.deepEqual(result.warnings, []);
assert.strictEqual(result.code.replace(/function \(/g, "function("), (semver.satisfies(process.version, "<=0.10") ? [ assert.strictEqual(result.code.replace(/function \(/g, "function("), (semver.satisfies(process.version, "<=0.10") ? [
"// Can't reproduce test failure", "// Can't reproduce test failure",
"// minify options: {", "// minify options: {",

View File

@@ -1,5 +1,5 @@
var crypto = require("crypto"); var crypto = require("crypto");
var U = require("./node"); var U = require("..");
var List = U.List; var List = U.List;
var os = require("os"); var os = require("os");
var sandbox = require("./sandbox"); var sandbox = require("./sandbox");
@@ -24,6 +24,10 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
reduce_options = reduce_options || {}; reduce_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 || 10000; var max_timeout = reduce_options.max_timeout || 10000;
var warnings = [];
var log = reduce_options.log || function(msg) {
warnings.push(msg);
};
var verbose = reduce_options.verbose; var verbose = reduce_options.verbose;
var minify_options_json = JSON.stringify(minify_options, null, 2); var minify_options_json = JSON.stringify(minify_options, null, 2);
var result_cache = Object.create(null); var result_cache = Object.create(null);
@@ -31,7 +35,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
var differs = producesDifferentResultWhenMinified(result_cache, testcase, minify_options, max_timeout); var differs = producesDifferentResultWhenMinified(result_cache, testcase, minify_options, max_timeout);
if (verbose) { if (verbose) {
console.error("// Node.js " + process.version + " on " + os.platform() + " " + os.arch()); log("// Node.js " + process.version + " on " + os.platform() + " " + os.arch());
} }
if (!differs) { if (!differs) {
// same stdout result produced when minified // same stdout result produced when minified
@@ -39,16 +43,19 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
code: [ code: [
"// Can't reproduce test failure", "// Can't reproduce test failure",
"// minify options: " + to_comment(minify_options_json) "// minify options: " + to_comment(minify_options_json)
].join("\n") ].join("\n"),
warnings: warnings,
}; };
} else if (differs.timed_out) { } else if (differs.timed_out) {
return { return {
code: [ code: [
"// Can't reproduce test failure within " + max_timeout + "ms", "// Can't reproduce test failure within " + max_timeout + "ms",
"// minify options: " + to_comment(minify_options_json) "// minify options: " + to_comment(minify_options_json)
].join("\n") ].join("\n"),
warnings: warnings,
}; };
} else if (differs.error) { } else if (differs.error) {
differs.warnings = warnings;
return differs; return differs;
} else if (is_error(differs.unminified_result) } else if (is_error(differs.unminified_result)
&& is_error(differs.minified_result) && is_error(differs.minified_result)
@@ -57,7 +64,8 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
code: [ code: [
"// No differences except in error message", "// No differences except in error message",
"// minify options: " + to_comment(minify_options_json) "// minify options: " + to_comment(minify_options_json)
].join("\n") ].join("\n"),
warnings: warnings,
}; };
} else { } else {
max_timeout = Math.min(100 * differs.elapsed, max_timeout); max_timeout = Math.min(100 * differs.elapsed, max_timeout);
@@ -414,10 +422,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
// only difference detected is in error message, so expose that and try again // only difference detected is in error message, so expose that and try again
testcase_ast.transform(new U.TreeTransformer(function(node, descend) { testcase_ast.transform(new U.TreeTransformer(function(node, descend) {
if (node.TYPE == "Call" && node.expression.print_to_string() == "console.log") { if (node.TYPE == "Call" && node.expression.print_to_string() == "console.log") {
return new U.AST_Sequence({ return to_sequence(node.args);
expressions: node.args,
start: {},
});
} }
if (node instanceof U.AST_Catch) { if (node instanceof U.AST_Catch) {
descend(node, this); descend(node, this);
@@ -443,11 +448,8 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
node.start._permute = 0; node.start._permute = 0;
})); }));
for (var c = 0; c < max_iterations; ++c) { for (var c = 0; c < max_iterations; ++c) {
if (verbose) { if (verbose && pass == 1 && c % 25 == 0) {
if (pass == 1 && c % 25 == 0) { log("// reduce test pass " + pass + ", iteration " + c + ": " + testcase.length + " bytes");
console.error("// reduce test pass "
+ pass + ", iteration " + c + ": " + testcase.length + " bytes");
}
} }
var CHANGED = false; var CHANGED = false;
var code_ast = testcase_ast.clone(true).transform(tt); var code_ast = testcase_ast.clone(true).transform(tt);
@@ -457,9 +459,9 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
} catch (ex) { } catch (ex) {
// AST is not well formed. // AST is not well formed.
// no harm done - just log the error, ignore latest change and continue iterating. // no harm done - just log the error, ignore latest change and continue iterating.
console.error("*** Error generating code from AST."); log("*** Error generating code from AST.");
console.error(ex); log(ex.stack);
console.error("*** Discarding permutation and continuing."); log("*** Discarding permutation and continuing.");
continue; continue;
} }
var diff = producesDifferentResultWhenMinified(result_cache, code, minify_options, max_timeout); var diff = producesDifferentResultWhenMinified(result_cache, code, minify_options, max_timeout);
@@ -470,10 +472,10 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
} else if (diff.error) { } else if (diff.error) {
// something went wrong during minify() - could be malformed AST or genuine bug. // something went wrong during minify() - could be malformed AST or genuine bug.
// no harm done - just log code & error, ignore latest change and continue iterating. // no harm done - just log code & error, ignore latest change and continue iterating.
console.error("*** Error during minification."); log("*** Error during minification.");
console.error(code); log(code);
console.error(diff.error); log(diff.error.stack);
console.error("*** Discarding permutation and continuing."); log("*** Discarding permutation and continuing.");
} else if (is_error(diff.unminified_result) } else if (is_error(diff.unminified_result)
&& is_error(diff.minified_result) && is_error(diff.minified_result)
&& diff.unminified_result.name == diff.minified_result.name) { && diff.unminified_result.name == diff.minified_result.name) {
@@ -489,7 +491,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
} }
if (c == 0) break; if (c == 0) break;
if (verbose) { if (verbose) {
console.error("// reduce test pass " + pass + ": " + testcase.length + " bytes"); log("// reduce test pass " + pass + ": " + testcase.length + " bytes");
} }
} }
testcase = try_beautify(result_cache, testcase, minify_options, differs.unminified_result, max_timeout); testcase = try_beautify(result_cache, testcase, minify_options, differs.unminified_result, max_timeout);
@@ -510,6 +512,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
} }
lines.push("// options: " + to_comment(minify_options_json)); lines.push("// options: " + to_comment(minify_options_json));
testcase.code += lines.join("\n"); testcase.code += lines.join("\n");
testcase.warnings = warnings;
return testcase; return testcase;
} }
}; };