Source code
Revision control
Copy as Markdown
Other Tools
load(libdir + 'asserts.js');
load(libdir + 'eqArrayHelper.js');
assertThrowsInstanceOf(() => new Function('[...a, ,] = []'), SyntaxError, 'trailing elision');
assertThrowsInstanceOf(() => new Function('[a, ...b, c] = []'), SyntaxError, 'trailing param');
assertThrowsInstanceOf(() => new Function('[...a=b] = []'), SyntaxError, 'assignment expression');
assertThrowsInstanceOf(() => new Function('[...a()] = []'), SyntaxError, 'call expression');
assertThrowsInstanceOf(() => new Function('[...(a,b)] = []'), SyntaxError, 'comma expression');
assertThrowsInstanceOf(() => new Function('[...a++] = []'), SyntaxError, 'postfix expression');
assertThrowsInstanceOf(() => new Function('[...!a] = []'), SyntaxError, 'unary expression');
assertThrowsInstanceOf(() => new Function('[...a+b] = []'), SyntaxError, 'binary expression');
assertThrowsInstanceOf(() => new Function('var [...a.x] = []'), SyntaxError, 'lvalue expression in declaration');
assertThrowsInstanceOf(() => new Function('var [...(b)] = []'), SyntaxError);
assertThrowsInstanceOf(() => new Function('[...b,] = []'), SyntaxError);
assertThrowsInstanceOf(() => {
try {
eval('let [...[...x]] = (() => { throw "foo"; } )();');
} catch(e) {
assertEq(e, "foo");
}
x;
}, ReferenceError);
var inputArray = [1, 2, 3];
var inputDeep = [1, inputArray];
var inputObject = {a: inputArray};
var inputStr = 'str';
function *inputGenerator() {
yield 1;
yield 2;
yield 3;
}
var o = {prop: null, call: function () { return o; }};
var expected = [2, 3];
var expectedStr = ['t', 'r'];
function testAll(fn) {
testDeclaration(fn);
o.prop = null;
assertEqArray(fn('[, ...(o.prop)]', inputArray, 'o.prop'), expected);
o.prop = null;
assertEqArray(fn('[, ...(o.call().prop)]', inputArray, 'o.prop'), expected);
o.prop = null;
assertEqArray(fn('[, ...[...(o.prop)]]', inputArray, 'o.prop'), expected);
o.prop = null;
assertEqArray(fn('[, ...[...(o.call().prop)]]', inputArray, 'o.prop'), expected);
}
function testDeclaration(fn) {
testStr(fn);
assertEqArray(fn('[, ...rest]', inputArray), expected);
assertEqArray(fn('[, ...rest]', inputGenerator()), expected);
assertEqArray(fn('[, [, ...rest]]', inputDeep), expected);
assertEqArray(fn('{a: [, ...rest]}', inputObject), expected);
assertEqArray(fn('[, ...[...rest]]', inputArray), expected);
assertEqArray(fn('[, ...[...rest]]', inputGenerator()), expected);
assertEqArray(fn('[, [, ...[...rest]]]', inputDeep), expected);
assertEqArray(fn('{a: [, ...[...rest]]}', inputObject), expected);
assertEqArray(fn('[, ...{0: a, 1: b}]', inputArray, '[a, b]'), expected);
assertEqArray(fn('[, ...{0: a, 1: b}]', inputGenerator(), '[a, b]'), expected);
assertEqArray(fn('[, [, ...{0: a, 1: b}]]', inputDeep, '[a, b]'), expected);
assertEqArray(fn('{a: [, ...{0: a, 1: b}]}', inputObject, '[a, b]'), expected);
}
function testStr(fn) {
assertEqArray(fn('[, ...rest]', inputStr), expectedStr);
assertEqArray(fn('[, ...[...rest]]', inputStr), expectedStr);
assertEqArray(fn('[, ...{0: a, 1: b}]', inputStr, '[a, b]'), expectedStr);
}
function testForIn(pattern, input, binding) {
binding = binding || 'rest';
return new Function('input',
'for (var ' + pattern + ' in {[input]: 1}) {}' +
'return ' + binding
)(input);
}
testStr(testForIn);
function testVar(pattern, input, binding) {
binding = binding || 'rest';
return new Function('input',
'var ' + pattern + ' = input;' +
'return ' + binding
)(input);
}
testDeclaration(testVar);
function testGlobal(pattern, input, binding) {
binding = binding || 'rest';
return new Function('input',
'(' + pattern + ' = input);' +
'return ' + binding
)(input);
}
testAll(testGlobal);
function testClosure(pattern, input, binding) {
binding = binding || 'rest';
const decl = binding.replace('[', '').replace(']', '');
return new Function('input',
'var ' + decl + '; (function () {' +
'(' + pattern + ' = input);' +
'})();' +
'return ' + binding
)(input);
}
testDeclaration(testClosure);
function testArgument(pattern, input, binding) {
binding = binding || 'rest';
return new Function('input',
'return (function (' + pattern + ') {' +
'return ' + binding + '; })(input);'
)(input);
}
testDeclaration(testArgument);
function testArgumentFunction(pattern, input, binding) {
binding = binding || 'rest';
return new Function(pattern,
'return ' + binding
)(input);
}
// ES6 requires the `Function` constructor to accept arbitrary
// `BindingElement`s as formal parameters.
testDeclaration(testArgumentFunction);
function testThrow(pattern, input, binding) {
binding = binding || 'rest';
return new Function('input',
'try { throw input }' +
'catch(' + pattern + ') {' +
'return ' + binding + '; }'
)(input);
}
testDeclaration(testThrow);