File indexing completed on 2024-04-28 15:28:37
0001 /////////////////////////////// 0002 // empty bodies 0003 0004 function empty1() { ; } 0005 shouldBe("empty1()", "undefined"); 0006 0007 function empty2() { } 0008 shouldBe("empty2()", "undefined"); 0009 0010 var g = 2; 0011 var obj = new Object(); 0012 with (obj) { 0013 obj.func = function(a) { return g*l*a; }; 0014 } 0015 obj.l = 3; 0016 0017 shouldBe("obj.func(11)", "66"); 0018 0019 /////////////////////////////// 0020 0021 function ctor(xx) { 0022 this.x = xx; 0023 this.dummy = new Array(); // once broke the returned completion 0024 } 0025 0026 c = new ctor(11); 0027 shouldBe("c.x", "11"); 0028 0029 /////////////////////////////// 0030 // anonymous functions 0031 /////////////////////////////// 0032 0033 f = function (arg) { 0034 return arg; 0035 }; 0036 0037 0038 shouldBe("f('bbbbb')", "'bbbbb'"); 0039 0040 ///////////////////////////// 0041 // named function expressions 0042 ///////////////////////////// 0043 0044 var objectWithFunctionProperty = { f: function z(a) { return a*a; } }; 0045 shouldBe("objectWithFunctionProperty.f(3)", "9"); 0046 0047 //////////////////////////////////// 0048 0049 function f() {return 1;}; 0050 0051 // just verify that this can be parsed 0052 Math.round(function anon() { }); 0053 0054 // verify that this is not broken (happened once) 0055 function onceBroken() { return new String(); } 0056 0057 /////////////////////////////// 0058 // arguments object 0059 /////////////////////////////// 0060 0061 function foo() { 0062 var result = "|"; 0063 for (i = 0; i < arguments.length; i++) 0064 result += arguments[i] + "|"; 0065 return result; 0066 } 0067 0068 shouldBe("foo()", "'|'"); 0069 shouldBe("foo('bar')", "'|bar|'"); 0070 shouldBe("foo('bar', 'x')", "'|bar|x|'"); 0071 0072 function foo2(a) { 0073 var i = 0; 0074 for(a in arguments) // should NOT be enumerable 0075 i++; 0076 return i; 0077 } 0078 0079 shouldBe("foo2(7)", "0"); 0080 0081 // I have my doubts about the standard conformance of this 0082 function foo3(i, j) { 0083 switch(i) { 0084 case 0: 0085 return foo3.arguments.length; 0086 case 1: 0087 return foo3.arguments; 0088 case 2: 0089 return foo3.j; 0090 } 0091 } 0092 0093 shouldBe("foo3(0, 99)", "2"); 0094 shouldBe("foo3(1, 99).length", "2"); 0095 //shouldBe("foo3(2, 99)", "99"); // IE doesn't support this either 0096 0097 /////////////////////////////// 0098 // nested function declarations 0099 /////////////////////////////// 0100 0101 function nest0(a, b) 0102 { 0103 function nest1(c) { return c*c; } 0104 return nest1(a*b); 0105 } 0106 shouldBe("nest0(2,3)", "36"); 0107 0108 /////////////////////////////// 0109 // Function object 0110 /////////////////////////////// 0111 0112 shouldBe("(new Function('return 11;'))()", "11"); 0113 shouldBe("(new Function('', 'return 22;'))()", "22"); 0114 shouldBe("(new Function('a', 'b', 'return a*b;'))(11, 3)", "33"); 0115 shouldBe("(new Function(' a ', ' b ', 'return a*b;'))(11, 4)", "44"); 0116 shouldBe("(new Function(' a,b ', ' c ', 'return a*b;'))(11, 5)", "55"); 0117 shouldBe("(new Function(' a,b ', ' c3 ', 'return a*b;'))(11, 6)", "66"); 0118 0119 0120 /////////////////////////////// 0121 // length property 0122 function funcp3(a, b, c) { } 0123 shouldBe("funcp3.length", "3"); 0124 shouldBe("(function(a, b, c, d) { }).length", "4"); 0125 shouldBe("(new Function('a', 'b', '')).length", "2"); 0126 0127 // recursive call 0128 function f4(i) 0129 { 0130 return i == 1 ? 1 : i*f4(i-1); 0131 } 0132 0133 shouldBe("f4(4)", "24"); 0134 0135 function f5(a) { 0136 return f6(); 0137 } 0138 0139 function f6() { 0140 return f5.arguments[0]; 0141 } 0142 0143 shouldBe("f5(11)", "11"); 0144 shouldBe("f5.arguments", "null"); 0145 0146 /////////////////////////////// 0147 // calling conventions 0148 /////////////////////////////// 0149 0150 function manipulate(x) { 0151 x[0] = 99; // should operate on reference 0152 x = "nothing"; // should detach 0153 } 0154 var arr = new Array(1, 2, 3); 0155 manipulate(arr); 0156 shouldBe("arr[0]", "99"); 0157 arr = [1, 2, 3]; 0158 manipulate(arr); 0159 shouldBe("arr[0]", "99"); 0160 0161 /////////////////////////////// 0162 // toString() on functions 0163 /////////////////////////////// 0164 0165 function orgFunc(s) { return 'Hello ' + s; } 0166 eval("var orgFuncClone = " + orgFunc); 0167 shouldBe("typeof orgFuncClone", "'function'"); 0168 shouldBe("orgFuncClone('world')", "'Hello world'"); 0169 0170 function groupFunc(a, b) { return (a+b)*3; } // check for () being preserved 0171 eval("var groupClone = " + groupFunc); 0172 shouldBe("groupClone(1, 2)", "9"); 0173 0174 /////////////////////////////// 0175 // shadowed functions 0176 /////////////////////////////// 0177 0178 function shadow() { return 1; } 0179 function shadow() { return 2; } 0180 shouldBe("shadow()", "2"); 0181 0182 /**** not portable ******* 0183 0184 /////////////////////////////// 0185 // nested functions 0186 0187 var nest_property = "global nest"; 0188 0189 function nested_outer() { 0190 0191 function nested_inner() { 0192 return nest_property; 0193 } 0194 0195 } 0196 0197 function not_nested() { 0198 return nest_property; 0199 } 0200 0201 nested_outer.nest_property = "outer nest"; 0202 0203 var nested = nested_outer.nested_inner; 0204 shouldBe("nested()","'outer nest'"); 0205 0206 var not_nestedret = not_nested(); 0207 shouldBe("not_nestedret","'global nest'"); 0208 0209 *** end of non-portable tests ***** */ 0210 0211 /////////////////////////////// 0212 // other properties 0213 /////////////////////////////// 0214 function sample() { } 0215 shouldBeUndefined("sample.prototype.prototype"); 0216 shouldBeTrue("sample.prototype.constructor == sample"); 0217 0218 var caught = false; 0219 try { 0220 sample.apply(1, 1); // invalid argument 0221 } catch(dummy) { 0222 caught = true; 0223 } 0224 shouldBeTrue("caught"); 0225 0226 0227 function functionWithVarOverride(a) { 0228 var a = 2; 0229 return a; 0230 } 0231 0232 shouldBe("functionWithVarOverride(1)", "2"); 0233 0234 // named function expressions 0235 var fabs = function abs(x) { return x >= 0 ? x : abs(-x); } 0236 shouldBe("fabs(-4)", "4"); 0237 0238 function fh(x) { 0239 return function diff(arg) { 0240 if (arg == x) 0241 return 0; 0242 else 0243 return 1 + diff(arg + 1); 0244 }; 0245 }; 0246 shouldBe("fh(5)(2)", "3"); 0247 0248 // test flags of function prototype's constructor property 0249 // inspired by an Acid3 test 0250 var funcToModify1 = function () { 1 }; 0251 funcToModify1.prototype.constructor = "altCtor1"; 0252 shouldBe("funcToModify1.prototype.constructor", "'altCtor1'"); 0253 delete funcToModify1.prototype.constructor; 0254 shouldBe("funcToModify1.prototype.constructor", "Object.prototype.constructor"); 0255 function funcToModify2() { 1 }; 0256 funcToModify2.prototype.constructor = "altCtor2"; 0257 shouldBe("funcToModify2.prototype.constructor", "'altCtor2'"); 0258 delete funcToModify2.prototype.constructor; 0259 shouldBe("funcToModify2.prototype.constructor", "Object.prototype.constructor"); 0260 0261 debug("Done"); 0262 0263 // .call 0264 0265 var testThis = {}; 0266 0267 function callTest(a, b) { 0268 _saveThis = this; 0269 _saveA = a; 0270 _saveB = b; 0271 shouldBe("_saveThis", "testThis"); 0272 shouldBe("_saveA", 1); 0273 shouldBe("_saveB", 42); 0274 } 0275 0276 callTest.call(testThis, 1, 42);