Improve support for binding pattern
Including improvements for parameters, variable assignment and catch parameter.
This commit is contained in:
@@ -1,27 +1,75 @@
|
||||
|
||||
destructuring_arrays: {
|
||||
input: {
|
||||
{const [aa, bb] = cc;}
|
||||
{const [aa, [bb, cc]] = dd;}
|
||||
{let [aa, bb] = cc;}
|
||||
{let [aa, [bb, cc]] = dd;}
|
||||
var [aa, bb] = cc;
|
||||
var [aa, [bb, cc]] = dd;
|
||||
var [,[,,,,,],,,zz,] = xx;
|
||||
}
|
||||
expect: {
|
||||
var[aa,bb]=cc;
|
||||
{const [aa, bb] = cc;}
|
||||
{const [aa, [bb, cc]] = dd;}
|
||||
{let [aa, bb] = cc;}
|
||||
{let [aa, [bb, cc]] = dd;}
|
||||
var [aa, bb] = cc;
|
||||
var [aa, [bb, cc]] = dd;
|
||||
var [,[,,,,,],,,zz,] = xx;
|
||||
}
|
||||
}
|
||||
|
||||
destructuring_objects: {
|
||||
input: {
|
||||
{const {aa, bb} = {aa:1, bb:2};}
|
||||
{const {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||
{let {aa, bb} = {aa:1, bb:2};}
|
||||
{let {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||
var {aa, bb} = {aa:1, bb:2};
|
||||
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
|
||||
}
|
||||
expect: {
|
||||
var{aa,bb}={aa:1,bb:2};
|
||||
{const {aa, bb} = {aa:1, bb:2};}
|
||||
{const {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||
{let {aa, bb} = {aa:1, bb:2};}
|
||||
{let {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||
var {aa, bb} = {aa:1, bb:2};
|
||||
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
|
||||
}
|
||||
}
|
||||
|
||||
destructuring_objects_trailing_elision: {
|
||||
input: {
|
||||
var {cc,} = foo;
|
||||
}
|
||||
expect_exact: "var{cc}=foo;"
|
||||
}
|
||||
|
||||
nested_destructuring_objects: {
|
||||
input: {
|
||||
const [{a},b] = c;
|
||||
let [{a},b] = c;
|
||||
var [{a},b] = c;
|
||||
}
|
||||
expect_exact: 'var[{a},b]=c;';
|
||||
expect_exact: 'const[{a},b]=c;let[{a},b]=c;var[{a},b]=c;';
|
||||
}
|
||||
|
||||
destructuring_constdef_in_loops: {
|
||||
input: {
|
||||
for (const [x,y] in pairs);
|
||||
for (const [a] = 0;;);
|
||||
for (const {c} of cees);
|
||||
}
|
||||
expect_exact: "for(const[x,y]in pairs);for(const[a]=0;;);for(const{c}of cees);"
|
||||
}
|
||||
|
||||
destructuring_letdef_in_loops: {
|
||||
input: {
|
||||
for (let [x,y] in pairs);
|
||||
for (let [a] = 0;;);
|
||||
for (let {c} of cees);
|
||||
}
|
||||
expect_exact: "for(let[x,y]in pairs);for(let[a]=0;;);for(let{c}of cees);"
|
||||
}
|
||||
|
||||
destructuring_vardef_in_loops: {
|
||||
@@ -32,6 +80,7 @@ destructuring_vardef_in_loops: {
|
||||
}
|
||||
expect_exact: "for(var[x,y]in pairs);for(var[a]=0;;);for(var{c}of cees);"
|
||||
}
|
||||
|
||||
destructuring_expressions: {
|
||||
input: {
|
||||
({a, b});
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
arrow_functions: {
|
||||
input: {
|
||||
(a) => b; // 1 args
|
||||
(a, b) => c; // n args
|
||||
() => b; // 0 args
|
||||
(a) => (b) => c; // func returns func returns func
|
||||
(a) => ((b) => c); // So these parens are dropped
|
||||
() => (b,c) => d; // func returns func returns func
|
||||
a=>{return b;}
|
||||
a => 'lel'; // Dropping the parens
|
||||
}
|
||||
expect_exact: "a=>b;(a,b)=>c;()=>b;a=>b=>c;a=>b=>c;()=>(b,c)=>d;a=>{return b};a=>\"lel\";"
|
||||
}
|
||||
|
||||
arrow_function_parens: {
|
||||
input: {
|
||||
something && (() => {});
|
||||
@@ -25,28 +11,6 @@ arrow_function_parens_2: {
|
||||
expect_exact: "(()=>null)();"
|
||||
}
|
||||
|
||||
regression_arrow_functions_and_hoist: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
hoist_funs: true
|
||||
}
|
||||
input: {
|
||||
(a) => b;
|
||||
}
|
||||
expect_exact: "a=>b;"
|
||||
}
|
||||
|
||||
regression_assign_arrow_functions: {
|
||||
input: {
|
||||
oninstall = e => false;
|
||||
oninstall = () => false;
|
||||
}
|
||||
expect: {
|
||||
oninstall=e=>false;
|
||||
oninstall=()=>false;
|
||||
}
|
||||
}
|
||||
|
||||
typeof_arrow_functions: {
|
||||
options = {
|
||||
evaluate: true
|
||||
@@ -57,86 +21,6 @@ typeof_arrow_functions: {
|
||||
expect_exact: "var foo=\"function\";"
|
||||
}
|
||||
|
||||
destructuring_arguments: {
|
||||
input: {
|
||||
(function ( a ) { });
|
||||
(function ( [ a ] ) { });
|
||||
(function ( [ a, b ] ) { });
|
||||
(function ( [ [ a ] ] ) { });
|
||||
(function ( [ [ a, b ] ] ) { });
|
||||
(function ( [ a, [ b ] ] ) { });
|
||||
(function ( [ [ b ], a ] ) { });
|
||||
|
||||
(function ( { a } ) { });
|
||||
(function ( { a, b } ) { });
|
||||
|
||||
(function ( [ { a } ] ) { });
|
||||
(function ( [ { a, b } ] ) { });
|
||||
(function ( [ a, { b } ] ) { });
|
||||
(function ( [ { b }, a ] ) { });
|
||||
|
||||
( [ a ] ) => { };
|
||||
( [ a, b ] ) => { };
|
||||
|
||||
( { a } ) => { };
|
||||
( { a, b, c, d, e } ) => { };
|
||||
|
||||
( [ a ] ) => b;
|
||||
( [ a, b ] ) => c;
|
||||
|
||||
( { a } ) => b;
|
||||
( { a, b } ) => c;
|
||||
}
|
||||
expect: {
|
||||
(function(a){});
|
||||
(function([a]){});
|
||||
(function([a,b]){});
|
||||
(function([[a]]){});
|
||||
(function([[a,b]]){});
|
||||
(function([a,[b]]){});
|
||||
(function([[b],a]){});
|
||||
|
||||
(function({a}){});
|
||||
(function({a,b}){});
|
||||
|
||||
(function([{a}]){});
|
||||
(function([{a,b}]){});
|
||||
(function([a,{b}]){});
|
||||
(function([{b},a]){});
|
||||
|
||||
([a])=>{};
|
||||
([a,b])=>{};
|
||||
|
||||
({a})=>{};
|
||||
({a,b,c,d,e})=>{};
|
||||
|
||||
([a])=>b;
|
||||
([a,b])=>c;
|
||||
|
||||
({a})=>b;
|
||||
({a,b})=>c;
|
||||
}
|
||||
}
|
||||
|
||||
default_arguments: {
|
||||
input: {
|
||||
function x(a = 6) { }
|
||||
function x(a = (6 + 5)) { }
|
||||
function x({ foo } = {}, [ bar ] = [ 1 ]) { }
|
||||
}
|
||||
expect_exact: "function x(a=6){}function x(a=6+5){}function x({foo}={},[bar]=[1]){}"
|
||||
}
|
||||
|
||||
default_values_in_destructurings: {
|
||||
input: {
|
||||
function x({a=(4), b}) {}
|
||||
function x([b, c=(12)]) {}
|
||||
var { x = (6), y } = x;
|
||||
var [ x, y = (6) ] = x;
|
||||
}
|
||||
expect_exact: "function x({a=4,b}){}function x([b,c=12]){}var{x=6,y}=x;var[x,y=6]=x;"
|
||||
}
|
||||
|
||||
classes: {
|
||||
input: {
|
||||
class SomeClass {
|
||||
|
||||
159
test/compress/parameters.js
Normal file
159
test/compress/parameters.js
Normal file
@@ -0,0 +1,159 @@
|
||||
arrow_functions: {
|
||||
input: {
|
||||
(a) => b; // 1 args
|
||||
(a, b) => c; // n args
|
||||
() => b; // 0 args
|
||||
(a) => (b) => c; // func returns func returns func
|
||||
(a) => ((b) => c); // So these parens are dropped
|
||||
() => (b,c) => d; // func returns func returns func
|
||||
a=>{return b;}
|
||||
a => 'lel'; // Dropping the parens
|
||||
}
|
||||
expect_exact: "a=>b;(a,b)=>c;()=>b;a=>b=>c;a=>b=>c;()=>(b,c)=>d;a=>{return b};a=>\"lel\";"
|
||||
}
|
||||
|
||||
regression_arrow_functions_and_hoist: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
hoist_funs: true
|
||||
}
|
||||
input: {
|
||||
(a) => b;
|
||||
}
|
||||
expect_exact: "a=>b;"
|
||||
}
|
||||
|
||||
regression_assign_arrow_functions: {
|
||||
input: {
|
||||
oninstall = e => false;
|
||||
oninstall = () => false;
|
||||
}
|
||||
expect: {
|
||||
oninstall=e=>false;
|
||||
oninstall=()=>false;
|
||||
}
|
||||
}
|
||||
|
||||
destructuring_arguments_1: {
|
||||
input: {
|
||||
(function ( a ) { });
|
||||
(function ( [ a ] ) { });
|
||||
(function ( [ a, b ] ) { });
|
||||
(function ( [ [ a ] ] ) { });
|
||||
(function ( [ [ a, b ] ] ) { });
|
||||
(function ( [ a, [ b ] ] ) { });
|
||||
(function ( [ [ b ], a ] ) { });
|
||||
|
||||
(function ( { a } ) { });
|
||||
(function ( { a, b } ) { });
|
||||
|
||||
(function ( [ { a } ] ) { });
|
||||
(function ( [ { a, b } ] ) { });
|
||||
(function ( [ a, { b } ] ) { });
|
||||
(function ( [ { b }, a ] ) { });
|
||||
|
||||
( [ a ] ) => { };
|
||||
( [ a, b ] ) => { };
|
||||
|
||||
( { a } ) => { };
|
||||
( { a, b, c, d, e } ) => { };
|
||||
|
||||
( [ a ] ) => b;
|
||||
( [ a, b ] ) => c;
|
||||
|
||||
( { a } ) => b;
|
||||
( { a, b } ) => c;
|
||||
}
|
||||
expect: {
|
||||
(function(a){});
|
||||
(function([a]){});
|
||||
(function([a,b]){});
|
||||
(function([[a]]){});
|
||||
(function([[a,b]]){});
|
||||
(function([a,[b]]){});
|
||||
(function([[b],a]){});
|
||||
|
||||
(function({a}){});
|
||||
(function({a,b}){});
|
||||
|
||||
(function([{a}]){});
|
||||
(function([{a,b}]){});
|
||||
(function([a,{b}]){});
|
||||
(function([{b},a]){});
|
||||
|
||||
([a])=>{};
|
||||
([a,b])=>{};
|
||||
|
||||
({a})=>{};
|
||||
({a,b,c,d,e})=>{};
|
||||
|
||||
([a])=>b;
|
||||
([a,b])=>c;
|
||||
|
||||
({a})=>b;
|
||||
({a,b})=>c;
|
||||
}
|
||||
}
|
||||
|
||||
destructuring_arguments_2: {
|
||||
input: {
|
||||
(function([]) {});
|
||||
(function({}) {});
|
||||
(function([,,,,,]) {});
|
||||
(function ([a, {b: c}]) {});
|
||||
(function ([...args]) {});
|
||||
(function ({x,}) {});
|
||||
class a { *method({ [thrower()]: x } = {}) {}};
|
||||
(function(a, b, c, d, [{e: [...f]}]){})(1, 2, 3, 4, [{e: [1, 2, 3]}]);
|
||||
}
|
||||
expect: {
|
||||
(function([]) {});
|
||||
(function({}) {});
|
||||
(function([,,,,,]) {});
|
||||
(function ([a, {b: c}]) {});
|
||||
(function ([...args]) {});
|
||||
(function ({x,}) {});
|
||||
class a { *method({ [thrower()]: x } = {}) {}};
|
||||
(function(a, b, c, d, [{e: [...f]}]){})(1, 2, 3, 4, [{e: [1, 2, 3]}]);
|
||||
}
|
||||
}
|
||||
|
||||
destructuring_arguments_3: {
|
||||
input: {
|
||||
function fn3({x: {y: {z: {} = 42}}}) {}
|
||||
const { cover = (function () {}), xCover = (0, function() {}) } = {};
|
||||
let { cover = (function () {}), xCover = (0, function() {}) } = {};
|
||||
var { cover = (function () {}), xCover = (0, function() {}) } = {};
|
||||
}
|
||||
expect_exact: "function fn3({x:{y:{z:{}=42}}}){}const{cover=function(){},xCover=(0,function(){})}={};let{cover=function(){},xCover=(0,function(){})}={};var{cover=function(){},xCover=(0,function(){})}={};"
|
||||
}
|
||||
|
||||
default_arguments: {
|
||||
input: {
|
||||
function x(a = 6) { }
|
||||
function x(a = (6 + 5)) { }
|
||||
function x({ foo } = {}, [ bar ] = [ 1 ]) { }
|
||||
}
|
||||
expect_exact: "function x(a=6){}function x(a=6+5){}function x({foo}={},[bar]=[1]){}"
|
||||
}
|
||||
|
||||
default_values_in_destructurings: {
|
||||
input: {
|
||||
function x({a=(4), b}) {}
|
||||
function x([b, c=(12)]) {}
|
||||
var { x = (6), y } = x;
|
||||
var [ x, y = (6) ] = x;
|
||||
}
|
||||
expect_exact: "function x({a=4,b}){}function x([b,c=12]){}var{x=6,y}=x;var[x,y=6]=x;"
|
||||
}
|
||||
|
||||
accept_duplicated_parameters_in_non_strict_without_spread_or_default_assignment: {
|
||||
input: {
|
||||
function a(b, b){}
|
||||
function b({c: test, c: test}){}
|
||||
}
|
||||
expect: {
|
||||
function a(b, b){}
|
||||
function b({c: test, c: test}){}
|
||||
}
|
||||
}
|
||||
9
test/compress/try-catch.js
Normal file
9
test/compress/try-catch.js
Normal file
@@ -0,0 +1,9 @@
|
||||
catch_destructuring_with_sequence: {
|
||||
input: {
|
||||
try {
|
||||
throw {};
|
||||
} catch ({xCover = (0, function() {})} ) {
|
||||
}
|
||||
}
|
||||
expect_exact: "try{throw{}}catch({xCover=(0,function(){})}){}"
|
||||
}
|
||||
@@ -16,7 +16,7 @@ describe("Class", function() {
|
||||
}
|
||||
var error = function(e) {
|
||||
return e instanceof uglify.JS_Parse_Error &&
|
||||
e.message === "SyntaxError: Unexpected token: expand (...)";
|
||||
e.message.substr(0, 31) === "SyntaxError: Unexpected token: ";
|
||||
}
|
||||
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
|
||||
@@ -2,6 +2,101 @@ var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
|
||||
describe("Function", function() {
|
||||
it ("Should parse binding patterns correctly", function() {
|
||||
// Function argument nodes are correct
|
||||
function get_args(args) {
|
||||
return args.map(function (arg) {
|
||||
return [arg.TYPE, arg.name];
|
||||
});
|
||||
}
|
||||
|
||||
// Destructurings as arguments
|
||||
var destr_fun1 = uglify.parse('(function ({a, b}) {})').body[0].body;
|
||||
var destr_fun2 = uglify.parse('(function ([a, [b]]) {})').body[0].body;
|
||||
|
||||
assert.equal(destr_fun1.argnames.length, 1);
|
||||
assert.equal(destr_fun2.argnames.length, 1);
|
||||
|
||||
var destr_fun1 = uglify.parse('({a, b}) => null').body[0].body;
|
||||
var destr_fun2 = uglify.parse('([a, [b]]) => null').body[0].body;
|
||||
|
||||
assert.equal(destr_fun1.argnames.length, 1);
|
||||
assert.equal(destr_fun2.argnames.length, 1);
|
||||
|
||||
var destruct1 = destr_fun1.argnames[0];
|
||||
var destruct2 = destr_fun2.argnames[0];
|
||||
|
||||
assert(destruct1 instanceof uglify.AST_Destructuring);
|
||||
assert(destruct2 instanceof uglify.AST_Destructuring);
|
||||
assert(destruct2.names[1] instanceof uglify.AST_Destructuring);
|
||||
|
||||
assert.equal(destruct1.start.value, '{');
|
||||
assert.equal(destruct1.end.value, '}');
|
||||
assert.equal(destruct2.start.value, '[');
|
||||
assert.equal(destruct2.end.value, ']');
|
||||
|
||||
assert.equal(destruct1.is_array, false);
|
||||
assert.equal(destruct2.is_array, true);
|
||||
|
||||
var aAndB = [
|
||||
['SymbolFunarg', 'a'],
|
||||
['SymbolFunarg', 'b']
|
||||
];
|
||||
|
||||
assert.deepEqual(
|
||||
[
|
||||
destruct1.names[0].TYPE,
|
||||
destruct1.names[0].name],
|
||||
aAndB[0]);
|
||||
|
||||
assert.deepEqual(
|
||||
[
|
||||
destruct2.names[1].names[0].TYPE,
|
||||
destruct2.names[1].names[0].name
|
||||
],
|
||||
aAndB[1]);
|
||||
|
||||
assert.deepEqual(
|
||||
get_args(destr_fun1.args_as_names()),
|
||||
aAndB);
|
||||
assert.deepEqual(
|
||||
get_args(destr_fun2.args_as_names()),
|
||||
aAndB);
|
||||
|
||||
// Making sure we don't accidentally accept things which
|
||||
// Aren't argument destructurings
|
||||
|
||||
assert.throws(function () {
|
||||
uglify.parse('(function ( { a, [ b ] } ) { })')
|
||||
});
|
||||
|
||||
assert.throws(function () {
|
||||
uglify.parse('(function (1) { })');
|
||||
}, /Invalid function parameter/);
|
||||
|
||||
assert.throws(function () {
|
||||
uglify.parse('(function (this) { })');
|
||||
});
|
||||
|
||||
assert.throws(function () {
|
||||
uglify.parse('(function ([1]) { })');
|
||||
}, /Invalid function parameter/);
|
||||
|
||||
assert.throws(function () {
|
||||
uglify.parse('(function [a] { })');
|
||||
});
|
||||
|
||||
// generators
|
||||
var generators_def = uglify.parse('function* fn() {}').body[0];
|
||||
assert.equal(generators_def.is_generator, true);
|
||||
|
||||
assert.throws(function () {
|
||||
uglify.parse('function* (){ }');
|
||||
});
|
||||
|
||||
var generators_yield_def = uglify.parse('function* fn() {\nyield remote();\}').body[0].body[0];
|
||||
assert.strictEqual(generators_yield_def.body.is_star, false);
|
||||
});
|
||||
it("Should not accept spread on non-last parameters", function() {
|
||||
var tests = [
|
||||
"var a = function(...a, b) { return a.join(b) }",
|
||||
@@ -20,11 +115,76 @@ describe("Function", function() {
|
||||
}
|
||||
var error = function(e) {
|
||||
return e instanceof uglify.JS_Parse_Error &&
|
||||
e.message === "SyntaxError: Unexpected token: expand (...)";
|
||||
e.message.substr(0, 31) === "SyntaxError: Unexpected token: ";
|
||||
}
|
||||
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.throws(test(tests[i]), error);
|
||||
}
|
||||
});
|
||||
it("Should not accept empty parameters after elision", function() {
|
||||
var tests = [
|
||||
"(function(,){})()",
|
||||
"(function(a,){})()",
|
||||
];
|
||||
var test = function(code) {
|
||||
return function() {
|
||||
uglify.parse(code, {fromString: true});
|
||||
}
|
||||
}
|
||||
var error = function(e) {
|
||||
return e instanceof uglify.JS_Parse_Error &&
|
||||
e.message === "SyntaxError: Invalid function parameter";
|
||||
}
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.throws(test(tests[i]), error);
|
||||
}
|
||||
});
|
||||
it("Should not accept an initializer when parameter is a rest parameter", function() {
|
||||
var tests = [
|
||||
"(function(...a = b){})()",
|
||||
"(function(a, ...b = [c, d]))"
|
||||
];
|
||||
var test = function(code) {
|
||||
return function () {
|
||||
uglify.parse(code, {fromString: true});
|
||||
}
|
||||
}
|
||||
var error = function (e) {
|
||||
return e instanceof uglify.JS_Parse_Error;
|
||||
}
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.throws(test(tests[i]), error, tests[i]);
|
||||
}
|
||||
});
|
||||
it("Shoult not accept duplicated identifiers inside parameters in strict mode or when using default assigment or spread", function() {
|
||||
// From: ES2016 9.2.12 FunctionDeclarationInstantiation (func, argumentsList)
|
||||
// NOTE Early errors ensure that duplicate parameter names can only occur
|
||||
// in non-strict functions that do not have parameter default values or
|
||||
// rest parameters.
|
||||
var tests = [
|
||||
"(function(a = 1, a){})()",
|
||||
"(function(a, [a = 3]){})()",
|
||||
"(function(a, b, c, d, [{e: [...a]}]){})()",
|
||||
"'use strict'; (function(a, a){})",
|
||||
"(function({a, a = b}))",
|
||||
"(function(a, [...a]){})",
|
||||
"(function(a, ...a){})",
|
||||
"(function(a, [a, ...b]){})",
|
||||
"(function(a, {b: a, c: [...d]}){})",
|
||||
"(function(a, a, {b: [...c]}){})"
|
||||
];
|
||||
var test = function(code) {
|
||||
return function () {
|
||||
uglify.parse(code, {fromString: true});
|
||||
}
|
||||
}
|
||||
var error = function (e) {
|
||||
return e instanceof uglify.JS_Parse_Error &&
|
||||
/^SyntaxError: Parameter [a-zA-Z]+ was used already$/.test(e.message);
|
||||
}
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.throws(test(tests[i]), error, tests[i]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
29
test/mocha/lhs-expressions.js
Normal file
29
test/mocha/lhs-expressions.js
Normal file
@@ -0,0 +1,29 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
|
||||
describe("Left-hand side expressions", function () {
|
||||
it("Should parse destructuring with const/let/var correctly", function () {
|
||||
var decls = uglify.parse('var {a,b} = foo, { c, d } = bar');
|
||||
|
||||
assert.equal(decls.body[0].TYPE, 'Var');
|
||||
assert.equal(decls.body[0].definitions.length, 2);
|
||||
assert.equal(decls.body[0].definitions[0].name.TYPE, 'Destructuring');
|
||||
assert.equal(decls.body[0].definitions[0].value.TYPE, 'SymbolRef');
|
||||
|
||||
var nested_def = uglify.parse('var [{x}] = foo').body[0].definitions[0];
|
||||
|
||||
assert.equal(nested_def.name.names[0].names[0].TYPE, 'SymbolVar');
|
||||
assert.equal(nested_def.name.names[0].names[0].name, 'x');
|
||||
|
||||
var holey_def = uglify.parse('const [,,third] = [1,2,3]').body[0].definitions[0];
|
||||
|
||||
assert.equal(holey_def.name.names[0].TYPE, 'Hole');
|
||||
assert.equal(holey_def.name.names[2].TYPE, 'SymbolConst');
|
||||
|
||||
var expanding_def = uglify.parse('var [first, ...rest] = [1,2,3]').body[0].definitions[0];
|
||||
|
||||
assert.equal(expanding_def.name.names[0].TYPE, 'SymbolVar');
|
||||
assert.equal(expanding_def.name.names[1].TYPE, 'Expansion');
|
||||
assert.equal(expanding_def.name.names[1].expression.TYPE, 'SymbolVar');
|
||||
});
|
||||
});
|
||||
22
test/mocha/try.js
Normal file
22
test/mocha/try.js
Normal file
@@ -0,0 +1,22 @@
|
||||
var assert = require("assert");
|
||||
var uglify = require("../../");
|
||||
|
||||
describe("Try", function() {
|
||||
it("Should not allow catch with an empty parameter", function() {
|
||||
var tests = [
|
||||
"try {} catch() {}"
|
||||
];
|
||||
|
||||
var test = function(code) {
|
||||
return function () {
|
||||
uglify.parse(code, {fromString: true});
|
||||
}
|
||||
}
|
||||
var error = function (e) {
|
||||
return e instanceof uglify.JS_Parse_Error;
|
||||
}
|
||||
for (var i = 0; i < tests.length; i++) {
|
||||
assert.throws(test(tests[i]), error, tests[i]);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -90,7 +90,7 @@ describe("Yield", function() {
|
||||
|
||||
var fail = function(e) {
|
||||
return e instanceof UglifyJS.JS_Parse_Error &&
|
||||
e.message === "SyntaxError: Unexpected yield identifier inside strict mode";
|
||||
/SyntaxError: Unexpected yield identifier (?:as parameter )?inside strict mode/.test(e.message);
|
||||
}
|
||||
|
||||
var test = function(input) {
|
||||
|
||||
138
test/parser.js
138
test/parser.js
@@ -1,138 +0,0 @@
|
||||
|
||||
var UglifyJS = require("..");
|
||||
var ok = require('assert');
|
||||
|
||||
module.exports = function () {
|
||||
console.log("--- Parser tests");
|
||||
|
||||
// Destructuring arguments
|
||||
|
||||
// Function argument nodes are correct
|
||||
function get_args(args) {
|
||||
return args.map(function (arg) {
|
||||
return [arg.TYPE, arg.name];
|
||||
});
|
||||
}
|
||||
|
||||
// Destructurings as arguments
|
||||
var destr_fun1 = UglifyJS.parse('(function ({a, b}) {})').body[0].body;
|
||||
var destr_fun2 = UglifyJS.parse('(function ([a, [b]]) {})').body[0].body;
|
||||
|
||||
ok.equal(destr_fun1.argnames.length, 1);
|
||||
ok.equal(destr_fun2.argnames.length, 1);
|
||||
|
||||
var destr_fun1 = UglifyJS.parse('({a, b}) => null').body[0].body;
|
||||
var destr_fun2 = UglifyJS.parse('([a, [b]]) => null').body[0].body;
|
||||
|
||||
ok.equal(destr_fun1.argnames.length, 1);
|
||||
ok.equal(destr_fun2.argnames.length, 1);
|
||||
|
||||
var destruct1 = destr_fun1.argnames[0];
|
||||
var destruct2 = destr_fun2.argnames[0];
|
||||
|
||||
ok(destruct1 instanceof UglifyJS.AST_Destructuring);
|
||||
ok(destruct2 instanceof UglifyJS.AST_Destructuring);
|
||||
ok(destruct2.names[1] instanceof UglifyJS.AST_Destructuring);
|
||||
|
||||
ok.equal(destruct1.start.value, '{');
|
||||
ok.equal(destruct1.end.value, '}');
|
||||
ok.equal(destruct2.start.value, '[');
|
||||
ok.equal(destruct2.end.value, ']');
|
||||
|
||||
ok.equal(destruct1.is_array, false);
|
||||
ok.equal(destruct2.is_array, true);
|
||||
|
||||
var aAndB = [
|
||||
['SymbolFunarg', 'a'],
|
||||
['SymbolFunarg', 'b']
|
||||
];
|
||||
|
||||
ok.deepEqual(
|
||||
[
|
||||
destruct1.names[0].TYPE,
|
||||
destruct1.names[0].name],
|
||||
aAndB[0]);
|
||||
|
||||
ok.deepEqual(
|
||||
[
|
||||
destruct2.names[1].names[0].TYPE,
|
||||
destruct2.names[1].names[0].name
|
||||
],
|
||||
aAndB[1]);
|
||||
|
||||
ok.deepEqual(
|
||||
get_args(destr_fun1.args_as_names()),
|
||||
aAndB)
|
||||
ok.deepEqual(
|
||||
get_args(destr_fun2.args_as_names()),
|
||||
aAndB)
|
||||
|
||||
// Making sure we don't accidentally accept things which
|
||||
// Aren't argument destructurings
|
||||
|
||||
ok.throws(function () {
|
||||
UglifyJS.parse('(function ([]) {})');
|
||||
}, /Invalid destructuring function parameter/);
|
||||
|
||||
ok.throws(function () {
|
||||
UglifyJS.parse('(function ( { a, [ b ] } ) { })')
|
||||
});
|
||||
|
||||
ok.throws(function () {
|
||||
UglifyJS.parse('(function (1) { })');
|
||||
}, /Invalid function parameter/);
|
||||
|
||||
ok.throws(function () {
|
||||
UglifyJS.parse('(function (this) { })');
|
||||
});
|
||||
|
||||
ok.throws(function () {
|
||||
UglifyJS.parse('(function ([1]) { })');
|
||||
}, /Invalid function parameter/);
|
||||
|
||||
ok.throws(function () {
|
||||
UglifyJS.parse('(function [a] { })');
|
||||
});
|
||||
|
||||
// Destructuring variable declaration
|
||||
|
||||
var decls = UglifyJS.parse('var {a,b} = foo, { c, d } = bar');
|
||||
|
||||
ok.equal(decls.body[0].TYPE, 'Var');
|
||||
ok.equal(decls.body[0].definitions.length, 2);
|
||||
ok.equal(decls.body[0].definitions[0].name.TYPE, 'Destructuring');
|
||||
ok.equal(decls.body[0].definitions[0].value.TYPE, 'SymbolRef');
|
||||
|
||||
var nested_def = UglifyJS.parse('var [{x}] = foo').body[0].definitions[0];
|
||||
|
||||
ok.equal(nested_def.name.names[0].names[0].TYPE, 'SymbolVar');
|
||||
ok.equal(nested_def.name.names[0].names[0].name, 'x');
|
||||
|
||||
var holey_def = UglifyJS.parse('const [,,third] = [1,2,3]').body[0].definitions[0];
|
||||
|
||||
ok.equal(holey_def.name.names[0].TYPE, 'Hole');
|
||||
ok.equal(holey_def.name.names[2].TYPE, 'SymbolConst');
|
||||
|
||||
var expanding_def = UglifyJS.parse('var [first, ...rest] = [1,2,3]').body[0].definitions[0];
|
||||
|
||||
ok.equal(expanding_def.name.names[0].TYPE, 'SymbolVar');
|
||||
ok.equal(expanding_def.name.names[1].TYPE, 'Expansion');
|
||||
ok.equal(expanding_def.name.names[1].expression.TYPE, 'SymbolVar');
|
||||
|
||||
// generators
|
||||
var generators_def = UglifyJS.parse('function* fn() {}').body[0];
|
||||
ok.equal(generators_def.is_generator, true);
|
||||
|
||||
ok.throws(function () {
|
||||
UglifyJS.parse('function* (){ }');
|
||||
});
|
||||
|
||||
var generators_yield_def = UglifyJS.parse('function* fn() {\nyield remote();\}').body[0].body[0];
|
||||
ok.strictEqual(generators_yield_def.body.is_star, false);
|
||||
}
|
||||
|
||||
// Run standalone
|
||||
if (module.parent === null) {
|
||||
module.exports();
|
||||
}
|
||||
|
||||
@@ -30,10 +30,6 @@ run_ast_conversion_tests({
|
||||
iterations: 1000
|
||||
});
|
||||
|
||||
var run_parser_tests = require('./parser.js');
|
||||
|
||||
run_parser_tests();
|
||||
|
||||
/* -----[ utils ]----- */
|
||||
|
||||
function tmpl() {
|
||||
|
||||
Reference in New Issue
Block a user