Merge branch 'master' into harmony-2.8.0

This commit is contained in:
alexlamsl
2017-02-27 04:37:48 +08:00
63 changed files with 4471 additions and 480 deletions

49
test/benchmark.js Normal file
View File

@@ -0,0 +1,49 @@
#! /usr/bin/env node
// -*- js -*-
"use strict";
var createHash = require("crypto").createHash;
var fork = require("child_process").fork;
var args = process.argv.slice(2);
if (!args.length) {
args.push("-mc", "warnings=false");
}
args.push("--stats");
var urls = [
"https://code.jquery.com/jquery-3.1.1.js",
"https://code.angularjs.org/1.6.1/angular.js",
"https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.9.0/math.js",
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js",
"https://unpkg.com/react@15.3.2/dist/react.js",
"http://builds.emberjs.com/tags/v2.11.0/ember.prod.js",
"https://cdn.jsdelivr.net/lodash/4.17.4/lodash.js",
"https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.js",
];
var results = {};
var remaining = 2 * urls.length;
function done() {
if (!--remaining) {
urls.forEach(function(url) {
console.log();
console.log(url);
console.log(results[url].time);
console.log("SHA1:", results[url].sha1);
});
}
}
urls.forEach(function(url) {
results[url] = { time: "" };
require(url.slice(0, url.indexOf(":"))).get(url, function(res) {
var uglifyjs = fork("bin/uglifyjs", args, { silent: true });
res.pipe(uglifyjs.stdin);
uglifyjs.stdout.pipe(createHash("sha1")).on("data", function(data) {
results[url].sha1 = data.toString("hex");
done();
});
uglifyjs.stderr.setEncoding("utf8");
uglifyjs.stderr.on("data", function(data) {
results[url].time += data;
}).on("end", done)
});
});

View File

@@ -23,10 +23,19 @@ constant_join: {
input: {
var a = [ "foo", "bar", "baz" ].join("");
var a1 = [ "foo", "bar", "baz" ].join();
var a2 = [ "foo", "bar", "baz" ].join(null);
var a3 = [ "foo", "bar", "baz" ].join(void 0);
var a4 = [ "foo", , "baz" ].join();
var a5 = [ "foo", null, "baz" ].join();
var a6 = [ "foo", void 0, "baz" ].join();
var b = [ "foo", 1, 2, 3, "bar" ].join("");
var c = [ boo(), "foo", 1, 2, 3, "bar", bar() ].join("");
var c1 = [ boo(), bar(), "foo", 1, 2, 3, "bar", bar() ].join("");
var c2 = [ 1, 2, "foo", "bar", baz() ].join("");
var c3 = [ boo() + bar() + "foo", 1, 2, 3, "bar", bar() + "foo" ].join("");
var c4 = [ 1, 2, null, undefined, "foo", "bar", baz() ].join("");
var c5 = [ boo() + bar() + "foo", 1, 2, 3, "bar", bar() + "foo" ].join();
var c6 = [ 1, 2, null, undefined, "foo", "bar", baz() ].join();
var d = [ "foo", 1 + 2 + "bar", "baz" ].join("-");
var e = [].join(foo + bar);
var f = [].join("");
@@ -35,10 +44,19 @@ constant_join: {
expect: {
var a = "foobarbaz";
var a1 = "foo,bar,baz";
var a2 = "foonullbarnullbaz";
var a3 = "foo,bar,baz";
var a4 = "foo,,baz";
var a5 = "foo,,baz";
var a6 = "foo,,baz";
var b = "foo123bar";
var c = boo() + "foo123bar" + bar();
var c1 = "" + boo() + bar() + "foo123bar" + bar();
var c2 = "12foobar" + baz();
var c3 = boo() + bar() + "foo123bar" + bar() + "foo";
var c4 = "12foobar" + baz();
var c5 = [ boo() + bar() + "foo", 1, 2, 3, "bar", bar() + "foo" ].join();
var c6 = [ "1,2,,,foo,bar", baz() ].join();
var d = "foo-3bar-baz";
var e = [].join(foo + bar);
var f = "";
@@ -148,6 +166,41 @@ spread_with_logical_expression_at_middle: {
}
}
constant_join_3: {
options = {
unsafe: true,
evaluate: true,
};
input: {
var a = [ null ].join();
var b = [ , ].join();
var c = [ , 1, , 3 ].join();
var d = [ foo ].join();
var e = [ foo, null, undefined, bar ].join("-");
var f = [ foo, bar ].join("");
var g = [ null, "foo", null, bar + "baz" ].join("");
var h = [ null, "foo", null, bar + "baz" ].join("-");
var i = [ "foo" + bar, null, baz + "moo" ].join("");
var j = [ foo + "bar", baz ].join("");
var k = [ foo, "bar" + baz ].join("");
var l = [ foo, bar + "baz" ].join("");
}
expect: {
var a = "";
var b = "";
var c = ",1,,3";
var d = "" + foo;
var e = [ foo, "-", bar ].join("-");
var f = "" + foo + bar;
var g = "foo" + bar + "baz";
var h = [ "-foo-", bar + "baz" ].join("-");
var i = "foo" + bar + baz + "moo";
var j = foo + "bar" + baz;
var k = foo + "bar" + baz;
var l = foo + (bar + "baz");
}
}
for_loop: {
options = {
unsafe : true,

View File

@@ -338,8 +338,9 @@ collapse_vars_while: {
collapse_vars_do_while: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:false, loops:false, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
comparisons:true, evaluate:true, booleans:false, loops:false, unused:"keep_assign",
hoist_funs:true, keep_fargs:true, if_return:true, join_vars:true, cascade:true,
side_effects:true
}
input: {
function f1(y) {
@@ -409,6 +410,79 @@ collapse_vars_do_while: {
}
}
collapse_vars_do_while_drop_assign: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:false, loops:false, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
}
input: {
function f1(y) {
// The constant do-while condition `c` will be replaced.
var c = 9;
do { } while (c === 77);
}
function f2(y) {
// The non-constant do-while condition `c` will not be replaced.
var c = 5 - y;
do { } while (c);
}
function f3(y) {
// The constant `x` will be replaced in the do loop body.
function fn(n) { console.log(n); }
var a = 2, x = 7;
do {
fn(a = x);
break;
} while (y);
}
function f4(y) {
// The non-constant `a` will not be replaced in the do loop body.
var a = y / 4;
do {
return a;
} while (y);
}
function f5(y) {
function p(x) { console.log(x); }
do {
// The non-constant `a` will be replaced in p(a)
// because it is declared in same block.
var a = y - 3;
p(a);
} while (--y);
}
}
expect: {
function f1(y) {
do ; while (false);
}
function f2(y) {
var c = 5 - y;
do ; while (c);
}
function f3(y) {
function fn(n) { console.log(n); }
do {
fn(7);
break;
} while (y);
}
function f4(y) {
var a = y / 4;
do
return a;
while (y);
}
function f5(y) {
function p(x) { console.log(x); }
do {
p(y - 3);
} while (--y);
}
}
}
collapse_vars_seq: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
@@ -567,8 +641,9 @@ collapse_vars_assignment: {
collapse_vars_lvalues: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
comparisons:true, evaluate:true, booleans:true, loops:true, unused:"keep_assign",
hoist_funs:true, keep_fargs:true, if_return:true, join_vars:true, cascade:true,
side_effects:true
}
input: {
function f0(x) { var i = ++x; return x += i; }
@@ -593,7 +668,38 @@ collapse_vars_lvalues: {
function f7(x) { var w = e1(), v = e2(), c = v - x; return (w = x) - c; }
function f8(x) { var w = e1(), v = e2(); return (w = x) - (v - x); }
function f9(x) { var w = e1(); return e2() - x - (w = x); }
}
}
collapse_vars_lvalues_drop_assign: {
options = {
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
}
input: {
function f0(x) { var i = ++x; return x += i; }
function f1(x) { var a = (x -= 3); return x += a; }
function f2(x) { var z = x, a = ++z; return z += a; }
function f3(x) { var a = (x -= 3), b = x + a; return b; }
function f4(x) { var a = (x -= 3); return x + a; }
function f5(x) { var w = e1(), v = e2(), c = v = --x, b = w = x; return b - c; }
function f6(x) { var w = e1(), v = e2(), c = v = --x, b = w = x; return c - b; }
function f7(x) { var w = e1(), v = e2(), c = v - x, b = w = x; return b - c; }
function f8(x) { var w = e1(), v = e2(), b = w = x, c = v - x; return b - c; }
function f9(x) { var w = e1(), v = e2(), b = w = x, c = v - x; return c - b; }
}
expect: {
function f0(x) { var i = ++x; return x += i; }
function f1(x) { var a = (x -= 3); return x += a; }
function f2(x) { var z = x, a = ++z; return z += a; }
function f3(x) { var a = (x -= 3); return x + a; }
function f4(x) { var a = (x -= 3); return x + a; }
function f5(x) { var v = (e1(), e2()), c = v = --x; return x - c; }
function f6(x) { e1(), e2(); return --x - x; }
function f7(x) { var v = (e1(), e2()), c = v - x; return x - c; }
function f8(x) { var v = (e1(), e2()); return x - (v - x); }
function f9(x) { e1(); return e2() - x - x; }
}
}

View File

@@ -24,3 +24,143 @@ concat_1: {
var f = "\x00360\08\0";
}
}
concat_2: {
options = {};
input: {
console.log(
1 + (2 + 3),
1 + (2 + "3"),
1 + ("2" + 3),
1 + ("2" + "3"),
"1" + (2 + 3),
"1" + (2 + "3"),
"1" + ("2" + 3),
"1" + ("2" + "3")
);
}
expect: {
console.log(
1 + (2 + 3),
1 + (2 + "3"),
1 + "2" + 3,
1 + "2" + "3",
"1" + (2 + 3),
"1" + 2 + "3",
"1" + "2" + 3,
"1" + "2" + "3"
);
}
}
concat_3: {
options = {};
input: {
console.log(
1 + 2 + (3 + 4 + 5),
1 + 2 + (3 + 4 + "5"),
1 + 2 + (3 + "4" + 5),
1 + 2 + (3 + "4" + "5"),
1 + 2 + ("3" + 4 + 5),
1 + 2 + ("3" + 4 + "5"),
1 + 2 + ("3" + "4" + 5),
1 + 2 + ("3" + "4" + "5")
);
}
expect: {
console.log(
1 + 2 + (3 + 4 + 5),
1 + 2 + (3 + 4 + "5"),
1 + 2 + (3 + "4") + 5,
1 + 2 + (3 + "4") + "5",
1 + 2 + "3" + 4 + 5,
1 + 2 + "3" + 4 + "5",
1 + 2 + "3" + "4" + 5,
1 + 2 + "3" + "4" + "5"
);
}
}
concat_4: {
options = {};
input: {
console.log(
1 + "2" + (3 + 4 + 5),
1 + "2" + (3 + 4 + "5"),
1 + "2" + (3 + "4" + 5),
1 + "2" + (3 + "4" + "5"),
1 + "2" + ("3" + 4 + 5),
1 + "2" + ("3" + 4 + "5"),
1 + "2" + ("3" + "4" + 5),
1 + "2" + ("3" + "4" + "5")
);
}
expect: {
console.log(
1 + "2" + (3 + 4 + 5),
1 + "2" + (3 + 4) + "5",
1 + "2" + 3 + "4" + 5,
1 + "2" + 3 + "4" + "5",
1 + "2" + "3" + 4 + 5,
1 + "2" + "3" + 4 + "5",
1 + "2" + "3" + "4" + 5,
1 + "2" + "3" + "4" + "5"
);
}
}
concat_5: {
options = {};
input: {
console.log(
"1" + 2 + (3 + 4 + 5),
"1" + 2 + (3 + 4 + "5"),
"1" + 2 + (3 + "4" + 5),
"1" + 2 + (3 + "4" + "5"),
"1" + 2 + ("3" + 4 + 5),
"1" + 2 + ("3" + 4 + "5"),
"1" + 2 + ("3" + "4" + 5),
"1" + 2 + ("3" + "4" + "5")
);
}
expect: {
console.log(
"1" + 2 + (3 + 4 + 5),
"1" + 2 + (3 + 4) + "5",
"1" + 2 + 3 + "4" + 5,
"1" + 2 + 3 + "4" + "5",
"1" + 2 + "3" + 4 + 5,
"1" + 2 + "3" + 4 + "5",
"1" + 2 + "3" + "4" + 5,
"1" + 2 + "3" + "4" + "5"
);
}
}
concat_6: {
options = {};
input: {
console.log(
"1" + "2" + (3 + 4 + 5),
"1" + "2" + (3 + 4 + "5"),
"1" + "2" + (3 + "4" + 5),
"1" + "2" + (3 + "4" + "5"),
"1" + "2" + ("3" + 4 + 5),
"1" + "2" + ("3" + 4 + "5"),
"1" + "2" + ("3" + "4" + 5),
"1" + "2" + ("3" + "4" + "5")
);
}
expect: {
console.log(
"1" + "2" + (3 + 4 + 5),
"1" + "2" + (3 + 4) + "5",
"1" + "2" + 3 + "4" + 5,
"1" + "2" + 3 + "4" + "5",
"1" + "2" + "3" + 4 + 5,
"1" + "2" + "3" + 4 + "5",
"1" + "2" + "3" + "4" + 5,
"1" + "2" + "3" + "4" + "5"
);
}
}

165
test/compress/const.js Normal file
View File

@@ -0,0 +1,165 @@
issue_1191: {
options = {
evaluate : true,
booleans : true,
comparisons : true,
dead_code : true,
conditionals : true,
side_effects : true,
unused : true,
hoist_funs : true,
if_return : true,
join_vars : true,
sequences : false,
collapse_vars : false,
reduce_vars : true,
}
input: {
function foo(rot) {
const rotTol = 5;
if (rot < -rotTol || rot > rotTol)
bar();
baz();
}
}
expect: {
function foo(rot) {
(rot < -5 || rot > 5) && bar();
baz();
}
}
}
issue_1194: {
options = {
evaluate : true,
booleans : true,
comparisons : true,
dead_code : true,
conditionals : true,
side_effects : true,
unused : true,
hoist_funs : true,
if_return : true,
join_vars : true,
sequences : false,
collapse_vars : false,
reduce_vars : true,
}
input: {
function f1() {const a = "X"; return a + a;}
function f2() {const aa = "X"; return aa + aa;}
function f3() {const aaa = "X"; return aaa + aaa;}
}
expect: {
function f1(){return"XX"}
function f2(){return"XX"}
function f3(){return"XX"}
}
}
issue_1396: {
options = {
evaluate : true,
booleans : true,
comparisons : true,
dead_code : true,
conditionals : true,
side_effects : true,
unused : true,
hoist_funs : true,
if_return : true,
join_vars : true,
sequences : false,
collapse_vars : false,
reduce_vars : true,
}
input: {
function foo(a) {
const VALUE = 1;
console.log(2 | VALUE);
console.log(VALUE + 1);
console.log(VALUE);
console.log(a & VALUE);
}
function bar() {
const s = "01234567890123456789";
console.log(s + s + s + s + s);
const CONSTANT = "abc";
console.log(CONSTANT + CONSTANT + CONSTANT + CONSTANT + CONSTANT);
}
}
expect: {
function foo(a) {
console.log(3);
console.log(2);
console.log(1);
console.log(1 & a);
}
function bar() {
const s = "01234567890123456789";
console.log(s + s + s + s + s);
console.log("abcabcabcabcabc");
}
}
}
unused_regexp_literal: {
options = {
evaluate : true,
booleans : true,
comparisons : true,
dead_code : true,
conditionals : true,
side_effects : true,
unused : true,
hoist_funs : true,
if_return : true,
join_vars : true,
sequences : false,
collapse_vars : false,
}
input: {
function f(){ var a = /b/; }
}
expect: {
function f(){}
}
}
regexp_literal_not_const: {
options = {
evaluate : true,
booleans : true,
comparisons : true,
dead_code : true,
conditionals : true,
side_effects : true,
unused : true,
hoist_funs : true,
if_return : true,
join_vars : true,
sequences : false,
collapse_vars : false,
reduce_vars : true,
}
input: {
(function(){
var result;
const s = 'acdabcdeabbb';
const REGEXP_LITERAL = /ab*/g;
while (result = REGEXP_LITERAL.exec(s)) {
console.log(result[0]);
}
})();
}
expect: {
(function() {
var result;
const REGEXP_LITERAL = /ab*/g;
while (result = REGEXP_LITERAL.exec("acdabcdeabbb")) console.log(result[0]);
})();
}
}

View File

@@ -116,7 +116,8 @@ dead_code_const_declaration: {
loops : true,
booleans : true,
conditionals : true,
evaluate : true
evaluate : true,
reduce_vars : true,
};
input: {
var unused;
@@ -141,7 +142,8 @@ dead_code_const_annotation: {
loops : true,
booleans : true,
conditionals : true,
evaluate : true
evaluate : true,
reduce_vars : true,
};
input: {
var unused;
@@ -189,7 +191,8 @@ dead_code_const_annotation_complex_scope: {
loops : true,
booleans : true,
conditionals : true,
evaluate : true
evaluate : true,
reduce_vars : true,
};
input: {
var unused_var;
@@ -223,6 +226,5 @@ dead_code_const_annotation_complex_scope: {
var beef = 'good';
var meat = 'beef';
var pork = 'bad';
'good' === pork && console.log('reached, not const');
}
}

View File

@@ -1,24 +1,24 @@
drop_console_1: {
options = {};
input: {
console.log('foo');
console.log.apply(console, arguments);
}
expect: {
console.log('foo');
console.log.apply(console, arguments);
}
}
drop_console_1: {
options = { drop_console: true };
input: {
console.log('foo');
console.log.apply(console, arguments);
}
expect: {
// with regular compression these will be stripped out as well
void 0;
void 0;
}
}
drop_console_1: {
options = {};
input: {
console.log('foo');
console.log.apply(console, arguments);
}
expect: {
console.log('foo');
console.log.apply(console, arguments);
}
}
drop_console_2: {
options = { drop_console: true };
input: {
console.log('foo');
console.log.apply(console, arguments);
}
expect: {
// with regular compression these will be stripped out as well
void 0;
void 0;
}
}

View File

@@ -258,3 +258,505 @@ keep_fnames: {
}
}
}
drop_assign: {
options = { unused: true };
input: {
function f1() {
var a;
a = 1;
}
function f2() {
var a = 1;
a = 2;
}
function f3(a) {
a = 1;
}
function f4() {
var a;
return a = 1;
}
function f5() {
var a;
return function() {
a = 1;
}
}
}
expect: {
function f1() {
1;
}
function f2() {
2;
}
function f3(a) {
1;
}
function f4() {
return 1;
}
function f5() {
var a;
return function() {
a = 1;
}
}
}
}
keep_assign: {
options = { unused: "keep_assign" };
input: {
function f1() {
var a;
a = 1;
}
function f2() {
var a = 1;
a = 2;
}
function f3(a) {
a = 1;
}
function f4() {
var a;
return a = 1;
}
function f5() {
var a;
return function() {
a = 1;
}
}
}
expect: {
function f1() {
var a;
a = 1;
}
function f2() {
var a = 1;
a = 2;
}
function f3(a) {
a = 1;
}
function f4() {
var a;
return a = 1;
}
function f5() {
var a;
return function() {
a = 1;
}
}
}
}
drop_toplevel_funcs: {
options = { toplevel: "funcs", unused: true };
input: {
var a, b = 1, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
function h() {}
console.log(b = 3);
}
expect: {
var a, b = 1, c = g;
a = 2;
function g() {}
console.log(b = 3);
}
}
drop_toplevel_vars: {
options = { toplevel: "vars", unused: true };
input: {
var a, b = 1, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
function h() {}
console.log(b = 3);
}
expect: {
var c = g;
function f(d) {
return function() {
c = 2;
}
}
2;
function g() {}
function h() {}
console.log(3);
}
}
drop_toplevel_vars_fargs: {
options = { keep_fargs: false, toplevel: "vars", unused: true };
input: {
var a, b = 1, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
function h() {}
console.log(b = 3);
}
expect: {
var c = g;
function f() {
return function() {
c = 2;
}
}
2;
function g() {}
function h() {}
console.log(3);
}
}
drop_toplevel_all: {
options = { toplevel: true, unused: true };
input: {
var a, b = 1, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
function h() {}
console.log(b = 3);
}
expect: {
2;
console.log(3);
}
}
drop_toplevel_retain: {
options = { top_retain: "f,a,o", unused: true };
input: {
var a, b = 1, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
function h() {}
console.log(b = 3);
}
expect: {
var a, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
console.log(3);
}
}
drop_toplevel_retain_array: {
options = { top_retain: [ "f", "a", "o" ], unused: true };
input: {
var a, b = 1, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
function h() {}
console.log(b = 3);
}
expect: {
var a, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
console.log(3);
}
}
drop_toplevel_retain_regex: {
options = { top_retain: /^[fao]$/, unused: true };
input: {
var a, b = 1, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
function h() {}
console.log(b = 3);
}
expect: {
var a, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
console.log(3);
}
}
drop_toplevel_all_retain: {
options = { toplevel: true, top_retain: "f,a,o", unused: true };
input: {
var a, b = 1, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
function h() {}
console.log(b = 3);
}
expect: {
var a, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
console.log(3);
}
}
drop_toplevel_funcs_retain: {
options = { toplevel: "funcs", top_retain: "f,a,o", unused: true };
input: {
var a, b = 1, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
function h() {}
console.log(b = 3);
}
expect: {
var a, b = 1, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
console.log(b = 3);
}
}
drop_toplevel_vars_retain: {
options = { toplevel: "vars", top_retain: "f,a,o", unused: true };
input: {
var a, b = 1, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
function h() {}
console.log(b = 3);
}
expect: {
var a, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
function h() {}
console.log(3);
}
}
drop_toplevel_keep_assign: {
options = { toplevel: true, unused: "keep_assign" };
input: {
var a, b = 1, c = g;
function f(d) {
return function() {
c = 2;
}
}
a = 2;
function g() {}
function h() {}
console.log(b = 3);
}
expect: {
var a, b = 1;
a = 2;
console.log(b = 3);
}
}
drop_fargs: {
options = {
keep_fargs: false,
unused: true,
}
input: {
function f(a) {
var b = a;
}
}
expect: {
function f() {}
}
}
drop_fnames: {
options = {
keep_fnames: false,
unused: true,
}
input: {
function f() {
return function g() {
var a = g;
};
}
}
expect: {
function f() {
return function() {};
}
}
}
global_var: {
options = {
side_effects: true,
unused: true,
}
input: {
var a;
function foo(b) {
a;
b;
c;
typeof c === "undefined";
c + b + a;
b && b.ar();
return b;
}
}
expect: {
var a;
function foo(b) {
c;
c;
b && b.ar();
return b;
}
}
}
iife: {
options = {
side_effects: true,
unused: true,
}
input: {
function f() {
var a;
~function() {}(b);
}
}
expect: {
function f() {
~function() {}(b);
}
}
}
drop_value: {
options = {
side_effects: true,
}
input: {
(1, [2, foo()], 3, {a:1, b:bar()});
}
expect: {
foo(), bar();
}
}
const_assign: {
options = {
evaluate: true,
reduce_vars: true,
unused: true,
}
input: {
function f() {
const b = 2;
return 1 + b;
}
function g() {
const b = 2;
b = 3;
return 1 + b;
}
}
expect: {
function f() {
return 3;
}
function g() {
const b = 2;
b = 3;
return 1 + b;
}
}
}

View File

@@ -692,3 +692,51 @@ unsafe_prototype_function: {
var h = "" + ({toString: 0});
}
}
call_args: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
const a = 1;
console.log(a);
+function(a) {
return a;
}(a);
}
expect: {
const a = 1;
console.log(1);
+function(a) {
return 1;
}(1);
}
}
in_boolean_context: {
options = {
booleans: true,
evaluate: true,
}
input: {
!42;
!"foo";
![1, 2];
!/foo/;
!b(42);
!b("foo");
!b([1, 2]);
!b(/foo/);
}
expect: {
!1;
!1;
!1;
!1;
!b(42);
!b("foo");
!b([1, 2]);
!b(/foo/);
}
}

View File

@@ -0,0 +1,147 @@
must_replace: {
options = {
global_defs: {
D: "foo bar",
}
}
input: {
console.log(D);
}
expect: {
console.log("foo bar");
}
}
keyword: {
options = {
global_defs: {
undefined: 0,
NaN: 1,
Infinity: 2,
},
}
input: {
console.log(undefined, NaN, Infinity);
}
expect: {
console.log(0, 1, 2);
}
}
object: {
options = {
evaluate: true,
global_defs: {
CONFIG: {
DEBUG: [ 0 ],
VALUE: 42,
},
},
unsafe: true,
}
input: {
function f(CONFIG) {
// CONFIG not global - do not replace
return CONFIG.VALUE;
}
function g() {
var CONFIG = { VALUE: 1 };
// CONFIG not global - do not replace
return CONFIG.VALUE;
}
function h() {
return CONFIG.VALUE;
}
if (CONFIG.DEBUG[0])
console.debug("foo");
}
expect: {
function f(CONFIG) {
return CONFIG.VALUE;
}
function g() {
var CONFIG = { VALUE: 1 };
return CONFIG.VALUE;
}
function h() {
return 42;
}
if (0)
console.debug("foo");
}
}
expanded: {
options = {
global_defs: {
"CONFIG.DEBUG": [ 0 ],
"CONFIG.VALUE": 42,
},
}
input: {
function f(CONFIG) {
// CONFIG not global - do not replace
return CONFIG.VALUE;
}
function g() {
var CONFIG = { VALUE: 1 };
// CONFIG not global - do not replace
return CONFIG.VALUE;
}
function h() {
return CONFIG.VALUE;
}
if (CONFIG.DEBUG[0])
console.debug("foo");
}
expect: {
function f(CONFIG) {
return CONFIG.VALUE;
}
function g() {
var CONFIG = { VALUE: 1 };
return CONFIG.VALUE;
}
function h() {
return 42;
}
if ([0][0])
console.debug("foo");
}
}
mixed: {
options = {
evaluate: true,
global_defs: {
"CONFIG.VALUE": 42,
"FOO.BAR": "moo",
},
properties: true,
}
input: {
const FOO = { BAR: 0 };
console.log(FOO.BAR);
console.log(++CONFIG.DEBUG);
console.log(++CONFIG.VALUE);
console.log(++CONFIG["VAL" + "UE"]);
console.log(++DEBUG[CONFIG.VALUE]);
CONFIG.VALUE.FOO = "bar";
console.log(CONFIG);
}
expect: {
const FOO = { BAR: 0 };
console.log("moo");
console.log(++CONFIG.DEBUG);
console.log(++CONFIG.VALUE);
console.log(++CONFIG.VALUE);
console.log(++DEBUG[42]);
CONFIG.VALUE.FOO = "bar";
console.log(CONFIG);
}
expect_warnings: [
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:126,22]',
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:127,22]',
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:129,8]',
]
}

View File

@@ -0,0 +1,90 @@
statements: {
options = {
hoist_funs: false,
hoist_vars: true,
}
input: {
function f() {
var a = 1;
var b = 2;
var c = 3;
function g() {}
return g(a, b, c);
}
}
expect: {
function f() {
var a = 1, b = 2, c = 3;
function g() {}
return g(a, b, c);
}
}
}
statements_funs: {
options = {
hoist_funs: true,
hoist_vars: true,
}
input: {
function f() {
var a = 1;
var b = 2;
var c = 3;
function g() {}
return g(a, b, c);
}
}
expect: {
function f() {
function g() {}
var a = 1, b = 2, c = 3;
return g(a, b, c);
}
}
}
sequences: {
options = {
hoist_funs: false,
hoist_vars: true,
}
input: {
function f() {
var a = 1, b = 2;
function g() {}
var c = 3;
return g(a, b, c);
}
}
expect: {
function f() {
var c, a = 1, b = 2;
function g() {}
c = 3;
return g(a, b, c);
}
}
}
sequences_funs: {
options = {
hoist_funs: true,
hoist_vars: true,
}
input: {
function f() {
var a = 1, b = 2;
function g() {}
var c = 3;
return g(a, b, c);
}
}
expect: {
function f() {
function g() {}
var a = 1, b = 2, c = 3;
return g(a, b, c);
}
}
}

View File

@@ -170,8 +170,51 @@ if_return_7: {
}
}
expect: {
// suboptimal
function f(x){return!!x||(foo(),void bar())}
function f(x){if(x)return!0;foo(),bar()}
}
}
if_return_8: {
options = {
if_return: true,
sequences: true,
conditionals: true,
side_effects : true,
}
input: {
function f(e) {
if (2 == e) return foo();
if (3 == e) return bar();
if (4 == e) return baz();
fail(e);
}
function g(e) {
if (a(e)) return foo();
if (b(e)) return bar();
if (c(e)) return baz();
fail(e);
}
function h(e) {
if (a(e)) return foo();
else if (b(e)) return bar();
else if (c(e)) return baz();
else fail(e);
}
function i(e) {
if (a(e)) return foo();
else if (b(e)) return bar();
else if (c(e)) return baz();
fail(e);
}
}
expect: {
function f(e){return 2==e?foo():3==e?bar():4==e?baz():void fail(e)}
function g(e){return a(e)?foo():b(e)?bar():c(e)?baz():void fail(e)}
function h(e){return a(e)?foo():b(e)?bar():c(e)?baz():void fail(e)}
function i(e){return a(e)?foo():b(e)?bar():c(e)?baz():void fail(e)}
}
}
@@ -205,3 +248,57 @@ issue_1089: {
}
}
}
issue_1437: {
options = {
if_return : true,
sequences : true,
conditionals : false
}
input: {
function x() {
if (a())
return b();
if (c())
return d();
else
e();
f();
}
}
expect: {
function x() {
if (a())
return b();
if (c())
return d();
else
e()
f();
}
}
}
issue_1437_conditionals: {
options = {
conditionals : true,
if_return : true,
sequences : true
}
input: {
function x() {
if (a())
return b();
if (c())
return d();
else
e();
f();
}
}
expect: {
function x() {
return a() ? b() : c() ? d() : (e(), f(), void 0);
}
}
}

View File

@@ -13,7 +13,8 @@ const_declaration: {
const_pragma: {
options = {
evaluate: true
evaluate: true,
reduce_vars: true,
};
input: {
@@ -27,7 +28,8 @@ const_pragma: {
// for completeness' sake
not_const: {
options = {
evaluate: true
evaluate: true,
reduce_vars: true,
};
input: {

View File

@@ -1,25 +0,0 @@
typeof_eq_undefined: {
options = {
comparisons: true
};
input: { a = typeof b.c != "undefined" }
expect: { a = "undefined" != typeof b.c }
}
typeof_eq_undefined_unsafe: {
options = {
comparisons: true,
unsafe: true
};
input: { a = typeof b.c != "undefined" }
expect: { a = void 0 !== b.c }
}
typeof_eq_undefined_unsafe2: {
options = {
comparisons: true,
unsafe: true
};
input: { a = "undefined" != typeof b.c }
expect: { a = void 0 !== b.c }
}

118
test/compress/issue-1261.js Normal file
View File

@@ -0,0 +1,118 @@
pure_function_calls: {
options = {
evaluate : true,
conditionals : true,
comparisons : true,
side_effects : true,
booleans : true,
unused : true,
if_return : true,
join_vars : true,
cascade : true,
negate_iife : true,
}
input: {
// pure top-level IIFE will be dropped
// @__PURE__ - comment
(function() {
console.log("iife0");
})();
// pure top-level IIFE assigned to unreferenced var will not be dropped
var iife1 = /*@__PURE__*/(function() {
console.log("iife1");
function iife1() {}
return iife1;
})();
(function(){
// pure IIFE in function scope assigned to unreferenced var will be dropped
var iife2 = /*#__PURE__*/(function() {
console.log("iife2");
function iife2() {}
return iife2;
})();
})();
// comment #__PURE__ comment
bar(), baz(), quux();
a.b(), /* @__PURE__ */ c.d.e(), f.g();
}
expect: {
var iife1 = function() {
console.log("iife1");
function iife1() {}
return iife1;
}();
baz(), quux();
a.b(), f.g();
}
expect_warnings: [
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:17,8]",
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:17,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:30,37]",
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:30,16]",
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:28,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:38,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:39,31]",
]
}
pure_function_calls_toplevel: {
options = {
evaluate : true,
conditionals : true,
comparisons : true,
side_effects : true,
booleans : true,
unused : true,
if_return : true,
join_vars : true,
cascade : true,
negate_iife : true,
toplevel : true,
}
input: {
// pure top-level IIFE will be dropped
// @__PURE__ - comment
(function() {
console.log("iife0");
})();
// pure top-level IIFE assigned to unreferenced var will be dropped
var iife1 = /*@__PURE__*/(function() {
console.log("iife1");
function iife1() {}
return iife1;
})();
(function(){
// pure IIFE in function scope assigned to unreferenced var will be dropped
var iife2 = /*#__PURE__*/(function() {
console.log("iife2");
function iife2() {}
return iife2;
})();
})();
// comment #__PURE__ comment
bar(), baz(), quux();
a.b(), /* @__PURE__ */ c.d.e(), f.g();
}
expect: {
baz(), quux();
a.b(), f.g();
}
expect_warnings: [
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:79,8]",
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:79,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:92,37]",
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:92,16]",
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:90,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:100,8]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:101,31]",
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:84,33]",
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:84,12]",
]
}

View File

@@ -1,3 +1,32 @@
level_zero: {
options = {
keep_fnames: true
}
mangle = {
keep_fnames: true
}
input: {
function f(x) {
function n(a) {
return a * a;
}
return function() {
return x;
};
}
}
expect: {
function f(r) {
function n(n) {
return n * n;
}
return function() {
return r;
};
}
}
}
level_one: {
options = {
keep_fnames: true

View File

@@ -0,0 +1,69 @@
// tests assume that variable `undefined` not redefined and has `void 0` as value
unsafe_undefined: {
options = {
if_return: true,
unsafe: true
}
mangle = {}
input: {
function f(undefined) {
return function() {
if (a)
return b;
if (c)
return d;
};
}
}
expect: {
function f(n) {
return function() {
if (a)
return b;
if (c)
return d;
else
return n;
};
}
}
}
keep_fnames: {
options = {
if_return: true,
unsafe: true
}
mangle = {
keep_fnames: true
}
input: {
function f(undefined) {
return function() {
function n(a) {
return a * a;
}
if (a)
return b;
if (c)
return d;
};
}
}
expect: {
function f(r) {
return function() {
function n(n) {
return n * n;
}
if (a)
return b;
if (c)
return d;
else
return r;
};
}
}
}

View File

@@ -0,0 +1,71 @@
typeof_eq_undefined: {
options = {
comparisons: true
}
input: {
var a = typeof b != "undefined";
b = typeof a != "undefined";
var c = typeof d.e !== "undefined";
var f = "undefined" === typeof g;
g = "undefined" === typeof f;
var h = "undefined" == typeof i.j;
}
expect: {
var a = "undefined" != typeof b;
b = void 0 !== a;
var c = void 0 !== d.e;
var f = "undefined" == typeof g;
g = void 0 === f;
var h = void 0 === i.j;
}
}
typeof_eq_undefined_ie8: {
options = {
comparisons: true,
screw_ie8: false
}
input: {
var a = typeof b != "undefined";
b = typeof a != "undefined";
var c = typeof d.e !== "undefined";
var f = "undefined" === typeof g;
g = "undefined" === typeof f;
var h = "undefined" == typeof i.j;
}
expect: {
var a = "undefined" != typeof b;
b = void 0 !== a;
var c = "undefined" != typeof d.e;
var f = "undefined" == typeof g;
g = void 0 === f;
var h = "undefined" == typeof i.j;
}
}
undefined_redefined: {
options = {
comparisons: true
}
input: {
function f(undefined) {
var n = 1;
return typeof n == "undefined";
}
}
expect_exact: "function f(undefined){var n=1;return void 0===n}"
}
undefined_redefined_mangle: {
options = {
comparisons: true
}
mangle = {}
input: {
function f(undefined) {
var n = 1;
return typeof n == "undefined";
}
}
expect_exact: "function f(n){var r=1;return void 0===r}"
}

View File

@@ -0,0 +1,45 @@
else_with_empty_block: {
options = {}
input: {
if (x)
yes();
else {
}
}
expect_exact: "if(x)yes();"
}
else_with_empty_statement: {
options = {}
input: {
if (x)
yes();
else
;
}
expect_exact: "if(x)yes();"
}
conditional_false_stray_else_in_loop: {
options = {
evaluate : true,
comparisons : true,
booleans : true,
unused : true,
loops : true,
side_effects : true,
dead_code : true,
hoist_vars : true,
join_vars : true,
if_return : true,
cascade : true,
conditionals : false,
}
input: {
for (var i = 1; i <= 4; ++i) {
if (i <= 2) continue;
console.log(i);
}
}
expect_exact: "for(var i=1;i<=4;++i)if(!(i<=2))console.log(i);"
}

View File

@@ -27,3 +27,44 @@ do_update_rhs: {
MY_DEBUG += 0;
}
}
mixed: {
options = {
evaluate: true,
global_defs: {
DEBUG: 0,
ENV: 1,
FOO: 2,
}
}
input: {
const ENV = 3;
var FOO = 4;
f(ENV * 10);
--FOO;
DEBUG = 1;
DEBUG++;
DEBUG += 1;
f(DEBUG);
x = DEBUG;
}
expect: {
const ENV = 3;
var FOO = 4;
f(10);
--FOO;
DEBUG = 1;
DEBUG++;
DEBUG += 1;
f(0);
x = 0;
}
expect_warnings: [
'WARN: global_defs ENV redefined [test/compress/issue-208.js:41,14]',
'WARN: global_defs FOO redefined [test/compress/issue-208.js:42,12]',
'WARN: global_defs FOO redefined [test/compress/issue-208.js:44,10]',
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:45,8]',
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:46,8]',
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:47,8]',
]
}

View File

@@ -82,7 +82,7 @@ issue979_test_negated_is_best: {
1!=a||2!=b||foo();
}
function f7() {
return 1!=a&&2!=b?bar():void foo();
if(1!=a&&2!=b)return bar();foo()
}
}
}

View File

@@ -187,3 +187,32 @@ keep_collapse_const_in_own_block_scope_2: {
console.log(c);
}
}
evaluate: {
options = {
loops: true,
dead_code: true,
evaluate: true,
};
input: {
while (true) {
a();
}
while (false) {
b();
}
do {
c();
} while (true);
do {
d();
} while (false);
}
expect: {
for(;;)
a();
for(;;)
c();
d();
}
}

View File

@@ -0,0 +1,28 @@
too_short: {
beautify = {
max_line_len: 10,
}
input: {
function f(a) {
return { c: 42, d: a(), e: "foo"};
}
}
expect_exact: 'function f(a){\nreturn{\nc:42,\nd:a(),\ne:"foo"}}'
expect_warnings: [
"WARN: Output exceeds 10 characters"
]
}
just_enough: {
beautify = {
max_line_len: 14,
}
input: {
function f(a) {
return { c: 42, d: a(), e: "foo"};
}
}
expect_exact: 'function f(a){\nreturn{c:42,\nd:a(),e:"foo"}\n}'
expect_warnings: [
]
}

View File

@@ -10,6 +10,16 @@ negate_iife_1: {
}
}
negate_iife_1_off: {
options = {
negate_iife: false,
};
input: {
(function(){ stuff() })();
}
expect_exact: '(function(){stuff()})();'
}
negate_iife_2: {
options = {
negate_iife: true
@@ -25,6 +35,7 @@ negate_iife_2: {
negate_iife_3: {
options = {
negate_iife: true,
conditionals: true
};
input: {
(function(){ return true })() ? console.log(true) : console.log(false);
@@ -34,9 +45,23 @@ negate_iife_3: {
}
}
negate_iife_3: {
negate_iife_3_off: {
options = {
negate_iife: false,
conditionals: true,
};
input: {
(function(){ return true })() ? console.log(true) : console.log(false);
}
expect: {
!function(){ return true }() ? console.log(false) : console.log(true);
}
}
negate_iife_4: {
options = {
negate_iife: true,
conditionals: true,
sequences: true
};
input: {
@@ -52,7 +77,42 @@ negate_iife_3: {
}
}
negate_iife_4: {
sequence_off: {
options = {
negate_iife: false,
conditionals: true,
sequences: true,
passes: 2,
};
input: {
function f() {
(function(){ return true })() ? console.log(true) : console.log(false);
(function(){
console.log("something");
})();
}
function g() {
(function(){
console.log("something");
})();
(function(){ return true })() ? console.log(true) : console.log(false);
}
}
expect: {
function f() {
!function(){ return true }() ? console.log(false) : console.log(true), function(){
console.log("something");
}();
}
function g() {
(function(){
console.log("something");
})(), function(){ return true }() ? console.log(true) : console.log(false);
}
}
}
negate_iife_5: {
options = {
negate_iife: true,
sequences: true,
@@ -75,6 +135,29 @@ negate_iife_4: {
}
}
negate_iife_5_off: {
options = {
negate_iife: false,
sequences: true,
conditionals: true,
};
input: {
if ((function(){ return true })()) {
foo(true);
} else {
bar(false);
}
(function(){
console.log("something");
})();
}
expect: {
!function(){ return true }() ? bar(false) : foo(true), function(){
console.log("something");
}();
}
}
negate_iife_nested: {
options = {
negate_iife: true,
@@ -107,6 +190,38 @@ negate_iife_nested: {
}
}
negate_iife_nested_off: {
options = {
negate_iife: false,
sequences: true,
conditionals: true,
};
input: {
function Foo(f) {
this.f = f;
}
new Foo(function() {
(function(x) {
(function(y) {
console.log(y);
})(x);
})(7);
}).f();
}
expect: {
function Foo(f) {
this.f = f;
}
new Foo(function() {
(function(x) {
(function(y) {
console.log(y);
})(x);
})(7);
}).f();
}
}
negate_iife_issue_1073: {
options = {
negate_iife: true,
@@ -172,3 +287,36 @@ issue_1254_negate_iife_nested: {
}
expect_exact: '!function(){return function(){console.log("test")}}()()()()();'
}
issue_1288: {
options = {
negate_iife: true,
conditionals: true,
};
input: {
if (w) ;
else {
(function f() {})();
}
if (!x) {
(function() {
x = {};
})();
}
if (y)
(function() {})();
else
(function(z) {
return z;
})(0);
}
expect: {
w || function f() {}();
x || function() {
x = {};
}();
y ? function() {}() : function(z) {
return z;
}(0);
}
}

View File

@@ -540,3 +540,19 @@ first_256_hex_chars_as_properties: {
};
}
}
native_prototype: {
options = {
unsafe_proto: true,
}
input: {
Array.prototype.splice.apply(a, [1, 2, b, c]);
Object.prototype.hasOwnProperty.call(d, "foo");
String.prototype.indexOf.call(e, "bar");
}
expect: {
[].splice.apply(a, [1, 2, b, c]);
({}).hasOwnProperty.call(d, "foo");
"".indexOf.call(e, "bar");
}
}

295
test/compress/pure_funcs.js Normal file
View File

@@ -0,0 +1,295 @@
array: {
options = {
pure_funcs: [ "Math.floor" ],
side_effects: true,
}
input: {
var a;
function f(b) {
Math.floor(a / b);
Math.floor(c / b);
}
}
expect: {
var a;
function f(b) {
c;
}
}
}
func: {
options = {
pure_funcs: function(node) {
return !~node.args[0].print_to_string().indexOf("a");
},
side_effects: true,
}
input: {
function f(a, b) {
Math.floor(a / b);
Math.floor(c / b);
}
}
expect: {
function f(a, b) {
Math.floor(c / b);
}
}
}
side_effects: {
options = {
pure_funcs: [ "console.log" ],
side_effects: true,
}
input: {
function f(a, b) {
console.log(a());
console.log(b);
}
}
expect: {
function f(a, b) {
a();
}
}
}
unused: {
options = {
pure_funcs: [ "pure" ],
side_effects: true,
unused: true,
}
input: {
function foo() {
var u = pure(1);
var x = pure(2);
var y = pure(x);
var z = pure(pure(side_effects()));
return pure(3);
}
}
expect: {
function foo() {
side_effects();
return pure(3);
}
}
}
babel: {
options = {
pure_funcs: [ "_classCallCheck" ],
side_effects: true,
unused: true,
}
input: {
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor))
throw new TypeError("Cannot call a class as a function");
}
var Foo = function Foo() {
_classCallCheck(this, Foo);
};
}
expect: {
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor))
throw new TypeError("Cannot call a class as a function");
}
var Foo = function() {
};
}
}
conditional: {
options = {
pure_funcs: [ "pure" ],
side_effects: true,
}
input: {
pure(1 | a() ? 2 & b() : 7 ^ c());
pure(1 | a() ? 2 & b() : 5);
pure(1 | a() ? 4 : 7 ^ c());
pure(1 | a() ? 4 : 5);
pure(3 ? 2 & b() : 7 ^ c());
pure(3 ? 2 & b() : 5);
pure(3 ? 4 : 7 ^ c());
pure(3 ? 4 : 5);
}
expect: {
1 | a() ? b() : c();
1 | a() && b();
1 | a() || c();
a();
3 ? b() : c();
3 && b();
3 || c();
}
}
relational: {
options = {
pure_funcs: [ "foo" ],
side_effects :true,
}
input: {
foo() in foo();
foo() instanceof bar();
foo() < "bar";
bar() > foo();
bar() != bar();
bar() !== "bar";
"bar" == foo();
"bar" === bar();
"bar" >= "bar";
}
expect: {
bar();
bar();
bar(), bar();
bar();
bar();
}
}
arithmetic: {
options = {
pure_funcs: [ "foo" ],
side_effects :true,
}
input: {
foo() + foo();
foo() - bar();
foo() * "bar";
bar() / foo();
bar() & bar();
bar() | "bar";
"bar" >> foo();
"bar" << bar();
"bar" >>> "bar";
}
expect: {
bar();
bar();
bar(), bar();
bar();
bar();
}
}
boolean_and: {
options = {
pure_funcs: [ "foo" ],
side_effects :true,
}
input: {
foo() && foo();
foo() && bar();
foo() && "bar";
bar() && foo();
bar() && bar();
bar() && "bar";
"bar" && foo();
"bar" && bar();
"bar" && "bar";
}
expect: {
foo() && bar();
bar();
bar() && bar();
bar();
"bar" && bar();
}
}
boolean_or: {
options = {
pure_funcs: [ "foo" ],
side_effects :true,
}
input: {
foo() || foo();
foo() || bar();
foo() || "bar";
bar() || foo();
bar() || bar();
bar() || "bar";
"bar" || foo();
"bar" || bar();
"bar" || "bar";
}
expect: {
foo() || bar();
bar();
bar() || bar();
bar();
"bar" || bar();
}
}
assign: {
options = {
pure_funcs: [ "foo" ],
side_effects :true,
}
input: {
var a;
function f(b) {
a = foo();
b *= 4 + foo();
c >>= 0 | foo();
}
}
expect: {
var a;
function f(b) {
a = foo();
b *= 4 + foo();
c >>= 0 | foo();
}
}
}
unary: {
options = {
pure_funcs: [ "foo" ],
side_effects :true,
}
input: {
typeof foo();
typeof bar();
typeof "bar";
void foo();
void bar();
void "bar";
delete a[foo()];
delete a[bar()];
delete a["bar"];
a[foo()]++;
a[bar()]++;
a["bar"]++;
--a[foo()];
--a[bar()];
--a["bar"];
~foo();
~bar();
~"bar";
}
expect: {
bar();
bar();
delete a[foo()];
delete a[bar()];
delete a["bar"];
a[foo()]++;
a[bar()]++;
a["bar"]++;
--a[foo()];
--a[bar()];
--a["bar"];
bar();
}
}

View File

@@ -108,8 +108,6 @@ modified: {
}
console.log(a + b);
console.log(b + c);
// TODO: as "modified" is determined in "figure_out_scope",
// even "passes" wouldn't improve this any further
console.log(a + c);
console.log(a + b + c);
}
@@ -136,8 +134,8 @@ modified: {
}
function f2() {
var b = 2, c = 3;
b = c;
var b = 2;
b = 3;
console.log(1 + b);
console.log(b + 3);
console.log(4);
@@ -145,8 +143,8 @@ modified: {
}
function f3() {
var b = 2, c = 3;
b *= c;
var b = 2;
b *= 3;
console.log(1 + b);
console.log(b + 3);
console.log(4);
@@ -238,7 +236,7 @@ unsafe_evaluate_object: {
function f0(){
var a = 1;
var b = {};
b[a] = 2;
b[1] = 2;
console.log(4);
}
@@ -282,7 +280,7 @@ unsafe_evaluate_array: {
function f0(){
var a = 1;
var b = [];
b[a] = 2;
b[1] = 2;
console.log(4);
}
@@ -350,3 +348,125 @@ unsafe_evaluate_equality: {
}
}
}
passes: {
options = {
conditionals: true,
evaluate: true,
passes: 2,
reduce_vars: true,
unused: true,
}
input: {
function f() {
var a = 1, b = 2, c = 3;
if (a) {
b = c;
} else {
c = b;
}
console.log(a + b);
console.log(b + c);
console.log(a + c);
console.log(a + b + c);
}
}
expect: {
function f() {
var b = 2;
b = 3;
console.log(1 + b);
console.log(b + 3);
console.log(4);
console.log(1 + b + 3);
}
}
}
iife: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
!function(a, b, c) {
b++;
console.log(a - 1, b * 1, c + 2);
}(1, 2, 3);
}
expect: {
!function(a, b, c) {
b++;
console.log(0, 1 * b, 5);
}(1, 2, 3);
}
}
iife_new: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
var A = new function(a, b, c) {
b++;
console.log(a - 1, b * 1, c + 2);
}(1, 2, 3);
}
expect: {
var A = new function(a, b, c) {
b++;
console.log(0, 1 * b, 5);
}(1, 2, 3);
}
}
multi_def: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
function f(a) {
if (a)
var b = 1;
else
var b = 2
console.log(b + 1);
}
}
expect: {
function f(a) {
if (a)
var b = 1;
else
var b = 2
console.log(b + 1);
}
}
}
multi_def_2: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
if (code == 16)
var bitsLength = 2, bitsOffset = 3, what = len;
else if (code == 17)
var bitsLength = 3, bitsOffset = 3, what = (len = 0);
else if (code == 18)
var bitsLength = 7, bitsOffset = 11, what = (len = 0);
var repeatLength = this.getBits(bitsLength) + bitsOffset;
}
expect: {
if (16 == code)
var bitsLength = 2, bitsOffset = 3, what = len;
else if (17 == code)
var bitsLength = 3, bitsOffset = 3, what = (len = 0);
else if (18 == code)
var bitsLength = 7, bitsOffset = 11, what = (len = 0);
var repeatLength = this.getBits(bitsLength) + bitsOffset;
}
}

View File

@@ -169,3 +169,85 @@ for_sequences: {
for (y = 5; false;);
}
}
limit_1: {
options = {
sequences: 3,
};
input: {
a;
b;
c;
d;
e;
f;
g;
h;
i;
j;
k;
}
expect: {
a, b, c;
d, e, f;
g, h, i;
j, k;
}
}
limit_2: {
options = {
sequences: 3,
};
input: {
a, b;
c, d;
e, f;
g, h;
i, j;
k;
}
expect: {
a, b, c, d;
e, f, g, h;
i, j, k;
}
}
negate_iife_for: {
options = {
sequences: true,
negate_iife: true,
};
input: {
(function() {})();
for (i = 0; i < 5; i++) console.log(i);
(function() {})();
for (; i < 5; i++) console.log(i);
}
expect: {
for (!function() {}(), i = 0; i < 5; i++) console.log(i);
for (function() {}(); i < 5; i++) console.log(i);
}
}
iife: {
options = {
sequences: true,
};
input: {
x = 42;
(function a() {})();
!function b() {}();
~function c() {}();
+function d() {}();
-function e() {}();
void function f() {}();
typeof function g() {}();
}
expect: {
x = 42, function a() {}(), function b() {}(), function c() {}(),
function d() {}(), function e() {}(), function f() {}(), function g() {}()
}
}

View File

@@ -0,0 +1 @@
console.log(C.V, C.D);

View File

@@ -0,0 +1 @@
console.log(D);

View File

@@ -0,0 +1 @@
foo, bar(

View File

@@ -0,0 +1 @@
function f(a{}

View File

@@ -0,0 +1 @@
foo( xyz, 0abc);

View File

@@ -0,0 +1,73 @@
if (x) {
foo();
}
if (x) {
foo();
} else {
baz();
}
if (x) {
foo();
} else if (y) {
bar();
} else {
baz();
}
if (x) {
if (y) {
foo();
} else {
bar();
}
} else {
baz();
}
if (x) {
foo();
} else if (y) {
bar();
} else if (z) {
baz();
} else {
moo();
}
function f() {
if (x) {
foo();
}
if (x) {
foo();
} else {
baz();
}
if (x) {
foo();
} else if (y) {
bar();
} else {
baz();
}
if (x) {
if (y) {
foo();
} else {
bar();
}
} else {
baz();
}
if (x) {
foo();
} else if (y) {
bar();
} else if (z) {
baz();
} else {
moo();
}
}

View File

@@ -0,0 +1,17 @@
if (x) foo();
if (x) foo(); else baz();
if (x) foo(); else if (y) bar(); else baz();
if (x) if (y) foo(); else bar(); else baz();
if (x) foo(); else if (y) bar(); else if (z) baz(); else moo();
function f() {
if (x) foo();
if (x) foo(); else baz();
if (x) foo(); else if (y) bar(); else baz();
if (x) if (y) foo(); else bar(); else baz();
if (x) foo(); else if (y) bar(); else if (z) baz(); else moo();
}

View File

@@ -0,0 +1,12 @@
if (x) foo();
if (x) foo(); else baz();
if (x) foo(); else if (y) bar(); else baz();
if (x) if (y) foo(); else bar(); else baz();
if (x) foo(); else if (y) bar(); else if (z) baz(); else moo();
function f() {
if (x) foo();
if (x) foo(); else baz();
if (x) foo(); else if (y) bar(); else baz();
if (x) if (y) foo(); else bar(); else baz();
if (x) foo(); else if (y) bar(); else if (z) baz(); else moo();
}

View File

@@ -0,0 +1,3 @@
var Foo = function Foo(){console.log(1+2);}; new Foo();
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLElBQU0sR0FBRyxHQUFDLEFBQUUsWUFBVyxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBLEFBQUUsQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDOyJ9

View File

@@ -0,0 +1,2 @@
new function(){console.log(3)};
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUErQyxHQUFyQyxZQUFnQkEsUUFBUUMsSUFBSSIsInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl19

87
test/jetstream.js Normal file
View File

@@ -0,0 +1,87 @@
#! /usr/bin/env node
// -*- js -*-
"use strict";
var site = "http://browserbench.org/JetStream/";
if (typeof phantom == "undefined") {
// workaround for tty output truncation upon process.exit()
[process.stdout, process.stderr].forEach(function(stream){
if (stream._handle && stream._handle.setBlocking)
stream._handle.setBlocking(true);
});
var args = process.argv.slice(2);
if (!args.length) {
args.push("-mc", "warnings=false");
}
args.push("--stats");
var child_process = require("child_process");
try {
require("phantomjs-prebuilt");
} catch(e) {
child_process.execSync("npm install phantomjs-prebuilt@2.1.14");
}
var http = require("http");
var server = http.createServer(function(request, response) {
request.resume();
var url = decodeURIComponent(request.url.slice(1));
var stderr = "";
var uglifyjs = child_process.fork("bin/uglifyjs", args, {
silent: true
}).on("exit", function(code) {
console.log("uglifyjs", url.indexOf(site) == 0 ? url.slice(site.length) : url, args.join(" "));
console.log(stderr);
if (code) throw new Error("uglifyjs failed with code " + code);
});
uglifyjs.stderr.on("data", function(data) {
stderr += data;
}).setEncoding("utf8");
uglifyjs.stdout.pipe(response);
http.get(url, function(res) {
res.pipe(uglifyjs.stdin);
});
}).listen().on("listening", function() {
var phantomjs = require("phantomjs-prebuilt");
var program = phantomjs.exec(process.argv[1], server.address().port);
program.stdout.pipe(process.stdout);
program.stderr.pipe(process.stderr);
program.on("exit", function(code) {
server.close();
if (code) throw new Error("JetStream failed!");
console.log("JetStream completed successfully.");
});
});
server.timeout = 0;
} else {
var page = require("webpage").create();
page.onError = function(msg, trace) {
var body = [ msg ];
if (trace) trace.forEach(function(t) {
body.push(" " + (t.function || "Anonymous function") + " (" + t.file + ":" + t.line + ")");
});
console.error(body.join("\n"));
phantom.exit(1);
};
var url = "http://localhost:" + require("system").args[1] + "/";
page.onResourceRequested = function(requestData, networkRequest) {
if (/\.js$/.test(requestData.url))
networkRequest.changeUrl(url + encodeURIComponent(requestData.url));
}
page.onConsoleMessage = function(msg) {
if (/Error:/i.test(msg)) {
console.error(msg);
phantom.exit(1);
}
console.log(msg);
if (~msg.indexOf("Raw results:")) {
phantom.exit();
}
};
page.open(site, function(status) {
if (status != "success") phantomjs.exit(1);
page.evaluate(function() {
JetStream.switchToQuick();
JetStream.start();
});
});
}

View File

@@ -0,0 +1,32 @@
var UglifyJS = require('../../');
var assert = require("assert");
describe("Accessor tokens", function() {
it("Should fill the token information for accessors (issue #1492)", function() {
// location 0 1 2 3 4
// 01234567890123456789012345678901234567890123456789
var ast = UglifyJS.parse("var obj = { get latest() { return undefined; } }");
// test all AST_ObjectProperty tokens are set as expected
var checkedAST_ObjectProperty = false;
var checkWalker = new UglifyJS.TreeWalker(function(node, descend) {
if (node instanceof UglifyJS.AST_ObjectProperty) {
checkedAST_ObjectProperty = true;
assert.equal(node.start.pos, 12);
assert.equal(node.end.endpos, 46);
assert(node.key instanceof UglifyJS.AST_SymbolRef);
assert.equal(node.key.start.pos, 16);
assert.equal(node.key.end.endpos, 22);
assert(node.value instanceof UglifyJS.AST_Accessor);
assert.equal(node.value.start.pos, 22);
assert.equal(node.value.end.endpos, 46);
}
});
ast.walk(checkWalker);
assert(checkedAST_ObjectProperty, "AST_ObjectProperty not found");
});
});

View File

@@ -1,5 +1,6 @@
var assert = require("assert");
var exec = require("child_process").exec;
var readFileSync = require("fs").readFileSync;
describe("bin/uglifyjs", function () {
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
@@ -100,4 +101,141 @@ describe("bin/uglifyjs", function () {
done();
});
});
it("Should work with --define (simple)", function (done) {
var command = uglifyjscmd + ' test/input/global_defs/simple.js --define D=5 -c';
exec(command, function (err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "console.log(5);\n");
done();
});
});
it("Should work with --define (nested)", function (done) {
var command = uglifyjscmd + ' test/input/global_defs/nested.js --define C.D=5,C.V=3 -c';
exec(command, function (err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "console.log(3,5);\n");
done();
});
});
it("Should work with --define (AST_Node)", function (done) {
var command = uglifyjscmd + ' test/input/global_defs/simple.js --define console.log=stdout.println -c';
exec(command, function (err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, "stdout.println(D);\n");
done();
});
});
it("Should work with `--beautify`", function (done) {
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b';
exec(command, function (err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, readFileSync("test/input/issue-1482/default.js", "utf8"));
done();
});
});
it("Should work with `--beautify bracketize`", function (done) {
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b bracketize';
exec(command, function (err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, readFileSync("test/input/issue-1482/bracketize.js", "utf8"));
done();
});
});
it("Should process inline source map", function(done) {
var command = uglifyjscmd + ' test/input/issue-520/input.js -cm toplevel --in-source-map inline --source-map-inline';
exec(command, function (err, stdout) {
if (err) throw err;
assert.strictEqual(stdout, readFileSync("test/input/issue-520/output.js", "utf8"));
done();
});
});
it("Should warn for missing inline source map", function(done) {
var command = uglifyjscmd + ' test/input/issue-1323/sample.js --in-source-map inline';
exec(command, function (err, stdout, stderr) {
if (err) throw err;
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n");
assert.strictEqual(stderr, "WARN: inline source map not found\n");
done();
});
});
it("Should fail with multiple input and inline source map", function(done) {
var command = uglifyjscmd + ' test/input/issue-520/input.js test/input/issue-520/output.js --in-source-map inline --source-map-inline';
exec(command, function (err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stderr, "ERROR: Inline source map only works with singular input\n");
done();
});
});
it("Should fail with acorn and inline source map", function(done) {
var command = uglifyjscmd + ' test/input/issue-520/input.js --in-source-map inline --source-map-inline --acorn';
exec(command, function (err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stderr, "ERROR: Inline source map only works with built-in parser\n");
done();
});
});
it("Should fail with SpiderMonkey and inline source map", function(done) {
var command = uglifyjscmd + ' test/input/issue-520/input.js --in-source-map inline --source-map-inline --spidermonkey';
exec(command, function (err, stdout, stderr) {
assert.ok(err);
assert.strictEqual(stderr, "ERROR: Inline source map only works with built-in parser\n");
done();
});
});
it("Should fail with invalid syntax", function(done) {
var command = uglifyjscmd + ' test/input/invalid/simple.js';
exec(command, function (err, stdout, stderr) {
assert.ok(err);
var lines = stderr.split(/\n/);
assert.strictEqual(lines[0], "Parse error at test/input/invalid/simple.js:1,12");
assert.strictEqual(lines[1], "function f(a{}");
assert.strictEqual(lines[2], " ^");
assert.strictEqual(lines[3], "SyntaxError: Unexpected token punc «{», expected punc «,»");
done();
});
});
it("Should fail with correct marking of tabs", function(done) {
var command = uglifyjscmd + ' test/input/invalid/tab.js';
exec(command, function (err, stdout, stderr) {
assert.ok(err);
var lines = stderr.split(/\n/);
assert.strictEqual(lines[0], "Parse error at test/input/invalid/tab.js:1,12");
assert.strictEqual(lines[1], "\t\tfoo(\txyz, 0abc);");
assert.strictEqual(lines[2], "\t\t \t ^");
assert.strictEqual(lines[3], "SyntaxError: Invalid syntax: 0abc");
done();
});
});
it("Should fail with correct marking at start of line", function(done) {
var command = uglifyjscmd + ' test/input/invalid/eof.js';
exec(command, function (err, stdout, stderr) {
assert.ok(err);
var lines = stderr.split(/\n/);
assert.strictEqual(lines[0], "Parse error at test/input/invalid/eof.js:2,0");
assert.strictEqual(lines[1], "foo, bar(");
assert.strictEqual(lines[2], " ^");
assert.strictEqual(lines[3], "SyntaxError: Unexpected token: eof (undefined)");
done();
});
});
});

View File

@@ -13,7 +13,7 @@ describe("Comment", function() {
var fail = function(e) {
return e instanceof uglify.JS_Parse_Error &&
e.message === "SyntaxError: Unexpected token: operator (>)" &&
e.message === "Unexpected token: operator (>)" &&
e.line === 2 &&
e.col === 0;
}
@@ -37,7 +37,7 @@ describe("Comment", function() {
var fail = function(e) {
return e instanceof uglify.JS_Parse_Error &&
e.message === "SyntaxError: Unexpected token: operator (>)" &&
e.message === "Unexpected token: operator (>)" &&
e.line === 5 &&
e.col === 0;
}

View File

@@ -7,7 +7,7 @@ describe("comment before constant", function() {
it("Should test comment before constant is retained and output after mangle.", function() {
var result = Uglify.minify(js, {
fromString: true,
compress: { collapse_vars: false },
compress: { collapse_vars: false, reduce_vars: false },
mangle: {},
output: { comments: true },
});
@@ -17,9 +17,9 @@ describe("comment before constant", function() {
it("Should test code works when comments disabled.", function() {
var result = Uglify.minify(js, {
fromString: true,
compress: { collapse_vars: false },
compress: { collapse_vars: false, reduce_vars: false },
mangle: {},
output: {},
output: { comments: false },
});
assert.strictEqual(result.code, 'function f(){var n=!1;return n}');
});

View File

@@ -178,7 +178,7 @@ describe("Directives", function() {
throw new Error("Expected parser to fail");
} catch (e) {
assert.strictEqual(e instanceof uglify.JS_Parse_Error, true);
assert.strictEqual(e.message, "SyntaxError: Unexpected token: punc (])");
assert.strictEqual(e.message, "Unexpected token: punc (])");
}
test_directive(tokenizer, tests[i]);

View File

@@ -0,0 +1,89 @@
var UglifyJS = require('../../');
var assert = require("assert");
describe("Getters and setters", function() {
it("Should not accept operator symbols as getter/setter name", function() {
var illegalOperators = [
"++",
"--",
"+",
"-",
"!",
"~",
"&",
"|",
"^",
"*",
"/",
"%",
">>",
"<<",
">>>",
"<",
">",
"<=",
">=",
"==",
"===",
"!=",
"!==",
"?",
"=",
"+=",
"-=",
"/=",
"*=",
"%=",
">>=",
"<<=",
">>>=",
"|=",
"^=",
"&=",
"&&",
"||"
];
var generator = function() {
var results = [];
for (var i in illegalOperators) {
results.push({
code: "var obj = { get " + illegalOperators[i] + "() { return test; }};",
operator: illegalOperators[i],
method: "get"
});
results.push({
code: "var obj = { set " + illegalOperators[i] + "(value) { test = value}};",
operator: illegalOperators[i],
method: "set"
});
}
return results;
};
var testCase = function(data) {
return function() {
UglifyJS.parse(data.code);
};
};
var fail = function(data) {
return function (e) {
return e instanceof UglifyJS.JS_Parse_Error &&
e.message === "Invalid getter/setter name: " + data.operator;
};
};
var errorMessage = function(data) {
return "Expected but didn't get a syntax error while parsing following line:\n" + data.code;
};
var tests = generator();
for (var i = 0; i < tests.length; i++) {
var test = tests[i];
assert.throws(testCase(test), fail(test), errorMessage(test));
}
});
});

View File

@@ -50,7 +50,7 @@ describe("line-endings", function() {
}
var fail = function(e) {
return e instanceof Uglify.JS_Parse_Error &&
e.message === "SyntaxError: Unexpected line terminator";
e.message === "Unexpected line terminator";
}
for (var i = 0; i < inputs.length; i++) {
assert.throws(test(inputs[i]), fail);

View File

@@ -1,5 +1,6 @@
var Uglify = require('../../');
var assert = require("assert");
var readFileSync = require("fs").readFileSync;
describe("minify", function() {
it("Should test basic sanity of minify with default options", function() {
@@ -75,6 +76,51 @@ describe("minify", function() {
assert.equal(map.sourcesContent[0],
'let foo = x => "foo " + x;\nconsole.log(foo("bar"));');
});
it("Should process inline source map", function() {
var code = Uglify.minify("./test/input/issue-520/input.js", {
inSourceMap: "inline",
sourceMapInline: true
}).code + "\n";
assert.strictEqual(code, readFileSync("test/input/issue-520/output.js", "utf8"));
});
it("Should warn for missing inline source map", function() {
var warn_function = Uglify.AST_Node.warn_function;
var warnings = [];
Uglify.AST_Node.warn_function = function(txt) {
warnings.push(txt);
};
try {
var result = Uglify.minify("./test/input/issue-1323/sample.js", {
inSourceMap: "inline",
mangle: false,
});
assert.strictEqual(result.code, "var bar=function(){function foo(bar){return bar}return foo}();");
assert.strictEqual(warnings.length, 1);
assert.strictEqual(warnings[0], "inline source map not found");
} finally {
Uglify.AST_Node.warn_function = warn_function;
}
});
it("Should fail with multiple input and inline source map", function() {
assert.throws(function() {
Uglify.minify([
"./test/input/issue-520/input.js",
"./test/input/issue-520/output.js"
], {
inSourceMap: "inline",
sourceMapInline: true
});
});
});
it("Should fail with SpiderMonkey and inline source map", function() {
assert.throws(function() {
Uglify.minify("./test/input/issue-520/input.js", {
inSourceMap: "inline",
sourceMapInline: true,
spidermonkey: true
});
});
});
});
describe("sourceMapInline", function() {
@@ -95,4 +141,34 @@ describe("minify", function() {
assert.strictEqual(code, "var a=function(n){return n};");
});
});
describe("#__PURE__", function() {
it("should drop #__PURE__ hint after use", function() {
var result = Uglify.minify('//@__PURE__ comment1 #__PURE__ comment2\n foo(), bar();', {
fromString: true,
output: {
comments: "all",
beautify: false,
}
});
var code = result.code;
assert.strictEqual(code, "// comment1 comment2\nbar();");
});
});
describe("JS_Parse_Error", function() {
it("should throw syntax error", function() {
assert.throws(function() {
Uglify.minify("function f(a{}", { fromString: true });
}, function(err) {
assert.ok(err instanceof Error);
assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token punc «{», expected punc «,»");
assert.strictEqual(err.filename, 0);
assert.strictEqual(err.line, 1);
assert.strictEqual(err.col, 12);
return true;
});
});
});
});

View File

@@ -15,7 +15,7 @@ describe("Number literals", function () {
}
var error = function(e) {
return e instanceof uglify.JS_Parse_Error &&
e.message === "SyntaxError: Legacy octal literals are not allowed in strict mode";
e.message === "Legacy octal literals are not allowed in strict mode";
}
for (var i = 0; i < inputs.length; i++) {
assert.throws(test(inputs[i]), error, inputs[i]);

489
test/mocha/operator.js Normal file
View File

@@ -0,0 +1,489 @@
var UglifyJS = require("../../");
var assert = require("assert");
describe("operator", function() {
it("Should handle mixing of ++/+/--/- correctly", function() {
function evaluate(exp) {
return new Function("var a=1,b=2,c=" + exp + ";return{a:a,b:b,c:c}")();
}
[ "", "+", "-" ].forEach(function(p) {
[ "++a", "--a", "a", "a--", "a++" ].forEach(function(a) {
[ "+", "-" ].forEach(function(o) {
[ "", "+", "-" ].forEach(function(q) {
[ "++b", "--b", "b", "b--", "b++" ].forEach(function(b) {
var exp = [p, a, o, q, b].join(" ");
var orig = evaluate(exp);
var uglify = evaluate(UglifyJS.parse(exp).print_to_string());
assert.strictEqual(orig.a, uglify.a);
assert.strictEqual(orig.b, uglify.b);
assert.strictEqual(orig.c, uglify.c);
var beautify = evaluate(UglifyJS.parse(exp).print_to_string({
beautify: true
}));
assert.strictEqual(orig.a, beautify.a);
assert.strictEqual(orig.b, beautify.b);
assert.strictEqual(orig.c, beautify.c);
});
});
});
});
});
});
it("Should remove extraneous spaces", function() {
[
[ "++a + ++b", "++a+ ++b" ],
[ "++a + --b", "++a+--b" ],
[ "++a + b", "++a+b" ],
[ "++a + b--", "++a+b--" ],
[ "++a + b++", "++a+b++" ],
[ "++a + + ++b", "++a+ + ++b" ],
[ "++a + + --b", "++a+ +--b" ],
[ "++a + + b", "++a+ +b" ],
[ "++a + + b--", "++a+ +b--" ],
[ "++a + + b++", "++a+ +b++" ],
[ "++a + - ++b", "++a+-++b" ],
[ "++a + - --b", "++a+- --b" ],
[ "++a + - b", "++a+-b" ],
[ "++a + - b--", "++a+-b--" ],
[ "++a + - b++", "++a+-b++" ],
[ "++a - ++b", "++a-++b" ],
[ "++a - --b", "++a- --b" ],
[ "++a - b", "++a-b" ],
[ "++a - b--", "++a-b--" ],
[ "++a - b++", "++a-b++" ],
[ "++a - + ++b", "++a-+ ++b" ],
[ "++a - + --b", "++a-+--b" ],
[ "++a - + b", "++a-+b" ],
[ "++a - + b--", "++a-+b--" ],
[ "++a - + b++", "++a-+b++" ],
[ "++a - - ++b", "++a- -++b" ],
[ "++a - - --b", "++a- - --b" ],
[ "++a - - b", "++a- -b" ],
[ "++a - - b--", "++a- -b--" ],
[ "++a - - b++", "++a- -b++" ],
[ "--a + ++b", "--a+ ++b" ],
[ "--a + --b", "--a+--b" ],
[ "--a + b", "--a+b" ],
[ "--a + b--", "--a+b--" ],
[ "--a + b++", "--a+b++" ],
[ "--a + + ++b", "--a+ + ++b" ],
[ "--a + + --b", "--a+ +--b" ],
[ "--a + + b", "--a+ +b" ],
[ "--a + + b--", "--a+ +b--" ],
[ "--a + + b++", "--a+ +b++" ],
[ "--a + - ++b", "--a+-++b" ],
[ "--a + - --b", "--a+- --b" ],
[ "--a + - b", "--a+-b" ],
[ "--a + - b--", "--a+-b--" ],
[ "--a + - b++", "--a+-b++" ],
[ "--a - ++b", "--a-++b" ],
[ "--a - --b", "--a- --b" ],
[ "--a - b", "--a-b" ],
[ "--a - b--", "--a-b--" ],
[ "--a - b++", "--a-b++" ],
[ "--a - + ++b", "--a-+ ++b" ],
[ "--a - + --b", "--a-+--b" ],
[ "--a - + b", "--a-+b" ],
[ "--a - + b--", "--a-+b--" ],
[ "--a - + b++", "--a-+b++" ],
[ "--a - - ++b", "--a- -++b" ],
[ "--a - - --b", "--a- - --b" ],
[ "--a - - b", "--a- -b" ],
[ "--a - - b--", "--a- -b--" ],
[ "--a - - b++", "--a- -b++" ],
[ "a + ++b", "a+ ++b" ],
[ "a + --b", "a+--b" ],
[ "a + b", "a+b" ],
[ "a + b--", "a+b--" ],
[ "a + b++", "a+b++" ],
[ "a + + ++b", "a+ + ++b" ],
[ "a + + --b", "a+ +--b" ],
[ "a + + b", "a+ +b" ],
[ "a + + b--", "a+ +b--" ],
[ "a + + b++", "a+ +b++" ],
[ "a + - ++b", "a+-++b" ],
[ "a + - --b", "a+- --b" ],
[ "a + - b", "a+-b" ],
[ "a + - b--", "a+-b--" ],
[ "a + - b++", "a+-b++" ],
[ "a - ++b", "a-++b" ],
[ "a - --b", "a- --b" ],
[ "a - b", "a-b" ],
[ "a - b--", "a-b--" ],
[ "a - b++", "a-b++" ],
[ "a - + ++b", "a-+ ++b" ],
[ "a - + --b", "a-+--b" ],
[ "a - + b", "a-+b" ],
[ "a - + b--", "a-+b--" ],
[ "a - + b++", "a-+b++" ],
[ "a - - ++b", "a- -++b" ],
[ "a - - --b", "a- - --b" ],
[ "a - - b", "a- -b" ],
[ "a - - b--", "a- -b--" ],
[ "a - - b++", "a- -b++" ],
[ "a-- + ++b", "a--+ ++b" ],
[ "a-- + --b", "a--+--b" ],
[ "a-- + b", "a--+b" ],
[ "a-- + b--", "a--+b--" ],
[ "a-- + b++", "a--+b++" ],
[ "a-- + + ++b", "a--+ + ++b" ],
[ "a-- + + --b", "a--+ +--b" ],
[ "a-- + + b", "a--+ +b" ],
[ "a-- + + b--", "a--+ +b--" ],
[ "a-- + + b++", "a--+ +b++" ],
[ "a-- + - ++b", "a--+-++b" ],
[ "a-- + - --b", "a--+- --b" ],
[ "a-- + - b", "a--+-b" ],
[ "a-- + - b--", "a--+-b--" ],
[ "a-- + - b++", "a--+-b++" ],
[ "a-- - ++b", "a---++b" ],
[ "a-- - --b", "a--- --b" ],
[ "a-- - b", "a---b" ],
[ "a-- - b--", "a---b--" ],
[ "a-- - b++", "a---b++" ],
[ "a-- - + ++b", "a---+ ++b" ],
[ "a-- - + --b", "a---+--b" ],
[ "a-- - + b", "a---+b" ],
[ "a-- - + b--", "a---+b--" ],
[ "a-- - + b++", "a---+b++" ],
[ "a-- - - ++b", "a--- -++b" ],
[ "a-- - - --b", "a--- - --b" ],
[ "a-- - - b", "a--- -b" ],
[ "a-- - - b--", "a--- -b--" ],
[ "a-- - - b++", "a--- -b++" ],
[ "a++ + ++b", "a+++ ++b" ],
[ "a++ + --b", "a+++--b" ],
[ "a++ + b", "a+++b" ],
[ "a++ + b--", "a+++b--" ],
[ "a++ + b++", "a+++b++" ],
[ "a++ + + ++b", "a+++ + ++b" ],
[ "a++ + + --b", "a+++ +--b" ],
[ "a++ + + b", "a+++ +b" ],
[ "a++ + + b--", "a+++ +b--" ],
[ "a++ + + b++", "a+++ +b++" ],
[ "a++ + - ++b", "a+++-++b" ],
[ "a++ + - --b", "a+++- --b" ],
[ "a++ + - b", "a+++-b" ],
[ "a++ + - b--", "a+++-b--" ],
[ "a++ + - b++", "a+++-b++" ],
[ "a++ - ++b", "a++-++b" ],
[ "a++ - --b", "a++- --b" ],
[ "a++ - b", "a++-b" ],
[ "a++ - b--", "a++-b--" ],
[ "a++ - b++", "a++-b++" ],
[ "a++ - + ++b", "a++-+ ++b" ],
[ "a++ - + --b", "a++-+--b" ],
[ "a++ - + b", "a++-+b" ],
[ "a++ - + b--", "a++-+b--" ],
[ "a++ - + b++", "a++-+b++" ],
[ "a++ - - ++b", "a++- -++b" ],
[ "a++ - - --b", "a++- - --b" ],
[ "a++ - - b", "a++- -b" ],
[ "a++ - - b--", "a++- -b--" ],
[ "a++ - - b++", "a++- -b++" ],
[ "+ ++a + ++b", "+ ++a+ ++b" ],
[ "+ ++a + --b", "+ ++a+--b" ],
[ "+ ++a + b", "+ ++a+b" ],
[ "+ ++a + b--", "+ ++a+b--" ],
[ "+ ++a + b++", "+ ++a+b++" ],
[ "+ ++a + + ++b", "+ ++a+ + ++b" ],
[ "+ ++a + + --b", "+ ++a+ +--b" ],
[ "+ ++a + + b", "+ ++a+ +b" ],
[ "+ ++a + + b--", "+ ++a+ +b--" ],
[ "+ ++a + + b++", "+ ++a+ +b++" ],
[ "+ ++a + - ++b", "+ ++a+-++b" ],
[ "+ ++a + - --b", "+ ++a+- --b" ],
[ "+ ++a + - b", "+ ++a+-b" ],
[ "+ ++a + - b--", "+ ++a+-b--" ],
[ "+ ++a + - b++", "+ ++a+-b++" ],
[ "+ ++a - ++b", "+ ++a-++b" ],
[ "+ ++a - --b", "+ ++a- --b" ],
[ "+ ++a - b", "+ ++a-b" ],
[ "+ ++a - b--", "+ ++a-b--" ],
[ "+ ++a - b++", "+ ++a-b++" ],
[ "+ ++a - + ++b", "+ ++a-+ ++b" ],
[ "+ ++a - + --b", "+ ++a-+--b" ],
[ "+ ++a - + b", "+ ++a-+b" ],
[ "+ ++a - + b--", "+ ++a-+b--" ],
[ "+ ++a - + b++", "+ ++a-+b++" ],
[ "+ ++a - - ++b", "+ ++a- -++b" ],
[ "+ ++a - - --b", "+ ++a- - --b" ],
[ "+ ++a - - b", "+ ++a- -b" ],
[ "+ ++a - - b--", "+ ++a- -b--" ],
[ "+ ++a - - b++", "+ ++a- -b++" ],
[ "+ --a + ++b", "+--a+ ++b" ],
[ "+ --a + --b", "+--a+--b" ],
[ "+ --a + b", "+--a+b" ],
[ "+ --a + b--", "+--a+b--" ],
[ "+ --a + b++", "+--a+b++" ],
[ "+ --a + + ++b", "+--a+ + ++b" ],
[ "+ --a + + --b", "+--a+ +--b" ],
[ "+ --a + + b", "+--a+ +b" ],
[ "+ --a + + b--", "+--a+ +b--" ],
[ "+ --a + + b++", "+--a+ +b++" ],
[ "+ --a + - ++b", "+--a+-++b" ],
[ "+ --a + - --b", "+--a+- --b" ],
[ "+ --a + - b", "+--a+-b" ],
[ "+ --a + - b--", "+--a+-b--" ],
[ "+ --a + - b++", "+--a+-b++" ],
[ "+ --a - ++b", "+--a-++b" ],
[ "+ --a - --b", "+--a- --b" ],
[ "+ --a - b", "+--a-b" ],
[ "+ --a - b--", "+--a-b--" ],
[ "+ --a - b++", "+--a-b++" ],
[ "+ --a - + ++b", "+--a-+ ++b" ],
[ "+ --a - + --b", "+--a-+--b" ],
[ "+ --a - + b", "+--a-+b" ],
[ "+ --a - + b--", "+--a-+b--" ],
[ "+ --a - + b++", "+--a-+b++" ],
[ "+ --a - - ++b", "+--a- -++b" ],
[ "+ --a - - --b", "+--a- - --b" ],
[ "+ --a - - b", "+--a- -b" ],
[ "+ --a - - b--", "+--a- -b--" ],
[ "+ --a - - b++", "+--a- -b++" ],
[ "+ a + ++b", "+a+ ++b" ],
[ "+ a + --b", "+a+--b" ],
[ "+ a + b", "+a+b" ],
[ "+ a + b--", "+a+b--" ],
[ "+ a + b++", "+a+b++" ],
[ "+ a + + ++b", "+a+ + ++b" ],
[ "+ a + + --b", "+a+ +--b" ],
[ "+ a + + b", "+a+ +b" ],
[ "+ a + + b--", "+a+ +b--" ],
[ "+ a + + b++", "+a+ +b++" ],
[ "+ a + - ++b", "+a+-++b" ],
[ "+ a + - --b", "+a+- --b" ],
[ "+ a + - b", "+a+-b" ],
[ "+ a + - b--", "+a+-b--" ],
[ "+ a + - b++", "+a+-b++" ],
[ "+ a - ++b", "+a-++b" ],
[ "+ a - --b", "+a- --b" ],
[ "+ a - b", "+a-b" ],
[ "+ a - b--", "+a-b--" ],
[ "+ a - b++", "+a-b++" ],
[ "+ a - + ++b", "+a-+ ++b" ],
[ "+ a - + --b", "+a-+--b" ],
[ "+ a - + b", "+a-+b" ],
[ "+ a - + b--", "+a-+b--" ],
[ "+ a - + b++", "+a-+b++" ],
[ "+ a - - ++b", "+a- -++b" ],
[ "+ a - - --b", "+a- - --b" ],
[ "+ a - - b", "+a- -b" ],
[ "+ a - - b--", "+a- -b--" ],
[ "+ a - - b++", "+a- -b++" ],
[ "+ a-- + ++b", "+a--+ ++b" ],
[ "+ a-- + --b", "+a--+--b" ],
[ "+ a-- + b", "+a--+b" ],
[ "+ a-- + b--", "+a--+b--" ],
[ "+ a-- + b++", "+a--+b++" ],
[ "+ a-- + + ++b", "+a--+ + ++b" ],
[ "+ a-- + + --b", "+a--+ +--b" ],
[ "+ a-- + + b", "+a--+ +b" ],
[ "+ a-- + + b--", "+a--+ +b--" ],
[ "+ a-- + + b++", "+a--+ +b++" ],
[ "+ a-- + - ++b", "+a--+-++b" ],
[ "+ a-- + - --b", "+a--+- --b" ],
[ "+ a-- + - b", "+a--+-b" ],
[ "+ a-- + - b--", "+a--+-b--" ],
[ "+ a-- + - b++", "+a--+-b++" ],
[ "+ a-- - ++b", "+a---++b" ],
[ "+ a-- - --b", "+a--- --b" ],
[ "+ a-- - b", "+a---b" ],
[ "+ a-- - b--", "+a---b--" ],
[ "+ a-- - b++", "+a---b++" ],
[ "+ a-- - + ++b", "+a---+ ++b" ],
[ "+ a-- - + --b", "+a---+--b" ],
[ "+ a-- - + b", "+a---+b" ],
[ "+ a-- - + b--", "+a---+b--" ],
[ "+ a-- - + b++", "+a---+b++" ],
[ "+ a-- - - ++b", "+a--- -++b" ],
[ "+ a-- - - --b", "+a--- - --b" ],
[ "+ a-- - - b", "+a--- -b" ],
[ "+ a-- - - b--", "+a--- -b--" ],
[ "+ a-- - - b++", "+a--- -b++" ],
[ "+ a++ + ++b", "+a+++ ++b" ],
[ "+ a++ + --b", "+a+++--b" ],
[ "+ a++ + b", "+a+++b" ],
[ "+ a++ + b--", "+a+++b--" ],
[ "+ a++ + b++", "+a+++b++" ],
[ "+ a++ + + ++b", "+a+++ + ++b" ],
[ "+ a++ + + --b", "+a+++ +--b" ],
[ "+ a++ + + b", "+a+++ +b" ],
[ "+ a++ + + b--", "+a+++ +b--" ],
[ "+ a++ + + b++", "+a+++ +b++" ],
[ "+ a++ + - ++b", "+a+++-++b" ],
[ "+ a++ + - --b", "+a+++- --b" ],
[ "+ a++ + - b", "+a+++-b" ],
[ "+ a++ + - b--", "+a+++-b--" ],
[ "+ a++ + - b++", "+a+++-b++" ],
[ "+ a++ - ++b", "+a++-++b" ],
[ "+ a++ - --b", "+a++- --b" ],
[ "+ a++ - b", "+a++-b" ],
[ "+ a++ - b--", "+a++-b--" ],
[ "+ a++ - b++", "+a++-b++" ],
[ "+ a++ - + ++b", "+a++-+ ++b" ],
[ "+ a++ - + --b", "+a++-+--b" ],
[ "+ a++ - + b", "+a++-+b" ],
[ "+ a++ - + b--", "+a++-+b--" ],
[ "+ a++ - + b++", "+a++-+b++" ],
[ "+ a++ - - ++b", "+a++- -++b" ],
[ "+ a++ - - --b", "+a++- - --b" ],
[ "+ a++ - - b", "+a++- -b" ],
[ "+ a++ - - b--", "+a++- -b--" ],
[ "+ a++ - - b++", "+a++- -b++" ],
[ "- ++a + ++b", "-++a+ ++b" ],
[ "- ++a + --b", "-++a+--b" ],
[ "- ++a + b", "-++a+b" ],
[ "- ++a + b--", "-++a+b--" ],
[ "- ++a + b++", "-++a+b++" ],
[ "- ++a + + ++b", "-++a+ + ++b" ],
[ "- ++a + + --b", "-++a+ +--b" ],
[ "- ++a + + b", "-++a+ +b" ],
[ "- ++a + + b--", "-++a+ +b--" ],
[ "- ++a + + b++", "-++a+ +b++" ],
[ "- ++a + - ++b", "-++a+-++b" ],
[ "- ++a + - --b", "-++a+- --b" ],
[ "- ++a + - b", "-++a+-b" ],
[ "- ++a + - b--", "-++a+-b--" ],
[ "- ++a + - b++", "-++a+-b++" ],
[ "- ++a - ++b", "-++a-++b" ],
[ "- ++a - --b", "-++a- --b" ],
[ "- ++a - b", "-++a-b" ],
[ "- ++a - b--", "-++a-b--" ],
[ "- ++a - b++", "-++a-b++" ],
[ "- ++a - + ++b", "-++a-+ ++b" ],
[ "- ++a - + --b", "-++a-+--b" ],
[ "- ++a - + b", "-++a-+b" ],
[ "- ++a - + b--", "-++a-+b--" ],
[ "- ++a - + b++", "-++a-+b++" ],
[ "- ++a - - ++b", "-++a- -++b" ],
[ "- ++a - - --b", "-++a- - --b" ],
[ "- ++a - - b", "-++a- -b" ],
[ "- ++a - - b--", "-++a- -b--" ],
[ "- ++a - - b++", "-++a- -b++" ],
[ "- --a + ++b", "- --a+ ++b" ],
[ "- --a + --b", "- --a+--b" ],
[ "- --a + b", "- --a+b" ],
[ "- --a + b--", "- --a+b--" ],
[ "- --a + b++", "- --a+b++" ],
[ "- --a + + ++b", "- --a+ + ++b" ],
[ "- --a + + --b", "- --a+ +--b" ],
[ "- --a + + b", "- --a+ +b" ],
[ "- --a + + b--", "- --a+ +b--" ],
[ "- --a + + b++", "- --a+ +b++" ],
[ "- --a + - ++b", "- --a+-++b" ],
[ "- --a + - --b", "- --a+- --b" ],
[ "- --a + - b", "- --a+-b" ],
[ "- --a + - b--", "- --a+-b--" ],
[ "- --a + - b++", "- --a+-b++" ],
[ "- --a - ++b", "- --a-++b" ],
[ "- --a - --b", "- --a- --b" ],
[ "- --a - b", "- --a-b" ],
[ "- --a - b--", "- --a-b--" ],
[ "- --a - b++", "- --a-b++" ],
[ "- --a - + ++b", "- --a-+ ++b" ],
[ "- --a - + --b", "- --a-+--b" ],
[ "- --a - + b", "- --a-+b" ],
[ "- --a - + b--", "- --a-+b--" ],
[ "- --a - + b++", "- --a-+b++" ],
[ "- --a - - ++b", "- --a- -++b" ],
[ "- --a - - --b", "- --a- - --b" ],
[ "- --a - - b", "- --a- -b" ],
[ "- --a - - b--", "- --a- -b--" ],
[ "- --a - - b++", "- --a- -b++" ],
[ "- a + ++b", "-a+ ++b" ],
[ "- a + --b", "-a+--b" ],
[ "- a + b", "-a+b" ],
[ "- a + b--", "-a+b--" ],
[ "- a + b++", "-a+b++" ],
[ "- a + + ++b", "-a+ + ++b" ],
[ "- a + + --b", "-a+ +--b" ],
[ "- a + + b", "-a+ +b" ],
[ "- a + + b--", "-a+ +b--" ],
[ "- a + + b++", "-a+ +b++" ],
[ "- a + - ++b", "-a+-++b" ],
[ "- a + - --b", "-a+- --b" ],
[ "- a + - b", "-a+-b" ],
[ "- a + - b--", "-a+-b--" ],
[ "- a + - b++", "-a+-b++" ],
[ "- a - ++b", "-a-++b" ],
[ "- a - --b", "-a- --b" ],
[ "- a - b", "-a-b" ],
[ "- a - b--", "-a-b--" ],
[ "- a - b++", "-a-b++" ],
[ "- a - + ++b", "-a-+ ++b" ],
[ "- a - + --b", "-a-+--b" ],
[ "- a - + b", "-a-+b" ],
[ "- a - + b--", "-a-+b--" ],
[ "- a - + b++", "-a-+b++" ],
[ "- a - - ++b", "-a- -++b" ],
[ "- a - - --b", "-a- - --b" ],
[ "- a - - b", "-a- -b" ],
[ "- a - - b--", "-a- -b--" ],
[ "- a - - b++", "-a- -b++" ],
[ "- a-- + ++b", "-a--+ ++b" ],
[ "- a-- + --b", "-a--+--b" ],
[ "- a-- + b", "-a--+b" ],
[ "- a-- + b--", "-a--+b--" ],
[ "- a-- + b++", "-a--+b++" ],
[ "- a-- + + ++b", "-a--+ + ++b" ],
[ "- a-- + + --b", "-a--+ +--b" ],
[ "- a-- + + b", "-a--+ +b" ],
[ "- a-- + + b--", "-a--+ +b--" ],
[ "- a-- + + b++", "-a--+ +b++" ],
[ "- a-- + - ++b", "-a--+-++b" ],
[ "- a-- + - --b", "-a--+- --b" ],
[ "- a-- + - b", "-a--+-b" ],
[ "- a-- + - b--", "-a--+-b--" ],
[ "- a-- + - b++", "-a--+-b++" ],
[ "- a-- - ++b", "-a---++b" ],
[ "- a-- - --b", "-a--- --b" ],
[ "- a-- - b", "-a---b" ],
[ "- a-- - b--", "-a---b--" ],
[ "- a-- - b++", "-a---b++" ],
[ "- a-- - + ++b", "-a---+ ++b" ],
[ "- a-- - + --b", "-a---+--b" ],
[ "- a-- - + b", "-a---+b" ],
[ "- a-- - + b--", "-a---+b--" ],
[ "- a-- - + b++", "-a---+b++" ],
[ "- a-- - - ++b", "-a--- -++b" ],
[ "- a-- - - --b", "-a--- - --b" ],
[ "- a-- - - b", "-a--- -b" ],
[ "- a-- - - b--", "-a--- -b--" ],
[ "- a-- - - b++", "-a--- -b++" ],
[ "- a++ + ++b", "-a+++ ++b" ],
[ "- a++ + --b", "-a+++--b" ],
[ "- a++ + b", "-a+++b" ],
[ "- a++ + b--", "-a+++b--" ],
[ "- a++ + b++", "-a+++b++" ],
[ "- a++ + + ++b", "-a+++ + ++b" ],
[ "- a++ + + --b", "-a+++ +--b" ],
[ "- a++ + + b", "-a+++ +b" ],
[ "- a++ + + b--", "-a+++ +b--" ],
[ "- a++ + + b++", "-a+++ +b++" ],
[ "- a++ + - ++b", "-a+++-++b" ],
[ "- a++ + - --b", "-a+++- --b" ],
[ "- a++ + - b", "-a+++-b" ],
[ "- a++ + - b--", "-a+++-b--" ],
[ "- a++ + - b++", "-a+++-b++" ],
[ "- a++ - ++b", "-a++-++b" ],
[ "- a++ - --b", "-a++- --b" ],
[ "- a++ - b", "-a++-b" ],
[ "- a++ - b--", "-a++-b--" ],
[ "- a++ - b++", "-a++-b++" ],
[ "- a++ - + ++b", "-a++-+ ++b" ],
[ "- a++ - + --b", "-a++-+--b" ],
[ "- a++ - + b", "-a++-+b" ],
[ "- a++ - + b--", "-a++-+b--" ],
[ "- a++ - + b++", "-a++-+b++" ],
[ "- a++ - - ++b", "-a++- -++b" ],
[ "- a++ - - --b", "-a++- - --b" ],
[ "- a++ - - b", "-a++- -b" ],
[ "- a++ - - b--", "-a++- -b--" ],
[ "- a++ - - b++", "-a++- -b++" ],
].forEach(function(exp) {
assert.strictEqual(UglifyJS.parse(exp[0]).print_to_string(), exp[1] + ";");
});
});
});

View File

@@ -19,7 +19,7 @@ describe("String literals", function() {
var error = function(e) {
return e instanceof UglifyJS.JS_Parse_Error &&
e.message === "SyntaxError: Unterminated string constant";
e.message === "Unterminated string constant";
};
for (var input in inputs) {
@@ -49,7 +49,7 @@ describe("String literals", function() {
var error = function(e) {
return e instanceof UglifyJS.JS_Parse_Error &&
e.message === "SyntaxError: Legacy octal escape sequences are not allowed in strict mode";
e.message === "Legacy octal escape sequences are not allowed in strict mode";
}
for (var input in inputs) {

View File

@@ -9,7 +9,7 @@ describe("With", function() {
}
var error = function(e) {
return e instanceof uglify.JS_Parse_Error &&
e.message === "SyntaxError: Strict mode may not include a with statement";
e.message === "Strict mode may not include a with statement";
}
assert.throws(test, error);
});

View File

@@ -194,6 +194,9 @@ function parse_test(file) {
if (node instanceof U.AST_LabeledStatement
&& tw.parent() instanceof U.AST_Toplevel) {
var name = node.label.name;
if (name in tests) {
throw new Error('Duplicated test name "' + name + '" in ' + file);
}
tests[name] = get_one_test(name, node.body);
return true;
}