blob: 160d18559359500dae35907d748e278a7bc6167a [file] [log] [blame]
function assert(cond, msg = "") {
if (!cond)
throw new Error(msg);
}
noInline(assert);
function shouldThrow(func) {
var hadError = false;
try {
func()
} catch (e) {
hadError = true;
}
assert(hadError, "Did not throw");
}
noInline(shouldThrow);
function shouldThrowSyntaxError(str) {
var hadError = false;
try {
eval(str);
} catch (e) {
if (e instanceof SyntaxError)
hadError = true;
}
assert(hadError, "Did not throw syntax error");
}
noInline(shouldThrowSyntaxError);
function shouldThrowTDZ(func) {
var hasThrown = false;
try {
func();
} catch(e) {
if (e.name.indexOf("ReferenceError") !== -1)
hasThrown = true;
}
assert(hasThrown);
}
noInline(shouldThrowTDZ);
function basic(x, y=x) {
assert(y === x, "basics don't work.")
}
basic(20);
basic("hello");
basic({foo: 20});
basic(undefined);
;(function(){
var scopeVariable = {hello: "world"};
function basicScope(x = scopeVariable) {
assert(x === scopeVariable);
}
basicScope();
})();
function basicFunctionCaptureInDefault(theArg = 20, y = function() {return theArg}) {
assert(theArg === y(), "y should return x.");
theArg = {};
assert(theArg === y(), "y should return x.");
}
basicFunctionCaptureInDefault()
basicFunctionCaptureInDefault(undefined)
function basicCaptured(x = 20, y = x) {
assert(x === y, "y should equal x");
function mutate() { x = "mutation"; }
mutate()
assert(x !== y, "y should not equal x");
}
basicCaptured()
basicCaptured(undefined)
function tricky(globalX = (globalX = "x"), y = (globalX = 20)) {
assert(globalX === 20);
assert(globalX === y);
}
shouldThrow(tricky);
function strict(x, y = x) {
assert(x === y);
}
strict(20);
strict(undefined);
function playground(x = "foo", y = "bar") {
return {x, y}
}
assert(playground().x === "foo")
assert(playground(undefined).x === "foo")
assert(playground(undefined, 20).x === "foo")
assert(playground(null).x === null)
assert(playground().y === "bar")
assert(playground(undefined, undefined).y === "bar")
assert(playground("hello", undefined).y === "bar")
assert(playground("bar").x === playground(undefined, undefined).y)
assert(playground(10).x === 10)
assert(playground(undefined, 20).y === 20)
assert(playground(undefined, null).y === null)
function scoping(f = function() { return local;}) {
shouldThrow(f);
var local = 10;
shouldThrow(f);
}
scoping();
function augmentsArguments1(x = 20) {
assert(x === 20);
arguments[0] = 10;
assert(x === 20);
x = 15;
assert(x === 15);
assert(arguments[0] === 10);
}
augmentsArguments1(undefined);
function augmentsArguments2(x = 20) {
assert(x === 20);
arguments[0] = 10;
assert(x === 20);
assert(arguments[0] === 10);
x = 15;
assert(x === 15);
assert(arguments[0] === 10);
function augment() { x = 40 }
augment()
assert(x === 40);
assert(arguments[0] === 10);
}
augmentsArguments2(undefined);
function augmentsArguments3(x = 10) {
assert(x === 10);
assert(arguments[0] === undefined);
x = 20;
assert(arguments[0] === undefined);
}
augmentsArguments3();
function augmentsArguments4(x) {
"use strict";
function inner(x = 10) {
assert(x === 10);
assert(arguments[0] === undefined);
x = 20;
assert(arguments[0] === undefined);
}
inner(x);
}
augmentsArguments4();
augmentsArguments4(undefined);
function augmentsArguments5(x) {
"use strict";
function inner(x = 10) {
assert(x === 20);
assert(arguments[0] === 20);
x = 20;
assert(arguments[0] === 20);
}
inner(x);
}
augmentsArguments5(20);
;(function () {
var outer = "outer";
function foo(a = outer, b = function() { return a; }, c = function(v) { a = v; }) {
var a;
assert(a === "outer");
a = 20;
assert(a === 20);
assert(b() === "outer");
c("hello");
assert(b() === "hello");
}
function bar(a = outer, b = function() { return a; }, c = function(v) { a = v; }) {
with({}) {
var a;
assert(a === "outer");
a = 20;
assert(a === 20);
assert(b() === "outer");
c("hello");
assert(b() === "hello");
}
}
function baz(x = function() { return y; }, y = "y") {
assert(x() === "y");
assert(x() === y);
assert(y === y);
}
function jaz(x = function() { return y; }, y = "y") {
return x;
}
function taz(x = 10, y = eval("x + 1")) {
assert(y === 11);
}
for (var i = 0; i < 1000; i++) {
foo();
bar();
baz();
assert(jaz(undefined, 20)() === 20);
assert(jaz(undefined, undefined)() === "y");
assert(jaz(undefined, {x: "x"})().x === "x");
taz();
}
})();
// Length
function named1(a){};
function named2(a=1){};
function named3(a,b){};
function named4(a,b=1){};
function named5(a=1,b=1){};
function named6(a,b,c){};
function named7(a=1,b,c){};
function named8(a,b=1,c){};
function named9(a,b,c=1){};
function named10(a,...b){};
function named11(a=1,...b){};
function named12(a=10,b,c=20,...r){};
assert( named1.length === 1 );
assert( named2.length === 0 );
assert( named3.length === 2 );
assert( named4.length === 1 );
assert( named5.length === 0 );
assert( named6.length === 3 );
assert( named7.length === 0 );
assert( named8.length === 1 );
assert( named9.length === 2 );
assert( named10.length === 1 );
assert( named11.length === 0 );
assert( named12.length === 0 );
assert( (function(a){}).length === 1 );
assert( (function(a=1){}).length === 0 );
assert( (function(a,b){}).length === 2 );
assert( (function(a,b=1){}).length === 1 );
assert( (function(a=1,b=1){}).length === 0 );
assert( (function(a,b,c){}).length === 3 );
assert( (function(a=1,b,c){}).length === 0 );
assert( (function(a,b=1,c){}).length === 1 );
assert( (function(a,b,c=1){}).length === 2 );
assert( (function(a,...b){}).length === 1 );
assert( (function(a=1,...b){}).length === 0 );
assert( (function(a=10,b,c=20,...r){}).length === 0 );
assert( (function*(a){}).length === 1 );
assert( (function*(a=1){}).length === 0 );
assert( (function*(a,b){}).length === 2 );
assert( (function*(a,b=1){}).length === 1 );
assert( (function*(a=1,b=1){}).length === 0 );
assert( (function*(a,b,c){}).length === 3 );
assert( (function*(a=1,b,c){}).length === 0 );
assert( (function*(a,b=1,c){}).length === 1 );
assert( (function*(a,b,c=1){}).length === 2 );
assert( (function*(a,...b){}).length === 1 );
assert( (function*(a=1,...b){}).length === 0 );
assert( (function*(a=10,b,c=20,...r){}).length === 0 );
assert( ((a)=>{}).length === 1 );
assert( ((a=1)=>{}).length === 0 );
assert( ((a,b)=>{}).length === 2 );
assert( ((a,b=1)=>{}).length === 1 );
assert( ((a=1,b=1)=>{}).length === 0 );
assert( ((a,b,c)=>{}).length === 3 );
assert( ((a=1,b,c)=>{}).length === 0 );
assert( ((a,b=1,c)=>{}).length === 1 );
assert( ((a,b,c=1)=>{}).length === 2 );
assert( ((a,...b)=>{}).length === 1 );
assert( ((a=1,...b)=>{}).length === 0 );
assert( ((a=10,b,c=20,...r)=>{}).length === 0 );
assert( Object.getOwnPropertyDescriptor({set setter(a){}}, "setter").set.length === 1 );
assert( Object.getOwnPropertyDescriptor({set setter(a=1){}}, "setter").set.length === 0 );
assert( ({method(a){}}).method.length === 1 );
assert( ({method(a=1){}}).method.length === 0 );
assert( ({method(a,b){}}).method.length === 2 );
assert( ({method(a,b=1){}}).method.length === 1 );
assert( ({method(a=1,b=1){}}).method.length === 0 );
assert( ({method(a,b,c){}}).method.length === 3 );
assert( ({method(a=1,b,c){}}).method.length === 0 );
assert( ({method(a,b=1,c){}}).method.length === 1 );
assert( ({method(a,b,c=1){}}).method.length === 2 );
assert( ({method(a,...b){}}).method.length === 1 );
assert( ({method(a=1,...b){}}).method.length === 0 );
assert( ({method(a=10,b,c=20,...r){}}).method.length === 0 );
assert( ({*method(a){}}).method.length === 1 );
assert( ({*method(a=1){}}).method.length === 0 );
assert( ({*method(a,b){}}).method.length === 2 );
assert( ({*method(a,b=1){}}).method.length === 1 );
assert( ({*method(a=1,b=1){}}).method.length === 0 );
assert( ({*method(a,b,c){}}).method.length === 3 );
assert( ({*method(a=1,b,c){}}).method.length === 0 );
assert( ({*method(a,b=1,c){}}).method.length === 1 );
assert( ({*method(a,b,c=1){}}).method.length === 2 );
assert( ({*method(a,...b){}}).method.length === 1 );
assert( ({*method(a=1,...b){}}).method.length === 0 );
assert( ({*method(a=10,b,c=20,...r){}}).method.length === 0 );
assert( (class {static method(a){}}).method.length === 1 );
assert( (class {static method(a=1){}}).method.length === 0 );
assert( (class {static method(a,b){}}).method.length === 2 );
assert( (class {static method(a,b=1){}}).method.length === 1 );
assert( (class {static method(a=1,b=1){}}).method.length === 0 );
assert( (class {static method(a,b,c){}}).method.length === 3 );
assert( (class {static method(a=1,b,c){}}).method.length === 0 );
assert( (class {static method(a,b=1,c){}}).method.length === 1 );
assert( (class {static method(a,b,c=1){}}).method.length === 2 );
assert( (class {static method(a,...b){}}).method.length === 1 );
assert( (class {static method(a=1,...b){}}).method.length === 0 );
assert( (class {static method(a=10,b,c=20,...r){}}).method.length === 0 );
// TDZ errors.
;(function() {
function basicError(x = y, y) { }
function basicError2(x = x) { }
function baz(z = {p: x}, x = z) {}
function bar(x = {p: [x]}) {}
function jaz(x = eval("y"), y) { }
function kaz(x = eval(";(function() { return y})();"), y) { }
for (var i = 0; i < 1000; i++) {
shouldThrowTDZ(basicError);
shouldThrowTDZ(basicError2);
shouldThrowTDZ(baz);
shouldThrowTDZ(bar);
shouldThrowTDZ(jaz);
shouldThrowTDZ(kaz);
}
})();
// Test proper variable binding.
;(function() {
function foo(a = function() { return b; }, {b}) {
assert(a() === 34);
assert(b === 34);
b = 50;
assert(a() === 50);
assert(b === 50);
}
function bar(a = function(x) { b = x; }, {b}) {
assert(b === 34);
a(50);
assert(b === 50);
}
function baz(f1 = function(x) { b = x; }, f2 = function() { return b; }, {b}) {
var b;
assert(b === 34);
assert(f2() === 34);
f1(50);
assert(b === 34);
assert(f2() === 50);
}
noInline(foo);
noInline(bar);
noInline(baz);
for (let i = 0; i < 1000; i++) {
foo(undefined, {b: 34});
bar(undefined, {b: 34});
baz(undefined, undefined, {b: 34});
}
})();
// Syntax errors.
shouldThrowSyntaxError("function b(a = 20, a = 40) {}");
shouldThrowSyntaxError("function b(aaaaa = 20,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v, aaaaa = 40) {}");
shouldThrowSyntaxError("function b(a = 20, {a}) {}");
shouldThrowSyntaxError("function b(a = 20, a) {}");
shouldThrowSyntaxError("function b(a, a = 20) {}");
shouldThrowSyntaxError("function b(a, a, b = 20) {}");
shouldThrowSyntaxError("function b({a, a} = 20) {}");
shouldThrowSyntaxError("function b({a, a} = 20) {}");