///////////////////////////////
// empty bodies
function empty1() { ; }
shouldBe("empty1()", "undefined");
function empty2() { }
shouldBe("empty2()", "undefined");
var g = 2;
var obj = new Object();
with (obj) {
obj.func = function(a) { return g*l*a; };
}
obj.l = 3;
shouldBe("obj.func(11)", "66");
///////////////////////////////
function ctor(xx) {
this.x = xx;
this.dummy = new Array(); // once broke the returned completion
}
c = new ctor(11);
shouldBe("c.x", "11");
///////////////////////////////
// anonymous functions
///////////////////////////////
f = function (arg) {
return arg;
};
shouldBe("f('bbbbb')", "'bbbbb'");
function f() {return 1;};
// just verify that this can be parsed
Math.round(function anon() { });
///////////////////////////////
// arguments object
///////////////////////////////
function foo() {
var result = "|";
for (i = 0; i < arguments.length; i++)
result += arguments[i] + "|";
return result;
}
shouldBe("foo()", "'|'");
shouldBe("foo('bar')", "'|bar|'");
shouldBe("foo('bar', 'x')", "'|bar|x|'");
function foo2(a) {
var i = 0;
for(a in arguments) // should be enumerable
i++;
return i;
}
shouldBe("foo2(7)", "1");
// I have my doubts about the standard conformance of this
function foo3(i, j) {
switch(i) {
case 0:
return foo3.arguments.length;
case 1:
return foo3.arguments;
case 2:
return foo3.j;
}
}
shouldBe("foo3(0, 99)", "2");
shouldBe("foo3(1, 99).length", "2");
//shouldBe("foo3(2, 99)", "99"); // IE doesn't support this either
///////////////////////////////
// nested function declarations
///////////////////////////////
function nest0(a, b)
{
function nest1(c) { return c*c; }
return nest1(a*b);
}
shouldBe("nest0(2,3)", "36");
///////////////////////////////
// Function object
///////////////////////////////
shouldBe("(new Function('return 11;'))()", "11");
shouldBe("(new Function('', 'return 22;'))()", "22");
shouldBe("(new Function('a', 'b', 'return a*b;'))(11, 3)", "33");
shouldBe("(new Function(' a ', ' b ', 'return a*b;'))(11, 4)", "44");
shouldBe("(new Function(' a,b ', ' c ', 'return a*b;'))(11, 5)", "55");
shouldBe("(new Function(' a,b ', ' c3 ', 'return a*b;'))(11, 6)", "66");
///////////////////////////////
// length property
function funcp3(a, b, c) { }
shouldBe("funcp3.length", "3");
shouldBe("(function(a, b, c, d) { }).length", "4");
shouldBe("(new Function('a', 'b', '')).length", "2");
// recursive call
function f4(i)
{
return i == 1 ? 1 : i*f4(i-1);
}
shouldBe("f4(4)", "24");
function f5(a) {
return f6();
}
function f6() {
return f5.arguments[0];
}
shouldBe("f5(11)", "11");
shouldBe("f5.arguments", "null");
///////////////////////////////
// calling conventions
///////////////////////////////
function manipulate(x) {
x[0] = 99; // should operate on reference
x = "nothing"; // should detach
}
var arr = new Array(1, 2, 3);
manipulate(arr);
shouldBe("arr[0]", "99");
arr = [1, 2, 3];
manipulate(arr);
shouldBe("arr[0]", "99");
///////////////////////////////
// toString() on functions
///////////////////////////////
function orgFunc(s) { return 'Hello ' + s; }
eval("var orgFuncClone = " + orgFunc);
shouldBe("typeof orgFuncClone", "'function'");
shouldBe("orgFuncClone('world')", "'Hello world'");
function groupFunc(a, b) { return (a+b)*3; } // check for () being preserved
eval("var groupClone = " + groupFunc);
shouldBe("groupClone(1, 2)", "9");
var sinStr = 'function sin() {\n [native code]\n}'
shouldBe("String(Math.sin)", "sinStr");
///////////////////////////////
// shadowed functions
///////////////////////////////
function shadow() { return 1; }
function shadow() { return 2; }
shouldBe("shadow()", "2");
///////////////////////////////
// nested functions
var nest_property = "global nest";
function nested_outer() {
var nest_property = "inner nest";
function nested_inner() {
return nest_property;
}
return nested_inner;
}
function not_nested() {
return nest_property;
}
nested_outer.nest_property = "outer nest";
var nested = nested_outer();
var nestedret = nested();
shouldBe("nestedret","'inner nest'");
var not_nestedret = not_nested();
shouldBe("not_nestedret","'global nest'");
///////////////////////////////
// other properties
///////////////////////////////
function sample() { }
shouldBeUndefined("sample.prototype.prototype");
shouldBeTrue("sample.prototype.constructor == sample");
var caught = false;
try {
sample.apply(1, 1); // invalid argument
} catch(dummy) {
caught = true;
}
shouldBeTrue("caught");
function functionWithVarOverride(a) {
var a = 2;
return a;
}
shouldBe("functionWithVarOverride(1)", "2");