@@ -620,6 +620,8 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
|
|
||||||
- `dead_code` (default: `true`) -- remove unreachable code
|
- `dead_code` (default: `true`) -- remove unreachable code
|
||||||
|
|
||||||
|
- `directives` (default: `true`) -- remove redundant or non-standard directives
|
||||||
|
|
||||||
- `drop_console` (default: `false`) -- Pass `true` to discard calls to
|
- `drop_console` (default: `false`) -- Pass `true` to discard calls to
|
||||||
`console.*` functions. If you wish to drop a specific function call
|
`console.*` functions. If you wish to drop a specific function call
|
||||||
such as `console.info` and/or retain side effects from function arguments
|
such as `console.info` and/or retain side effects from function arguments
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ function Compressor(options, false_by_default) {
|
|||||||
comparisons : !false_by_default,
|
comparisons : !false_by_default,
|
||||||
conditionals : !false_by_default,
|
conditionals : !false_by_default,
|
||||||
dead_code : !false_by_default,
|
dead_code : !false_by_default,
|
||||||
|
directives : !false_by_default,
|
||||||
drop_console : false,
|
drop_console : false,
|
||||||
drop_debugger : !false_by_default,
|
drop_debugger : !false_by_default,
|
||||||
evaluate : !false_by_default,
|
evaluate : !false_by_default,
|
||||||
@@ -3264,8 +3265,10 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
/* -----[ optimizers ]----- */
|
/* -----[ optimizers ]----- */
|
||||||
|
|
||||||
|
var directives = makePredicate(["use asm", "use strict"]);
|
||||||
OPT(AST_Directive, function(self, compressor) {
|
OPT(AST_Directive, function(self, compressor) {
|
||||||
if (compressor.has_directive(self.value) !== self) {
|
if (compressor.option("directives")
|
||||||
|
&& (!directives[self.value] || compressor.has_directive(self.value) !== self)) {
|
||||||
return make_node(AST_EmptyStatement, self);
|
return make_node(AST_EmptyStatement, self);
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
@@ -2025,6 +2025,7 @@ deduplicate_parenthesis: {
|
|||||||
|
|
||||||
drop_lone_use_strict: {
|
drop_lone_use_strict: {
|
||||||
options = {
|
options = {
|
||||||
|
directives: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -2052,6 +2053,27 @@ drop_lone_use_strict: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3166: {
|
||||||
|
options = {
|
||||||
|
directives: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"foo";
|
||||||
|
"use strict";
|
||||||
|
function f() {
|
||||||
|
"use strict";
|
||||||
|
"bar";
|
||||||
|
"use asm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
function f() {
|
||||||
|
"use asm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
issue_3016_1: {
|
issue_3016_1: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ function read(path) {
|
|||||||
|
|
||||||
describe("bin/uglifyjs", function() {
|
describe("bin/uglifyjs", function() {
|
||||||
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||||
it("should produce a functional build when using --self", function(done) {
|
it("Should produce a functional build when using --self", function(done) {
|
||||||
this.timeout(30000);
|
this.timeout(30000);
|
||||||
var command = uglifyjscmd + ' --self -cm --wrap WrappedUglifyJS';
|
var command = uglifyjscmd + ' --self -cm --wrap WrappedUglifyJS';
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
@@ -68,7 +68,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("should not append source map to output when not using --source-map url=inline", function(done) {
|
it("Should not append source map to output when not using --source-map url=inline", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1323/sample.js';
|
var command = uglifyjscmd + ' test/input/issue-1323/sample.js';
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
@@ -76,7 +76,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("should not consider source map file content as source map file name (issue #2082)", function(done) {
|
it("Should not consider source map file content as source map file name (issue #2082)", function(done) {
|
||||||
var command = [
|
var command = [
|
||||||
uglifyjscmd,
|
uglifyjscmd,
|
||||||
"test/input/issue-2082/sample.js",
|
"test/input/issue-2082/sample.js",
|
||||||
|
|||||||
@@ -4,12 +4,10 @@ var UglifyJS = require("../node");
|
|||||||
describe("Directives", function() {
|
describe("Directives", function() {
|
||||||
it("Should allow tokenizer to store directives state", function() {
|
it("Should allow tokenizer to store directives state", function() {
|
||||||
var tokenizer = UglifyJS.tokenizer("", "foo.js");
|
var tokenizer = UglifyJS.tokenizer("", "foo.js");
|
||||||
|
|
||||||
// Stack level 0
|
// Stack level 0
|
||||||
assert.strictEqual(tokenizer.has_directive("use strict"), false);
|
assert.strictEqual(tokenizer.has_directive("use strict"), false);
|
||||||
assert.strictEqual(tokenizer.has_directive("use asm"), false);
|
assert.strictEqual(tokenizer.has_directive("use asm"), false);
|
||||||
assert.strictEqual(tokenizer.has_directive("use thing"), false);
|
assert.strictEqual(tokenizer.has_directive("use thing"), false);
|
||||||
|
|
||||||
// Stack level 2
|
// Stack level 2
|
||||||
tokenizer.push_directives_stack();
|
tokenizer.push_directives_stack();
|
||||||
tokenizer.push_directives_stack();
|
tokenizer.push_directives_stack();
|
||||||
@@ -17,7 +15,6 @@ describe("Directives", function() {
|
|||||||
assert.strictEqual(tokenizer.has_directive("use strict"), true);
|
assert.strictEqual(tokenizer.has_directive("use strict"), true);
|
||||||
assert.strictEqual(tokenizer.has_directive("use asm"), false);
|
assert.strictEqual(tokenizer.has_directive("use asm"), false);
|
||||||
assert.strictEqual(tokenizer.has_directive("use thing"), false);
|
assert.strictEqual(tokenizer.has_directive("use thing"), false);
|
||||||
|
|
||||||
// Stack level 3
|
// Stack level 3
|
||||||
tokenizer.push_directives_stack();
|
tokenizer.push_directives_stack();
|
||||||
tokenizer.add_directive("use strict");
|
tokenizer.add_directive("use strict");
|
||||||
@@ -25,13 +22,11 @@ describe("Directives", function() {
|
|||||||
assert.strictEqual(tokenizer.has_directive("use strict"), true);
|
assert.strictEqual(tokenizer.has_directive("use strict"), true);
|
||||||
assert.strictEqual(tokenizer.has_directive("use asm"), true);
|
assert.strictEqual(tokenizer.has_directive("use asm"), true);
|
||||||
assert.strictEqual(tokenizer.has_directive("use thing"), false);
|
assert.strictEqual(tokenizer.has_directive("use thing"), false);
|
||||||
|
|
||||||
// Stack level 2
|
// Stack level 2
|
||||||
tokenizer.pop_directives_stack();
|
tokenizer.pop_directives_stack();
|
||||||
assert.strictEqual(tokenizer.has_directive("use strict"), true);
|
assert.strictEqual(tokenizer.has_directive("use strict"), true);
|
||||||
assert.strictEqual(tokenizer.has_directive("use asm"), false);
|
assert.strictEqual(tokenizer.has_directive("use asm"), false);
|
||||||
assert.strictEqual(tokenizer.has_directive("use thing"), false);
|
assert.strictEqual(tokenizer.has_directive("use thing"), false);
|
||||||
|
|
||||||
// Stack level 3
|
// Stack level 3
|
||||||
tokenizer.push_directives_stack();
|
tokenizer.push_directives_stack();
|
||||||
tokenizer.add_directive("use thing");
|
tokenizer.add_directive("use thing");
|
||||||
@@ -39,142 +34,128 @@ describe("Directives", function() {
|
|||||||
assert.strictEqual(tokenizer.has_directive("use strict"), true);
|
assert.strictEqual(tokenizer.has_directive("use strict"), true);
|
||||||
assert.strictEqual(tokenizer.has_directive("use asm"), false); // Directives are strict!
|
assert.strictEqual(tokenizer.has_directive("use asm"), false); // Directives are strict!
|
||||||
assert.strictEqual(tokenizer.has_directive("use thing"), true);
|
assert.strictEqual(tokenizer.has_directive("use thing"), true);
|
||||||
|
|
||||||
// Stack level 2
|
// Stack level 2
|
||||||
tokenizer.pop_directives_stack();
|
tokenizer.pop_directives_stack();
|
||||||
assert.strictEqual(tokenizer.has_directive("use strict"), true);
|
assert.strictEqual(tokenizer.has_directive("use strict"), true);
|
||||||
assert.strictEqual(tokenizer.has_directive("use asm"), false);
|
assert.strictEqual(tokenizer.has_directive("use asm"), false);
|
||||||
assert.strictEqual(tokenizer.has_directive("use thing"), false);
|
assert.strictEqual(tokenizer.has_directive("use thing"), false);
|
||||||
|
|
||||||
// Stack level 1
|
// Stack level 1
|
||||||
tokenizer.pop_directives_stack();
|
tokenizer.pop_directives_stack();
|
||||||
assert.strictEqual(tokenizer.has_directive("use strict"), false);
|
assert.strictEqual(tokenizer.has_directive("use strict"), false);
|
||||||
assert.strictEqual(tokenizer.has_directive("use asm"), false);
|
assert.strictEqual(tokenizer.has_directive("use asm"), false);
|
||||||
assert.strictEqual(tokenizer.has_directive("use thing"), false);
|
assert.strictEqual(tokenizer.has_directive("use thing"), false);
|
||||||
|
|
||||||
// Stack level 0
|
// Stack level 0
|
||||||
tokenizer.pop_directives_stack();
|
tokenizer.pop_directives_stack();
|
||||||
assert.strictEqual(tokenizer.has_directive("use strict"), false);
|
assert.strictEqual(tokenizer.has_directive("use strict"), false);
|
||||||
assert.strictEqual(tokenizer.has_directive("use asm"), false);
|
assert.strictEqual(tokenizer.has_directive("use asm"), false);
|
||||||
assert.strictEqual(tokenizer.has_directive("use thing"), false);
|
assert.strictEqual(tokenizer.has_directive("use thing"), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should know which strings are directive and which ones are not", function() {
|
it("Should know which strings are directive and which ones are not", function() {
|
||||||
var test_directive = function(tokenizer, test) {
|
[
|
||||||
test.directives.map(function(directive) {
|
[
|
||||||
assert.strictEqual(tokenizer.has_directive(directive), true, directive + " in " + test.input);
|
'"use strict"\n',
|
||||||
});
|
[ "use strict"],
|
||||||
test.non_directives.map(function(fake_directive) {
|
[ "use asm"]
|
||||||
assert.strictEqual(tokenizer.has_directive(fake_directive), false, fake_directive + " in " + test.input);
|
],
|
||||||
});
|
[
|
||||||
}
|
'"use\\\nstrict";',
|
||||||
|
[],
|
||||||
var tests = [
|
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
|
||||||
{
|
],
|
||||||
input: '"use strict"\n',
|
[
|
||||||
directives: ["use strict"],
|
'"use strict"\n"use asm"\n"use bar"\n',
|
||||||
non_directives: ["use asm"]
|
[ "use strict", "use asm", "use bar" ],
|
||||||
},
|
[ "use foo", "use\\x20strict" ]
|
||||||
{
|
],
|
||||||
input: '"use\\\nstrict";',
|
[
|
||||||
directives: [],
|
'"use \\\nstrict";"use strict";',
|
||||||
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
|
[],
|
||||||
},
|
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
|
||||||
{
|
],
|
||||||
input: '"use strict"\n"use asm"\n"use bar"\n',
|
[
|
||||||
directives: ["use strict", "use asm", "use bar"],
|
'"\\76";',
|
||||||
non_directives: ["use foo", "use\\x20strict"]
|
[],
|
||||||
},
|
[ ">", "\\76" ]
|
||||||
{
|
],
|
||||||
input: '"use \\\nstrict";"use strict";',
|
[
|
||||||
directives: [],
|
// no ; or newline
|
||||||
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
|
'"use strict"',
|
||||||
},
|
[],
|
||||||
{
|
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
|
||||||
input: '"\\76";',
|
],
|
||||||
directives: [],
|
[
|
||||||
non_directives: [">", "\\76"]
|
';"use strict"',
|
||||||
},
|
[],
|
||||||
{
|
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
|
||||||
input: '"use strict"', // no ; or newline
|
],
|
||||||
directives: [],
|
|
||||||
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
input: ';"use strict"',
|
|
||||||
directives: [],
|
|
||||||
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
|
|
||||||
},
|
|
||||||
// Duplicate above code but put it in a function
|
// Duplicate above code but put it in a function
|
||||||
{
|
[
|
||||||
input: 'function foo() {"use strict"\n',
|
'function foo() {"use strict"\n',
|
||||||
directives: ["use strict"],
|
[ "use strict" ],
|
||||||
non_directives: ["use asm"]
|
[ "use asm" ]
|
||||||
},
|
],
|
||||||
{
|
[
|
||||||
input: 'function foo() {"use\\\nstrict";',
|
'function foo() {"use\\\nstrict";',
|
||||||
directives: [],
|
[],
|
||||||
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
|
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
|
||||||
},
|
],
|
||||||
{
|
[
|
||||||
input: 'function foo() {"use strict"\n"use asm"\n"use bar"\n',
|
'function foo() {"use strict"\n"use asm"\n"use bar"\n',
|
||||||
directives: ["use strict", "use asm", "use bar"],
|
[ "use strict", "use asm", "use bar" ],
|
||||||
non_directives: ["use foo", "use\\x20strict"]
|
[ "use foo", "use\\x20strict" ]
|
||||||
},
|
],
|
||||||
{
|
[
|
||||||
input: 'function foo() {"use \\\nstrict";"use strict";',
|
'function foo() {"use \\\nstrict";"use strict";',
|
||||||
directives: [],
|
[],
|
||||||
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
|
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
|
||||||
},
|
],
|
||||||
{
|
[
|
||||||
input: 'var foo = function() {"\\76";',
|
'var foo = function() {"\\76";',
|
||||||
directives: [],
|
[],
|
||||||
non_directives: [">", "\\76"]
|
[ ">", "\\76" ]
|
||||||
},
|
],
|
||||||
{
|
[
|
||||||
input: 'var foo = function() {"use strict"', // no ; or newline
|
'var foo = function() {"use strict"', // no ; or newline
|
||||||
directives: [],
|
[],
|
||||||
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
|
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
|
||||||
},
|
],
|
||||||
{
|
[
|
||||||
input: 'var foo = function() {;"use strict"',
|
'var foo = function() {;"use strict"',
|
||||||
directives: [],
|
[],
|
||||||
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
|
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
|
||||||
},
|
],
|
||||||
// Special cases
|
// Special cases
|
||||||
{
|
[
|
||||||
input: '"1";"2";"3";"4";;"5"',
|
'"1";"2";"3";"4";;"5"',
|
||||||
directives: ["1", "2", "3", "4"],
|
[ "1", "2", "3", "4" ],
|
||||||
non_directives: ["5", "6", "use strict", "use asm"]
|
[ "5", "6", "use strict", "use asm" ]
|
||||||
},
|
],
|
||||||
{
|
[
|
||||||
input: 'if(1){"use strict";',
|
'if(1){"use strict";',
|
||||||
directives: [],
|
[],
|
||||||
non_directives: ["use strict", "use\nstrict", "use \nstrict", "use asm"]
|
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
|
||||||
},
|
],
|
||||||
{
|
[
|
||||||
input: '"use strict";try{"use asm";',
|
'"use strict";try{"use asm";',
|
||||||
directives: ["use strict"],
|
[ "use strict" ],
|
||||||
non_directives: ["use\nstrict", "use \nstrict", "use asm"]
|
[ "use\nstrict", "use \nstrict", "use asm" ]
|
||||||
}
|
],
|
||||||
];
|
].forEach(function(test) {
|
||||||
|
var tokenizer = UglifyJS.tokenizer(test[0] + "]", "foo.js");
|
||||||
for (var i = 0; i < tests.length; i++) {
|
assert.throws(function() {
|
||||||
// Fail parser deliberately to get state at failure
|
UglifyJS.parse(tokenizer);
|
||||||
var tokenizer = UglifyJS.tokenizer(tests[i].input + "]", "foo.js");
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error
|
||||||
try {
|
&& e.message === "Unexpected token: punc (])"
|
||||||
var parser = UglifyJS.parse(tokenizer);
|
}, test[0]);
|
||||||
throw new Error("Expected parser to fail");
|
test[1].forEach(function(directive) {
|
||||||
} catch (e) {
|
assert.strictEqual(tokenizer.has_directive(directive), true, directive + " in " + test[0]);
|
||||||
assert.strictEqual(e instanceof UglifyJS.JS_Parse_Error, true);
|
});
|
||||||
assert.strictEqual(e.message, "Unexpected token: punc (])");
|
test[2].forEach(function(fake_directive) {
|
||||||
}
|
assert.strictEqual(tokenizer.has_directive(fake_directive), false, fake_directive + " in " + test[0]);
|
||||||
|
});
|
||||||
test_directive(tokenizer, tests[i]);
|
});
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should test EXPECT_DIRECTIVE RegExp", function() {
|
it("Should test EXPECT_DIRECTIVE RegExp", function() {
|
||||||
[
|
[
|
||||||
[ "", true ],
|
[ "", true ],
|
||||||
@@ -184,7 +165,7 @@ describe("Directives", function() {
|
|||||||
[ "'tests'", false ],
|
[ "'tests'", false ],
|
||||||
[ "'tests'; \n\t", true ],
|
[ "'tests'; \n\t", true ],
|
||||||
[ "'tests';\n\n", true ],
|
[ "'tests';\n\n", true ],
|
||||||
["\n\n\"use strict\";\n\n", true]
|
[ "\n\n\"use strict\";\n\n", true ],
|
||||||
].forEach(function(test) {
|
].forEach(function(test) {
|
||||||
var out = UglifyJS.OutputStream();
|
var out = UglifyJS.OutputStream();
|
||||||
out.print(test[0]);
|
out.print(test[0]);
|
||||||
@@ -192,19 +173,33 @@ describe("Directives", function() {
|
|||||||
assert.strictEqual(out.get() === test[0] + ';""', test[1], test[0]);
|
assert.strictEqual(out.get() === test[0] + ';""', test[1], test[0]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should only print 2 semicolons spread over 2 lines in beautify mode", function() {
|
it("Should only print 2 semicolons spread over 2 lines in beautify mode", function() {
|
||||||
assert.strictEqual(
|
var result = UglifyJS.minify([
|
||||||
UglifyJS.minify(
|
'"use strict";',
|
||||||
'"use strict";\'use strict\';"use strict";"use strict";;\'use strict\';console.log(\'use strict\');',
|
"'use strict';",
|
||||||
{output: {beautify: true, quote_style: 3}, compress: false}
|
'"use strict";',
|
||||||
).code,
|
'"use strict";;',
|
||||||
'"use strict";\n\n\'use strict\';\n\n"use strict";\n\n"use strict";\n\n;\'use strict\';\n\nconsole.log(\'use strict\');'
|
"'use strict';",
|
||||||
);
|
"console.log('use strict');"
|
||||||
|
].join(""), {
|
||||||
|
compress: false,
|
||||||
|
output: {
|
||||||
|
beautify: true,
|
||||||
|
quote_style: 3
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, [
|
||||||
|
'"use strict";',
|
||||||
|
"'use strict';",
|
||||||
|
'"use strict";',
|
||||||
|
'"use strict";',
|
||||||
|
";'use strict';",
|
||||||
|
"console.log('use strict');"
|
||||||
|
].join("\n\n"));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should not add double semicolons in non-scoped block statements to avoid strings becoming directives", function() {
|
it("Should not add double semicolons in non-scoped block statements to avoid strings becoming directives", function() {
|
||||||
var tests = [
|
[
|
||||||
[
|
[
|
||||||
'{"use\x20strict"}',
|
'{"use\x20strict"}',
|
||||||
'{"use strict"}'
|
'{"use strict"}'
|
||||||
@@ -221,26 +216,27 @@ describe("Directives", function() {
|
|||||||
'if(1){"use\x20strict"} else {"use strict"}',
|
'if(1){"use\x20strict"} else {"use strict"}',
|
||||||
'if(1){"use strict"}else{"use strict"}'
|
'if(1){"use strict"}else{"use strict"}'
|
||||||
]
|
]
|
||||||
];
|
].forEach(function(test) {
|
||||||
|
var result = UglifyJS.minify(test[0], {
|
||||||
for (var i = 0; i < tests.length; i++) {
|
compress: false,
|
||||||
assert.strictEqual(
|
mangle: false
|
||||||
UglifyJS.minify(tests[i][0], {compress: false, mangle: false}).code,
|
});
|
||||||
tests[i][1],
|
if (result.error) throw result.error;
|
||||||
tests[i][0]
|
assert.strictEqual(result.code, test[1], test[0]);
|
||||||
);
|
});
|
||||||
|
});
|
||||||
|
it("Should add double semicolon when relying on automatic semicolon insertion", function() {
|
||||||
|
var result = UglifyJS.minify('"use strict";"use\\x20strict";', {
|
||||||
|
compress: false,
|
||||||
|
output: {
|
||||||
|
semicolons: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
it("Should add double semicolon when relying on automatic semicolon insertion", function() {
|
assert.strictEqual(result.code, '"use strict";;"use strict"\n');
|
||||||
var code = UglifyJS.minify('"use strict";"use\\x20strict";',
|
|
||||||
{output: {semicolons: false}, compress: false}
|
|
||||||
).code;
|
|
||||||
assert.strictEqual(code, '"use strict";;"use strict"\n');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check quote style of directives", function() {
|
it("Should check quote style of directives", function() {
|
||||||
var tests = [
|
[
|
||||||
// 0. Prefer double quotes, unless string contains more double quotes than single quotes
|
// 0. Prefer double quotes, unless string contains more double quotes than single quotes
|
||||||
[
|
[
|
||||||
'"testing something";',
|
'"testing something";',
|
||||||
@@ -337,45 +333,53 @@ describe("Directives", function() {
|
|||||||
3,
|
3,
|
||||||
"'\"use strict\"';",
|
"'\"use strict\"';",
|
||||||
],
|
],
|
||||||
];
|
].forEach(function(test) {
|
||||||
for (var i = 0; i < tests.length; i++) {
|
var result = UglifyJS.minify(test[0], {
|
||||||
assert.strictEqual(
|
compress: false,
|
||||||
UglifyJS.minify(tests[i][0], {output:{quote_style: tests[i][1]}, compress: false}).code,
|
output: {
|
||||||
tests[i][2],
|
quote_style: test[1]
|
||||||
tests[i][0] + " using mode " + tests[i][1]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, test[2], test[0] + " using mode " + test[1]);
|
||||||
|
});
|
||||||
|
});
|
||||||
it("Should be able to compress without side effects", function() {
|
it("Should be able to compress without side effects", function() {
|
||||||
// NOTE: the "use asm" directive disables any optimisation after being defined
|
[
|
||||||
var tests = [
|
|
||||||
[
|
[
|
||||||
'"use strict";"use strict";"use strict";"use foo";"use strict";;"use sloppy";doSomething("foo");',
|
'"use strict";"use strict";"use strict";"use foo";"use strict";;"use sloppy";doSomething("foo");',
|
||||||
'"use strict";"use foo";doSomething("foo");',
|
'"use strict";doSomething("foo");'
|
||||||
'function f(){ "use strict" }',
|
|
||||||
'function f(){ "use asm" }',
|
|
||||||
'function f(){ "use nondirective" }',
|
|
||||||
'function f(){ ;"use strict" }',
|
|
||||||
'function f(){ "use \n"; }',
|
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
// Nothing gets optimised in the compressor because "use asm" is the first statement
|
// Nothing gets optimised in the compressor because "use asm" is the first statement
|
||||||
'"use asm";"use\\x20strict";1+1;',
|
'"use asm";"use\\x20strict";1+1;',
|
||||||
'"use asm";;"use strict";1+1;', // Yet, the parser noticed that "use strict" wasn't a directive
|
// Yet, the parser noticed that "use strict" wasn't a directive
|
||||||
|
'"use asm";;"use strict";1+1;',
|
||||||
|
],
|
||||||
|
[
|
||||||
'function f(){ "use strict" }',
|
'function f(){ "use strict" }',
|
||||||
|
'function f(){}'
|
||||||
|
],
|
||||||
|
[
|
||||||
'function f(){ "use asm" }',
|
'function f(){ "use asm" }',
|
||||||
|
'function f(){"use asm"}'
|
||||||
|
],
|
||||||
|
[
|
||||||
'function f(){ "use nondirective" }',
|
'function f(){ "use nondirective" }',
|
||||||
'function f(){}',
|
'function f(){}'
|
||||||
'function f(){}',
|
],
|
||||||
]
|
[
|
||||||
];
|
'function f(){ ;"use strict" }',
|
||||||
|
'function f(){}'
|
||||||
for (var i = 0; i < tests.length; i++) {
|
],
|
||||||
assert.strictEqual(
|
[
|
||||||
UglifyJS.minify(tests[i][0]).code,
|
'function f(){ "use \\n"; }',
|
||||||
tests[i][1],
|
'function f(){}'
|
||||||
tests[i][0]
|
],
|
||||||
);
|
].forEach(function(test) {
|
||||||
}
|
var result = UglifyJS.minify(test[0]);
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, test[1], test[0]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ describe("bin/uglifyjs with input file globs", function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("should throw with non-matching glob string", function(done) {
|
it("Should throw with non-matching glob string", function(done) {
|
||||||
var command = uglifyjscmd + ' "test/input/issue-1242/blah.*"';
|
var command = uglifyjscmd + ' "test/input/issue-1242/blah.*"';
|
||||||
|
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
@@ -53,7 +53,7 @@ describe("bin/uglifyjs with input file globs", function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("should handle special characters in glob string", function(done) {
|
it("Should handle special characters in glob string", function(done) {
|
||||||
var command = uglifyjscmd + ' "test/input/issue-1632/^{*}[???](*)+$.??" -cm';
|
var command = uglifyjscmd + ' "test/input/issue-1632/^{*}[???](*)+$.??" -cm';
|
||||||
|
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
@@ -63,7 +63,7 @@ describe("bin/uglifyjs with input file globs", function() {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("should handle array of glob strings - matching and otherwise", function(done) {
|
it("Should handle array of glob strings - matching and otherwise", function(done) {
|
||||||
var dir = "test/input/issue-1242";
|
var dir = "test/input/issue-1242";
|
||||||
var command = uglifyjscmd + ' "' + [
|
var command = uglifyjscmd + ' "' + [
|
||||||
path.join(dir, "b*.es5"),
|
path.join(dir, "b*.es5"),
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ describe("minify", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("#__PURE__", function() {
|
describe("#__PURE__", function() {
|
||||||
it("should drop #__PURE__ hint after use", function() {
|
it("Should drop #__PURE__ hint after use", function() {
|
||||||
var result = UglifyJS.minify('//@__PURE__ comment1 #__PURE__ comment2\n foo(), bar();', {
|
var result = UglifyJS.minify('//@__PURE__ comment1 #__PURE__ comment2\n foo(), bar();', {
|
||||||
output: {
|
output: {
|
||||||
comments: "all",
|
comments: "all",
|
||||||
@@ -197,7 +197,7 @@ describe("minify", function() {
|
|||||||
var code = result.code;
|
var code = result.code;
|
||||||
assert.strictEqual(code, "// comment1 comment2\nbar();");
|
assert.strictEqual(code, "// comment1 comment2\nbar();");
|
||||||
});
|
});
|
||||||
it("should drop #__PURE__ hint if function is retained", function() {
|
it("Should drop #__PURE__ hint if function is retained", function() {
|
||||||
var result = UglifyJS.minify("var a = /*#__PURE__*/(function(){ foo(); })();", {
|
var result = UglifyJS.minify("var a = /*#__PURE__*/(function(){ foo(); })();", {
|
||||||
output: {
|
output: {
|
||||||
comments: "all",
|
comments: "all",
|
||||||
@@ -210,7 +210,7 @@ describe("minify", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("JS_Parse_Error", function() {
|
describe("JS_Parse_Error", function() {
|
||||||
it("should return syntax error", function() {
|
it("Should return syntax error", function() {
|
||||||
var result = UglifyJS.minify("function f(a{}");
|
var result = UglifyJS.minify("function f(a{}");
|
||||||
var err = result.error;
|
var err = result.error;
|
||||||
assert.ok(err instanceof Error);
|
assert.ok(err instanceof Error);
|
||||||
@@ -219,7 +219,7 @@ describe("minify", function() {
|
|||||||
assert.strictEqual(err.line, 1);
|
assert.strictEqual(err.line, 1);
|
||||||
assert.strictEqual(err.col, 12);
|
assert.strictEqual(err.col, 12);
|
||||||
});
|
});
|
||||||
it("should reject duplicated label name", function() {
|
it("Should reject duplicated label name", function() {
|
||||||
var result = UglifyJS.minify("L:{L:{}}");
|
var result = UglifyJS.minify("L:{L:{}}");
|
||||||
var err = result.error;
|
var err = result.error;
|
||||||
assert.ok(err instanceof Error);
|
assert.ok(err instanceof Error);
|
||||||
@@ -231,7 +231,7 @@ describe("minify", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("global_defs", function() {
|
describe("global_defs", function() {
|
||||||
it("should throw for non-trivial expressions", function() {
|
it("Should throw for non-trivial expressions", function() {
|
||||||
var result = UglifyJS.minify("alert(42);", {
|
var result = UglifyJS.minify("alert(42);", {
|
||||||
compress: {
|
compress: {
|
||||||
global_defs: {
|
global_defs: {
|
||||||
@@ -243,7 +243,7 @@ describe("minify", function() {
|
|||||||
assert.ok(err instanceof Error);
|
assert.ok(err instanceof Error);
|
||||||
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token: keyword (debugger)");
|
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token: keyword (debugger)");
|
||||||
});
|
});
|
||||||
it("should skip inherited properties", function() {
|
it("Should skip inherited properties", function() {
|
||||||
var foo = Object.create({ skip: this });
|
var foo = Object.create({ skip: this });
|
||||||
foo.bar = 42;
|
foo.bar = 42;
|
||||||
var result = UglifyJS.minify("alert(FOO);", {
|
var result = UglifyJS.minify("alert(FOO);", {
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ describe("sourcemaps", function() {
|
|||||||
assert.strictEqual(map.version, 3);
|
assert.strictEqual(map.version, 3);
|
||||||
assert.deepEqual(map.names, [ "x" ]);
|
assert.deepEqual(map.names, [ "x" ]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should give correct names", function() {
|
it("Should give correct names", function() {
|
||||||
var map = source_map([
|
var map = source_map([
|
||||||
"({",
|
"({",
|
||||||
@@ -67,7 +66,6 @@ describe("sourcemaps", function() {
|
|||||||
].join("\n"));
|
].join("\n"));
|
||||||
assert.deepEqual(map.names, [ "enabled", "x" ]);
|
assert.deepEqual(map.names, [ "enabled", "x" ]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should mark array/object literals", function() {
|
it("Should mark array/object literals", function() {
|
||||||
var result = UglifyJS.minify([
|
var result = UglifyJS.minify([
|
||||||
"var obj = {};",
|
"var obj = {};",
|
||||||
@@ -80,7 +78,6 @@ describe("sourcemaps", function() {
|
|||||||
assert.strictEqual(result.code, "({}).wat([]);");
|
assert.strictEqual(result.code, "({}).wat([]);");
|
||||||
assert.strictEqual(result.map, '{"version":3,"sources":["0"],"names":["wat"],"mappings":"CAAU,IACNA,IAAI"}');
|
assert.strictEqual(result.map, '{"version":3,"sources":["0"],"names":["wat"],"mappings":"CAAU,IACNA,IAAI"}');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should give correct sourceRoot", function() {
|
it("Should give correct sourceRoot", function() {
|
||||||
var code = "console.log(42);";
|
var code = "console.log(42);";
|
||||||
var result = UglifyJS.minify(code, {
|
var result = UglifyJS.minify(code, {
|
||||||
@@ -212,6 +209,9 @@ describe("sourcemaps", function() {
|
|||||||
});
|
});
|
||||||
it("Should work with max_line_len", function() {
|
it("Should work with max_line_len", function() {
|
||||||
var result = UglifyJS.minify(read("./test/input/issue-505/input.js"), {
|
var result = UglifyJS.minify(read("./test/input/issue-505/input.js"), {
|
||||||
|
compress: {
|
||||||
|
directives: false,
|
||||||
|
},
|
||||||
output: {
|
output: {
|
||||||
max_line_len: 20
|
max_line_len: 20
|
||||||
},
|
},
|
||||||
@@ -261,7 +261,6 @@ describe("sourcemaps", function() {
|
|||||||
var map = prepare_map(orig);
|
var map = prepare_map(orig);
|
||||||
assert.equal(map.sourceContentFor("index.js"), orig.sourcesContent[0]);
|
assert.equal(map.sourceContentFor("index.js"), orig.sourcesContent[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should copy sourcesContent if sources are relative", function() {
|
it("Should copy sourcesContent if sources are relative", function() {
|
||||||
var relativeMap = get_map();
|
var relativeMap = get_map();
|
||||||
relativeMap.sources = ['./index.js'];
|
relativeMap.sources = ['./index.js'];
|
||||||
@@ -270,7 +269,6 @@ describe("sourcemaps", function() {
|
|||||||
assert.equal(map.sourcesContent.length, 1);
|
assert.equal(map.sourcesContent.length, 1);
|
||||||
assert.equal(map.sourceContentFor("index.js"), relativeMap.sourcesContent[0]);
|
assert.equal(map.sourceContentFor("index.js"), relativeMap.sourcesContent[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should not have invalid mappings from inputSourceMap", function() {
|
it("Should not have invalid mappings from inputSourceMap", function() {
|
||||||
var map = prepare_map(get_map());
|
var map = prepare_map(get_map());
|
||||||
// The original source has only 2 lines, check that mappings don't have more lines
|
// The original source has only 2 lines, check that mappings don't have more lines
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ var exec = require("child_process").exec;
|
|||||||
var UglifyJS = require("../..");
|
var UglifyJS = require("../..");
|
||||||
|
|
||||||
describe("spidermonkey export/import sanity test", function() {
|
describe("spidermonkey export/import sanity test", function() {
|
||||||
it("should produce a functional build when using --self with spidermonkey", function(done) {
|
it("Should produce a functional build when using --self with spidermonkey", function(done) {
|
||||||
this.timeout(60000);
|
this.timeout(60000);
|
||||||
|
|
||||||
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
|
var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||||
@@ -23,7 +23,7 @@ describe("spidermonkey export/import sanity test", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not add unnecessary escape slashes to regexps", function() {
|
it("Should not add unnecessary escape slashes to regexps", function() {
|
||||||
var input = "/[\\\\/]/;";
|
var input = "/[\\\\/]/;";
|
||||||
var ast = UglifyJS.parse(input).to_mozilla_ast();
|
var ast = UglifyJS.parse(input).to_mozilla_ast();
|
||||||
assert.equal(
|
assert.equal(
|
||||||
|
|||||||
Reference in New Issue
Block a user