diff options
Diffstat (limited to 'js/src/tests/ecma_5/misc')
23 files changed, 1842 insertions, 0 deletions
diff --git a/js/src/tests/ecma_5/misc/browser.js b/js/src/tests/ecma_5/misc/browser.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/js/src/tests/ecma_5/misc/browser.js diff --git a/js/src/tests/ecma_5/misc/bug1126318.js b/js/src/tests/ecma_5/misc/bug1126318.js new file mode 100644 index 000000000..73ccdc07a --- /dev/null +++ b/js/src/tests/ecma_5/misc/bug1126318.js @@ -0,0 +1,13 @@ +if (typeof window === "undefined") + window = this; + +Object.defineProperty(window, "foo", { + get: function() { return 5; }, + configurable: true +}); + +for (var i = 0; i < 100; ++i) + assertEq(window.foo, 5); + +if (typeof reportCompare === "function") + reportCompare(0, 0); diff --git a/js/src/tests/ecma_5/misc/builtin-methods-reject-null-undefined-this.js b/js/src/tests/ecma_5/misc/builtin-methods-reject-null-undefined-this.js new file mode 100644 index 000000000..a2275c1b8 --- /dev/null +++ b/js/src/tests/ecma_5/misc/builtin-methods-reject-null-undefined-this.js @@ -0,0 +1,153 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 619283; +var summary = + "ECMAScript built-in methods that immediately throw when |this| is " + + "|undefined| or |null| (due to CheckObjectCoercible, ToObject, or ToString)"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +// We can't just exhaustively loop over everything because 1) method properties +// might be extensions with special |this| handling, and 2) some methods don't +// *quite* immediately throw a TypeError, first thing, if |this| is |undefined| +// or |null|, or their algorithms are very slightly ambiguous about whether they +// do. Why? Ipse-dixitism. *shrug* + +var ClassToMethodMap = + { + Object: [/* "toString" has special |this| handling */ + "toLocaleString", "valueOf", "hasOwnProperty", + /* + * "isPrototypeOf" has special |this| handling already tested in + * ecma_5/Object/isPrototypeOf.js. + */ + /* + * "isPrototypeOf" has special |this| handling already tested in + * ecma_5/Object/propertyIsEnumerable.js. + */], + // Function methods often don't ToObject(this) as their very first step, + // and they're already stepwise well-tested such that manual tests here + // would be redundant. + Array: ["toString", "toLocaleString", "concat", "join", "pop", "push", + "reverse", "shift", "slice", "sort", "splice", "unshift", + "indexOf", "lastIndexOf", "every", "some", "forEach", "map", + "filter", "reduce", "reduceRight"], + String: ["toString", "valueOf", "charAt", "charCodeAt", "concat", + "indexOf", "lastIndexOf", "localeCompare", "match", "replace", + "search", "slice", "split", "substring", "toLowerCase", + "toLocaleLowerCase", "toUpperCase", "toLocaleUpperCase", "trim", + /* + * "trimLeft" and "trimRight" are non-standard and thus are tested + * in ecma_5/extensions/trim-extensions.js. + */ + ], + Boolean: ["toString", "valueOf"], + Number: ["toString", "toLocaleString", "valueOf", + /* + * toFixed doesn't *immediately* test |this| for number or + * Number-ness, but because the ToInteger(void 0) which arguably + * precedes it in the toFixed algorithm won't throw in this test, + * we don't need to specially test it. + */ + "toFixed", + "toExponential", "toPrecision"], + Date: ["toDateString", "toTimeString", "toLocaleString", + "toLocaleDateString", "toLocaleTimeString", "valueOf", "getTime", + "getFullYear", "getUTCFullYear", "getMonth", "getUTCMonth", + "getDate", "getUTCDate", "getDay", "getUTCDay", "getHours", + "getUTCHours", "getMinutes", "getUTCMinutes", "getSeconds", + "getUTCSeconds", "getMilliseconds", "getUTCMilliseconds", + /* + * toFixed doesn't *immediately* test |this| for number or + * Number-ness, but because the TimeClip(ToNumber(void 0)) which + * arguably precedes it in the setTime algorithm won't throw in + * this test, we don't need to specially test it. + */ + "setTime", + "getTimezoneOffset", "setMilliseconds", "setUTCMilliseconds", + "setSeconds", "setUTCSeconds", "setMinutes", "setUTCMinutes", + "setHours", "setUTCHours", "setDate", "setUTCDate", "setMonth", + "setUTCMonth", "setFullYear", "setUTCFullYear", "toUTCString", + "toISOString", "toJSON"], + RegExp: ["exec", "test", "toString"], + Error: ["toString"], + }; + +var badThisValues = [null, undefined]; + +function testMethod(Class, className, method) +{ + var expr; + + // Try out explicit this values + for (var i = 0, sz = badThisValues.length; i < sz; i++) + { + var badThis = badThisValues[i]; + + expr = className + ".prototype." + method + ".call(" + badThis + ")"; + try + { + Class.prototype[method].call(badThis); + throw new Error(expr + " didn't throw a TypeError"); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "wrong error for " + expr + ", instead threw " + e); + } + + expr = className + ".prototype." + method + ".apply(" + badThis + ")"; + try + { + Class.prototype[method].apply(badThis); + throw new Error(expr + " didn't throw a TypeError"); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "wrong error for " + expr + ", instead threw " + e); + } + } + + // ..and for good measure.. + + expr = "(0, " + className + ".prototype." + method + ")()" + try + { + // comma operator to call GetValue() on the method and de-Reference it + (0, Class.prototype[method])(); + throw new Error(expr + " didn't throw a TypeError"); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "wrong error for " + expr + ", instead threw " + e); + } +} + +for (var className in ClassToMethodMap) +{ + var Class = this[className]; + + var methodNames = ClassToMethodMap[className]; + for (var i = 0, sz = methodNames.length; i < sz; i++) + { + var method = methodNames[i]; + testMethod(Class, className, method); + } +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/misc/enumerate-undefined.js b/js/src/tests/ecma_5/misc/enumerate-undefined.js new file mode 100644 index 000000000..17bc1c4c8 --- /dev/null +++ b/js/src/tests/ecma_5/misc/enumerate-undefined.js @@ -0,0 +1,24 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 547087; +var summary = 'JS_EnumerateStandardClasses uses wrong attributes for undefined'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +for (var p in this); + +assertEq(Object.getOwnPropertyDescriptor(this, "undefined").writable, false); + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/misc/error-undefined-message.js b/js/src/tests/ecma_5/misc/error-undefined-message.js new file mode 100644 index 000000000..8a9202b8f --- /dev/null +++ b/js/src/tests/ecma_5/misc/error-undefined-message.js @@ -0,0 +1,7 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +assertEq(new Error().hasOwnProperty('message'), false); +assertEq(new Error(undefined).hasOwnProperty('message'), false); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/ecma_5/misc/explicit-undefined-optional-argument.js b/js/src/tests/ecma_5/misc/explicit-undefined-optional-argument.js new file mode 100644 index 000000000..f861ccfdb --- /dev/null +++ b/js/src/tests/ecma_5/misc/explicit-undefined-optional-argument.js @@ -0,0 +1,34 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var BUGNUMBER = 373118; +var summary = + 'Properly handle explicitly-undefined optional arguments to a bunch of ' + + 'functions'; + +print(BUGNUMBER + ": " + summary); + +//----------------------------------------------------------------------------- + +var a; + +a = "abc".slice(0, undefined); +assertEq(a, "abc"); + +a = "abc".substr(0, undefined); +assertEq(a, "abc"); + +a = "abc".substring(0, undefined); +assertEq(a, "abc"); + +a = [1, 2, 3].slice(0, undefined); +assertEq(a.join(), '1,2,3'); + +a = [1, 2, 3].sort(undefined); +assertEq(a.join(), '1,2,3'); + +assertEq((20).toString(undefined), '20'); + +//----------------------------------------------------------------------------- + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/misc/function-definition-eval.js b/js/src/tests/ecma_5/misc/function-definition-eval.js new file mode 100644 index 000000000..27feae1a6 --- /dev/null +++ b/js/src/tests/ecma_5/misc/function-definition-eval.js @@ -0,0 +1,348 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 577325; +var summary = 'Implement the ES5 algorithm for processing function statements'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var outer, desc; +var isInShell = !("Window" in this); + +/////////////////////////////////////////////////// +// Function definitions over accessor properties // +/////////////////////////////////////////////////// + +var getCalled, setCalled; + +// configurable properties get blown away + +getCalled = false, setCalled = false; +Object.defineProperty(this, "acc1", + { + get: function() { getCalled = true; throw "FAIL get 1"; }, + set: function(v) { setCalled = true; throw "FAIL set 1 " + v; }, + configurable: true, + enumerable: false + }); + +// does not throw +outer = undefined; +eval("function acc1() { throw 'FAIL redefined 1'; } outer = acc1;"); +assertEq(getCalled, false); +assertEq(setCalled, false); +assertEq(typeof acc1, "function"); +assertEq(acc1, outer); +desc = Object.getOwnPropertyDescriptor(this, "acc1"); +assertEq(desc.value, acc1); +assertEq(desc.writable, true); +assertEq(desc.enumerable, true); +assertEq(desc.configurable, true); + + +getCalled = false, setCalled = false; +Object.defineProperty(this, "acc2", + { + get: function() { getCalled = true; throw "FAIL get 2"; }, + set: function(v) { setCalled = true; throw "FAIL set 2 " + v; }, + configurable: true, + enumerable: true + }); + +// does not throw +outer = undefined; +eval("function acc2() { throw 'FAIL redefined 2'; } outer = acc2;"); +assertEq(getCalled, false); +assertEq(setCalled, false); +assertEq(typeof acc2, "function"); +assertEq(acc2, outer); +desc = Object.getOwnPropertyDescriptor(this, "acc2"); +assertEq(desc.value, acc2); +assertEq(desc.writable, true); +assertEq(desc.enumerable, true); +assertEq(desc.configurable, true); + + +// non-configurable properties produce a TypeError. We only test this in shell, +// since defining non-configurable properties on Window instances throws. +if (isInShell) { + getCalled = false, setCalled = false; + Object.defineProperty(this, "acc3", + { + get: function() { getCalled = true; throw "FAIL get 3"; }, + set: function(v) { setCalled = true; throw "FAIL set 3 " + v; }, + configurable: false, + enumerable: true + }); + + outer = undefined; + try + { + eval("function acc3() { throw 'FAIL redefined 3'; }; outer = acc3"); + throw new Error("should have thrown trying to redefine global function " + + "over a non-configurable, enumerable accessor"); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "global function definition, when that function would overwrite " + + "a non-configurable, enumerable accessor, must throw a TypeError " + + "per ES5+errata: " + e); + desc = Object.getOwnPropertyDescriptor(this, "acc3"); + assertEq(typeof desc.get, "function"); + assertEq(typeof desc.set, "function"); + assertEq(desc.enumerable, true); + assertEq(desc.configurable, false); + assertEq(outer, undefined); + assertEq(getCalled, false); + assertEq(setCalled, false); + } + + + getCalled = false, setCalled = false; + Object.defineProperty(this, "acc4", + { + get: function() { getCalled = true; throw "FAIL get 4"; }, + set: function(v) { setCalled = true; throw "FAIL set 4 " + v; }, + configurable: false, + enumerable: false + }); + + outer = undefined; + try + { + eval("function acc4() { throw 'FAIL redefined 4'; }; outer = acc4"); + throw new Error("should have thrown trying to redefine global function " + + "over a non-configurable, non-enumerable accessor"); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "global function definition, when that function would overwrite " + + "a non-configurable, non-enumerable accessor, must throw a " + + "TypeError per ES5+errata: " + e); + desc = Object.getOwnPropertyDescriptor(this, "acc4"); + assertEq(typeof desc.get, "function"); + assertEq(typeof desc.set, "function"); + assertEq(desc.enumerable, false); + assertEq(desc.configurable, false); + assertEq(outer, undefined); + assertEq(getCalled, false); + assertEq(setCalled, false); + } +} + + +/////////////////////////////////////////////// +// Function definitions over data properties // +/////////////////////////////////////////////// + + +// configurable properties, regardless of other attributes, get blown away + +Object.defineProperty(this, "data1", + { + configurable: true, + enumerable: true, + writable: true, + value: "data1" + }); + +outer = undefined; +eval("function data1() { return 'data1 function'; } outer = data1;"); +assertEq(typeof data1, "function"); +assertEq(data1, outer); +desc = Object.getOwnPropertyDescriptor(this, "data1"); +assertEq(desc.configurable, true); +assertEq(desc.enumerable, true); +assertEq(desc.writable, true); +assertEq(desc.value, data1); + + +Object.defineProperty(this, "data2", + { + configurable: true, + enumerable: true, + writable: false, + value: "data2" + }); + +outer = undefined; +eval("function data2() { return 'data2 function'; } outer = data2;"); +assertEq(typeof data2, "function"); +assertEq(data2, outer); +desc = Object.getOwnPropertyDescriptor(this, "data2"); +assertEq(desc.configurable, true); +assertEq(desc.enumerable, true); +assertEq(desc.writable, true); +assertEq(desc.value, data2); + + +Object.defineProperty(this, "data3", + { + configurable: true, + enumerable: false, + writable: true, + value: "data3" + }); + +outer = undefined; +eval("function data3() { return 'data3 function'; } outer = data3;"); +assertEq(typeof data3, "function"); +assertEq(data3, outer); +desc = Object.getOwnPropertyDescriptor(this, "data3"); +assertEq(desc.configurable, true); +assertEq(desc.enumerable, true); +assertEq(desc.writable, true); +assertEq(desc.value, data3); + + +Object.defineProperty(this, "data4", + { + configurable: true, + enumerable: false, + writable: false, + value: "data4" + }); + +outer = undefined; +eval("function data4() { return 'data4 function'; } outer = data4;"); +assertEq(typeof data4, "function"); +assertEq(data4, outer); +desc = Object.getOwnPropertyDescriptor(this, "data4"); +assertEq(desc.value, data4); +assertEq(desc.writable, true); +assertEq(desc.enumerable, true); +assertEq(desc.configurable, true); + + +// non-configurable data properties are trickier. Again, we test these only in shell. + +if (isInShell) { + Object.defineProperty(this, "data5", + { + configurable: false, + enumerable: true, + writable: true, + value: "data5" + }); + + outer = undefined; + eval("function data5() { return 'data5 function'; } outer = data5;"); + assertEq(typeof data5, "function"); + assertEq(data5, outer); + desc = Object.getOwnPropertyDescriptor(this, "data5"); + assertEq(desc.configurable, false); + assertEq(desc.enumerable, true); + assertEq(desc.writable, true); + assertEq(desc.value, data5); + + + Object.defineProperty(this, "data6", + { + configurable: false, + enumerable: true, + writable: false, + value: "data6" + }); + + outer = undefined; + try + { + eval("function data6() { return 'data6 function'; } outer = data6;"); + throw new Error("should have thrown trying to redefine global function " + + "over a non-configurable, enumerable, non-writable accessor"); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "global function definition, when that function would overwrite " + + "a non-configurable, enumerable, non-writable data property, must " + + "throw a TypeError per ES5+errata: " + e); + assertEq(data6, "data6"); + assertEq(outer, undefined); + desc = Object.getOwnPropertyDescriptor(this, "data6"); + assertEq(desc.configurable, false); + assertEq(desc.enumerable, true); + assertEq(desc.writable, false); + assertEq(desc.value, "data6"); + } + + + Object.defineProperty(this, "data7", + { + configurable: false, + enumerable: false, + writable: true, + value: "data7" + }); + + outer = undefined; + try + { + eval("function data7() { return 'data7 function'; } outer = data7;"); + throw new Error("should have thrown trying to redefine global function " + + "over a non-configurable, non-enumerable, writable data" + + "property"); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "global function definition, when that function would overwrite " + + "a non-configurable, non-enumerable, writable data property, must " + + "throw a TypeError per ES5+errata: " + e); + assertEq(data7, "data7"); + assertEq(outer, undefined); + desc = Object.getOwnPropertyDescriptor(this, "data7"); + assertEq(desc.configurable, false); + assertEq(desc.enumerable, false); + assertEq(desc.writable, true); + assertEq(desc.value, "data7"); + } + + + Object.defineProperty(this, "data8", + { + configurable: false, + enumerable: false, + writable: false, + value: "data8" + }); + + outer = undefined; + try + { + eval("function data8() { return 'data8 function'; } outer = data8;"); + throw new Error("should have thrown trying to redefine global function " + + "over a non-configurable, non-enumerable, non-writable data" + + "property"); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "global function definition, when that function would overwrite " + + "a non-configurable, non-enumerable, non-writable data property, " + + "must throw a TypeError per ES5+errata: " + e); + assertEq(data8, "data8"); + assertEq(outer, undefined); + desc = Object.getOwnPropertyDescriptor(this, "data8"); + assertEq(desc.configurable, false); + assertEq(desc.enumerable, false); + assertEq(desc.writable, false); + assertEq(desc.value, "data8"); + } +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/misc/function-definition-evaluate.js b/js/src/tests/ecma_5/misc/function-definition-evaluate.js new file mode 100644 index 000000000..4ed156b2a --- /dev/null +++ b/js/src/tests/ecma_5/misc/function-definition-evaluate.js @@ -0,0 +1,344 @@ +// |reftest| skip-if(!xulRuntime.shell) -- needs evaluate() +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 577325; +var summary = 'Implement the ES5 algorithm for processing function statements'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var outer, desc; + +/////////////////////////////////////////////////// +// Function definitions over accessor properties // +/////////////////////////////////////////////////// + +var getCalled, setCalled; + +// configurable properties get blown away + +getCalled = false, setCalled = false; +Object.defineProperty(this, "acc1", + { + get: function() { getCalled = true; throw "FAIL get 1"; }, + set: function(v) { setCalled = true; throw "FAIL set 1 " + v; }, + configurable: true, + enumerable: false + }); + +// does not throw +outer = undefined; +evaluate("function acc1() { throw 'FAIL redefined 1'; } outer = acc1;"); +assertEq(getCalled, false); +assertEq(setCalled, false); +assertEq(typeof acc1, "function"); +assertEq(acc1, outer); +desc = Object.getOwnPropertyDescriptor(this, "acc1"); +assertEq(desc.value, acc1); +assertEq(desc.writable, true); +assertEq(desc.enumerable, true); +assertEq(desc.configurable, false); + + +getCalled = false, setCalled = false; +Object.defineProperty(this, "acc2", + { + get: function() { getCalled = true; throw "FAIL get 2"; }, + set: function(v) { setCalled = true; throw "FAIL set 2 " + v; }, + configurable: true, + enumerable: true + }); + +// does not throw +outer = undefined; +evaluate("function acc2() { throw 'FAIL redefined 2'; } outer = acc2;"); +assertEq(getCalled, false); +assertEq(setCalled, false); +assertEq(typeof acc2, "function"); +assertEq(acc2, outer); +desc = Object.getOwnPropertyDescriptor(this, "acc2"); +assertEq(desc.value, acc2); +assertEq(desc.writable, true); +assertEq(desc.enumerable, true); +assertEq(desc.configurable, false); + + +// non-configurable properties produce a TypeError + +getCalled = false, setCalled = false; +Object.defineProperty(this, "acc3", + { + get: function() { getCalled = true; throw "FAIL get 3"; }, + set: function(v) { setCalled = true; throw "FAIL set 3 " + v; }, + configurable: false, + enumerable: true + }); + +outer = undefined; +try +{ + evaluate("function acc3() { throw 'FAIL redefined 3'; }; outer = acc3"); + throw new Error("should have thrown trying to redefine global function " + + "over a non-configurable, enumerable accessor"); +} +catch (e) +{ + assertEq(e instanceof TypeError, true, + "global function definition, when that function would overwrite " + + "a non-configurable, enumerable accessor, must throw a TypeError " + + "per ES5+errata: " + e); + desc = Object.getOwnPropertyDescriptor(this, "acc3"); + assertEq(typeof desc.get, "function"); + assertEq(typeof desc.set, "function"); + assertEq(desc.enumerable, true); + assertEq(desc.configurable, false); + assertEq(outer, undefined); + assertEq(getCalled, false); + assertEq(setCalled, false); +} + + +getCalled = false, setCalled = false; +Object.defineProperty(this, "acc4", + { + get: function() { getCalled = true; throw "FAIL get 4"; }, + set: function(v) { setCalled = true; throw "FAIL set 4 " + v; }, + configurable: false, + enumerable: false + }); + +outer = undefined; +try +{ + evaluate("function acc4() { throw 'FAIL redefined 4'; }; outer = acc4"); + throw new Error("should have thrown trying to redefine global function " + + "over a non-configurable, non-enumerable accessor"); +} +catch (e) +{ + assertEq(e instanceof TypeError, true, + "global function definition, when that function would overwrite " + + "a non-configurable, non-enumerable accessor, must throw a " + + "TypeError per ES5+errata: " + e); + desc = Object.getOwnPropertyDescriptor(this, "acc4"); + assertEq(typeof desc.get, "function"); + assertEq(typeof desc.set, "function"); + assertEq(desc.enumerable, false); + assertEq(desc.configurable, false); + assertEq(outer, undefined); + assertEq(getCalled, false); + assertEq(setCalled, false); +} + + +/////////////////////////////////////////////// +// Function definitions over data properties // +/////////////////////////////////////////////// + + +// configurable properties, regardless of other attributes, get blown away + +Object.defineProperty(this, "data1", + { + configurable: true, + enumerable: true, + writable: true, + value: "data1" + }); + +outer = undefined; +evaluate("function data1() { return 'data1 function'; } outer = data1;"); +assertEq(typeof data1, "function"); +assertEq(data1, outer); +desc = Object.getOwnPropertyDescriptor(this, "data1"); +assertEq(desc.configurable, false); +assertEq(desc.enumerable, true); +assertEq(desc.writable, true); +assertEq(desc.value, data1); + + +Object.defineProperty(this, "data2", + { + configurable: true, + enumerable: true, + writable: false, + value: "data2" + }); + +outer = undefined; +evaluate("function data2() { return 'data2 function'; } outer = data2;"); +assertEq(typeof data2, "function"); +assertEq(data2, outer); +desc = Object.getOwnPropertyDescriptor(this, "data2"); +assertEq(desc.configurable, false); +assertEq(desc.enumerable, true); +assertEq(desc.writable, true); +assertEq(desc.value, data2); + + +Object.defineProperty(this, "data3", + { + configurable: true, + enumerable: false, + writable: true, + value: "data3" + }); + +outer = undefined; +evaluate("function data3() { return 'data3 function'; } outer = data3;"); +assertEq(typeof data3, "function"); +assertEq(data3, outer); +desc = Object.getOwnPropertyDescriptor(this, "data3"); +assertEq(desc.configurable, false); +assertEq(desc.enumerable, true); +assertEq(desc.writable, true); +assertEq(desc.value, data3); + + +Object.defineProperty(this, "data4", + { + configurable: true, + enumerable: false, + writable: false, + value: "data4" + }); + +outer = undefined; +evaluate("function data4() { return 'data4 function'; } outer = data4;"); +assertEq(typeof data4, "function"); +assertEq(data4, outer); +desc = Object.getOwnPropertyDescriptor(this, "data4"); +assertEq(desc.value, data4); +assertEq(desc.writable, true); +assertEq(desc.enumerable, true); +assertEq(desc.configurable, false); + + +// non-configurable data properties are trickier + +Object.defineProperty(this, "data5", + { + configurable: false, + enumerable: true, + writable: true, + value: "data5" + }); + +outer = undefined; +evaluate("function data5() { return 'data5 function'; } outer = data5;"); +assertEq(typeof data5, "function"); +assertEq(data5, outer); +desc = Object.getOwnPropertyDescriptor(this, "data5"); +assertEq(desc.configurable, false); +assertEq(desc.enumerable, true); +assertEq(desc.writable, true); +assertEq(desc.value, data5); + + +Object.defineProperty(this, "data6", + { + configurable: false, + enumerable: true, + writable: false, + value: "data6" + }); + +outer = undefined; +try +{ + evaluate("function data6() { return 'data6 function'; } outer = data6;"); + throw new Error("should have thrown trying to redefine global function " + + "over a non-configurable, enumerable, non-writable accessor"); +} +catch (e) +{ + assertEq(e instanceof TypeError, true, + "global function definition, when that function would overwrite " + + "a non-configurable, enumerable, non-writable data property, must " + + "throw a TypeError per ES5+errata: " + e); + assertEq(data6, "data6"); + assertEq(outer, undefined); + desc = Object.getOwnPropertyDescriptor(this, "data6"); + assertEq(desc.configurable, false); + assertEq(desc.enumerable, true); + assertEq(desc.writable, false); + assertEq(desc.value, "data6"); +} + + +Object.defineProperty(this, "data7", + { + configurable: false, + enumerable: false, + writable: true, + value: "data7" + }); + +outer = undefined; +try +{ + evaluate("function data7() { return 'data7 function'; } outer = data7;"); + throw new Error("should have thrown trying to redefine global function " + + "over a non-configurable, non-enumerable, writable data" + + "property"); +} +catch (e) +{ + assertEq(e instanceof TypeError, true, + "global function definition, when that function would overwrite " + + "a non-configurable, non-enumerable, writable data property, must " + + "throw a TypeError per ES5+errata: " + e); + assertEq(data7, "data7"); + assertEq(outer, undefined); + desc = Object.getOwnPropertyDescriptor(this, "data7"); + assertEq(desc.configurable, false); + assertEq(desc.enumerable, false); + assertEq(desc.writable, true); + assertEq(desc.value, "data7"); +} + + +Object.defineProperty(this, "data8", + { + configurable: false, + enumerable: false, + writable: false, + value: "data8" + }); + +outer = undefined; +try +{ + evaluate("function data8() { return 'data8 function'; } outer = data8;"); + throw new Error("should have thrown trying to redefine global function " + + "over a non-configurable, non-enumerable, non-writable data" + + "property"); +} +catch (e) +{ + assertEq(e instanceof TypeError, true, + "global function definition, when that function would overwrite " + + "a non-configurable, non-enumerable, non-writable data property, " + + "must throw a TypeError per ES5+errata: " + e); + assertEq(data8, "data8"); + assertEq(outer, undefined); + desc = Object.getOwnPropertyDescriptor(this, "data8"); + assertEq(desc.configurable, false); + assertEq(desc.enumerable, false); + assertEq(desc.writable, false); + assertEq(desc.value, "data8"); +} + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/misc/future-reserved-words.js b/js/src/tests/ecma_5/misc/future-reserved-words.js new file mode 100644 index 000000000..0fa2e3221 --- /dev/null +++ b/js/src/tests/ecma_5/misc/future-reserved-words.js @@ -0,0 +1,463 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 497869; +var summary = "Implement FutureReservedWords per-spec"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var futureReservedWords = + [ + "class", + // "const", // Mozilla extension enabled even for versionless code + "enum", + "export", + "extends", + "import", + "super", + ]; + +var strictFutureReservedWords = + [ + "implements", + "interface", + "let", // enabled: this file doesn't execute as JS1.7 + "package", + "private", + "protected", + "public", + "static", + "yield", // enabled: this file doesn't execute as JS1.7 + ]; + +function testWord(word, expectNormal, expectStrict) +{ + var actual, status; + + // USE AS LHS FOR ASSIGNMENT + + actual = ""; + status = summary + ": " + word + ": normal assignment"; + try + { + eval(word + " = 'foo';"); + actual = "no error"; + } + catch(e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectNormal, status); + + actual = ""; + status = summary + ": " + word + ": strict assignment"; + try + { + eval("'use strict'; " + word + " = 'foo';"); + actual = "no error"; + } + catch(e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); + + // USE IN VARIABLE DECLARATION + + actual = ""; + status = summary + ": " + word + ": normal var"; + try + { + eval("var " + word + ";"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectNormal, status); + + actual = ""; + status = summary + ": " + word + ": strict var"; + try + { + eval("'use strict'; var " + word + ";"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); + + // USE IN FOR-IN VARIABLE DECLARATION + + actual = ""; + status = summary + ": " + word + ": normal for-in var"; + try + { + eval("for (var " + word + " in {});"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectNormal, status); + + actual = ""; + status = summary + ": " + word + ": strict for-in var"; + try + { + eval("'use strict'; for (var " + word + " in {});"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); + + // USE AS CATCH IDENTIFIER + + actual = ""; + status = summary + ": " + word + ": normal var"; + try + { + eval("try { } catch (" + word + ") { }"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectNormal, status); + + actual = ""; + status = summary + ": " + word + ": strict var"; + try + { + eval("'use strict'; try { } catch (" + word + ") { }"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); + + // USE AS LABEL + + actual = ""; + status = summary + ": " + word + ": normal label"; + try + { + eval(word + ": while (false);"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectNormal, status); + + actual = ""; + status = summary + ": " + word + ": strict label"; + try + { + eval("'use strict'; " + word + ": while (false);"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); + + // USE AS ARGUMENT NAME IN FUNCTION DECLARATION + + actual = ""; + status = summary + ": " + word + ": normal function argument"; + try + { + eval("function foo(" + word + ") { }"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectNormal, status); + + actual = ""; + status = summary + ": " + word + ": strict function argument"; + try + { + eval("'use strict'; function foo(" + word + ") { }"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); + + actual = ""; + status = summary + ": " + word + ": function argument retroactively strict"; + try + { + eval("function foo(" + word + ") { 'use strict'; }"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); + + // USE AS ARGUMENT NAME IN FUNCTION EXPRESSION + + actual = ""; + status = summary + ": " + word + ": normal function expression argument"; + try + { + eval("var s = (function foo(" + word + ") { });"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectNormal, status); + + actual = ""; + status = summary + ": " + word + ": strict function expression argument"; + try + { + eval("'use strict'; var s = (function foo(" + word + ") { });"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); + + actual = ""; + status = summary + ": " + word + ": function expression argument retroactively strict"; + try + { + eval("var s = (function foo(" + word + ") { 'use strict'; });"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); + + // USE AS ARGUMENT NAME WITH FUNCTION CONSTRUCTOR + + actual = ""; + status = summary + ": " + word + ": argument with normal Function"; + try + { + Function(word, "return 17"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectNormal, status); + + actual = ""; + status = summary + ": " + word + ": argument with strict Function"; + try + { + Function(word, "'use strict'; return 17"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); + + // USE AS ARGUMENT NAME IN PROPERTY SETTER + + actual = ""; + status = summary + ": " + word + ": normal property setter argument"; + try + { + eval("var o = { set x(" + word + ") { } };"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectNormal, status); + + actual = ""; + status = summary + ": " + word + ": strict property setter argument"; + try + { + eval("'use strict'; var o = { set x(" + word + ") { } };"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); + + actual = ""; + status = summary + ": " + word + ": property setter argument retroactively strict"; + try + { + eval("var o = { set x(" + word + ") { 'use strict'; } };"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); + + // USE AS FUNCTION NAME IN FUNCTION DECLARATION + + actual = ""; + status = summary + ": " + word + ": normal function name"; + try + { + eval("function " + word + "() { }"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectNormal, status); + + actual = ""; + status = summary + ": " + word + ": strict function name"; + try + { + eval("'use strict'; function " + word + "() { }"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); + + actual = ""; + status = summary + ": " + word + ": function name retroactively strict"; + try + { + eval("function " + word + "() { 'use strict'; }"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); + + // USE AS FUNCTION NAME IN FUNCTION EXPRESSION + + actual = ""; + status = summary + ": " + word + ": normal function expression name"; + try + { + eval("var s = (function " + word + "() { });"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectNormal, status); + + actual = ""; + status = summary + ": " + word + ": strict function expression name"; + try + { + eval("'use strict'; var s = (function " + word + "() { });"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); + + actual = ""; + status = summary + ": " + word + ": function expression name retroactively strict"; + try + { + eval("var s = (function " + word + "() { 'use strict'; });"); + actual = "no error"; + } + catch (e) + { + actual = e.name; + status += ", " + e.name + ": " + e.message + " "; + } + assertEq(actual, expectStrict, status); +} + +function testFutureReservedWord(word) +{ + testWord(word, "SyntaxError", "SyntaxError"); +} + +function testStrictFutureReservedWord(word) +{ + testWord(word, "no error", "SyntaxError"); +} + +futureReservedWords.forEach(testFutureReservedWord); +strictFutureReservedWords.forEach(testStrictFutureReservedWord); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/misc/getter-setter-outerize-this.js b/js/src/tests/ecma_5/misc/getter-setter-outerize-this.js new file mode 100644 index 000000000..46c61b889 --- /dev/null +++ b/js/src/tests/ecma_5/misc/getter-setter-outerize-this.js @@ -0,0 +1,21 @@ +if (typeof window === "undefined") { + // This test is meant to run in the browser, but it's easy to + // run it in the shell as well, even though it has no inner/outer + // windows. + window = this; +} + +var res = false; +Object.defineProperty(this, "foo", {configurable: true, + get: function() { return this === window; }, + set: function(v) { res = this === window; }}); + +(function() { + for (var i = 0; i < 3000; ++i) { + window.foo = i; + assertEq(res, true, "setter"); + assertEq(window.foo, true, "getter"); + } +})(); + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/misc/global-numeric-properties.js b/js/src/tests/ecma_5/misc/global-numeric-properties.js new file mode 100644 index 000000000..352c0d3b7 --- /dev/null +++ b/js/src/tests/ecma_5/misc/global-numeric-properties.js @@ -0,0 +1,59 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 537863; +var summary = + 'undefined, Infinity, and NaN global properties should not be writable'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var desc, old, error; +var global = this; + +var names = ["NaN", "Infinity", "undefined"]; + +for (var i = 0; i < names.length; i++) +{ + var name = names[i]; + desc = Object.getOwnPropertyDescriptor(global, name); + assertEq(desc !== undefined, true, name + " should be present"); + assertEq(desc.enumerable, false, name + " should not be enumerable"); + assertEq(desc.configurable, false, name + " should not be configurable"); + assertEq(desc.writable, false, name + " should not be writable"); + + old = global[name]; + global[name] = 17; + assertEq(global[name], old, name + " changed on setting?"); + + error = "before"; + try + { + throw new TypeError("SpiderMonkey doesn't currently implement " + + "strict-mode throwing when setting a readonly " + + "property, not running this bit of test for now; " + + "see bug 537873"); + + (function() { "use strict"; global[name] = 42; error = "didn't throw"; })(); + } + catch (e) + { + if (e instanceof TypeError) + error = "typeerror"; + else + error = "bad exception: " + e; + } + assertEq(error, "typeerror", "wrong strict mode error setting " + name); +} + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/misc/line-paragraph-separator-parse-as-lineterminator.js b/js/src/tests/ecma_5/misc/line-paragraph-separator-parse-as-lineterminator.js new file mode 100644 index 000000000..8eef6d658 --- /dev/null +++ b/js/src/tests/ecma_5/misc/line-paragraph-separator-parse-as-lineterminator.js @@ -0,0 +1,51 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 663331; +var summary = + "U+2028 LINE SEPARATOR and U+2029 PARAGRAPH SEPARATOR must match the " + + "LineTerminator production when parsing code"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var hidden = 17; +var assigned; + +assigned = 42; +assertEq(eval('"use strict"; var hidden\u2028assigned = 5; typeof hidden'), + "undefined"); +assertEq(assigned, 5); + +assigned = 42; +function t1() +{ + assertEq(eval('var hidden\u2028assigned = 5; typeof hidden'), "undefined"); + assertEq(assigned, 5); +} +t1(); + +assigned = 42; +assertEq(eval('"use strict"; var hidden\u2029assigned = 5; typeof hidden'), + "undefined"); +assertEq(assigned, 5); + +assigned = 42; +function t2() +{ + assertEq(eval('var hidden\u2029assigned = 5; typeof hidden'), "undefined"); + assertEq(assigned, 5); +} +t2(); + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/misc/new-with-non-constructor.js b/js/src/tests/ecma_5/misc/new-with-non-constructor.js new file mode 100644 index 000000000..edec0e31d --- /dev/null +++ b/js/src/tests/ecma_5/misc/new-with-non-constructor.js @@ -0,0 +1,32 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function checkConstruct(thing) { + try { + new thing(); + assertEq(0, 1, "not reached " + thing); + } catch (e) { + assertEq(e.message.includes(" is not a constructor") || + e.message === "Function.prototype.toString called on incompatible object", true); + } +} + +var re = /aaa/ +checkConstruct(re); + +var boundFunctionPrototype = Function.prototype.bind(); +checkConstruct(boundFunctionPrototype); + +var boundBuiltin = Math.sin.bind(); +checkConstruct(boundBuiltin); + +var proxiedFunctionPrototype = new Proxy(Function.prototype, {}); +checkConstruct(proxiedFunctionPrototype); + +var proxiedBuiltin = new Proxy(parseInt, {}); +checkConstruct(proxiedBuiltin); + +if (typeof reportCompare == 'function') + reportCompare(0, 0, "ok"); diff --git a/js/src/tests/ecma_5/misc/redeclare-var-non-writable-property.js b/js/src/tests/ecma_5/misc/redeclare-var-non-writable-property.js new file mode 100644 index 000000000..f21289d85 --- /dev/null +++ b/js/src/tests/ecma_5/misc/redeclare-var-non-writable-property.js @@ -0,0 +1,24 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 539488; +var summary = + '|var| statements for existing, read-only/permanent properties should not ' + + 'be errors'; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var undefined; + +/******************************************************************************/ + +reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/misc/regexp-functions-with-undefined.js b/js/src/tests/ecma_5/misc/regexp-functions-with-undefined.js new file mode 100644 index 000000000..e55b2acd0 --- /dev/null +++ b/js/src/tests/ecma_5/misc/regexp-functions-with-undefined.js @@ -0,0 +1,43 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var a = /undefined/.exec(); +assertEq(a[0], 'undefined'); +assertEq(a.length, 1); + +a = /undefined/.exec(undefined); +assertEq(a[0], 'undefined'); +assertEq(a.length, 1); + +assertEq(/undefined/.test(), true); +assertEq(/undefined/.test(undefined), true); + +assertEq(/aaaa/.exec(), null); +assertEq(/aaaa/.exec(undefined), null); + +assertEq(/aaaa/.test(), false); +assertEq(/aaaa/.test(undefined), false); + + +assertEq("undefined".search(), 0); +assertEq("undefined".search(undefined), 0); +assertEq("aaaa".search(), 0); +assertEq("aaaa".search(undefined), 0); + +a = "undefined".match(); +assertEq(a[0], ""); +assertEq(a.length, 1); +a = "undefined".match(undefined); +assertEq(a[0], ""); +assertEq(a.length, 1); +a = "aaaa".match(); +assertEq(a[0], ""); +assertEq(a.length, 1); +a = "aaaa".match(undefined); +assertEq(a[0], ""); +assertEq(a.length, 1); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_5/misc/regress-bug632003.js b/js/src/tests/ecma_5/misc/regress-bug632003.js new file mode 100644 index 000000000..c299f6dc4 --- /dev/null +++ b/js/src/tests/ecma_5/misc/regress-bug632003.js @@ -0,0 +1,63 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * Contributor: + */ +var BUGNUMBER = 632003; +var summary = 'The var statement should add the property to the global if it exists on the prototype'; + +// Define properties on Object.prototype with various attributes and +// value-getter-setter combinations then check that a var statement +// can always define a variable with the same name in the global object. + +if (typeof evaluate != "undefined") { + var global_case = def_all("global_case"); + evaluate(global_case.source); + check_values(this, global_case.var_list); +} + +var eval_case = def_all("eval_case"); +eval(eval_case.source); +check_values(this, eval_case.var_list); + +function def_all(prefix) +{ + var builder, index, i, j; + + builder = {source: "", var_list: []}; + index = 0; + for (i = 0; i <= 1; ++i) { + for (j = 0; j <= 1; ++j) { + def({value: index}); + def({value: index, writable: true}); + def({get: Function("return "+index+";")}); + def({set: function() { }}); + def({get: Function("return "+index+";"), set: function() { }}); + } + } + return builder; + + function def(descriptor_seed) + { + var var_name = prefix + index; + descriptor_seed.configurable = !!i; + descriptor_seed.enumerable = !!j; + Object.defineProperty(Object.prototype, var_name, descriptor_seed); + var var_value = index + 0.5; + builder.source += "var "+var_name+" = "+var_value+";\n"; + builder.var_list.push({name: var_name, expected_value: var_value}); + ++index; + } +} + +function check_values(obj, var_list) +{ + for (i = 0; i != var_list.length; ++i) { + var name = var_list[i].name; + assertEq(obj.hasOwnProperty(name), true); + assertEq(obj[name], var_list[i].expected_value); + } +} + +reportCompare(true, true); diff --git a/js/src/tests/ecma_5/misc/shell.js b/js/src/tests/ecma_5/misc/shell.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/js/src/tests/ecma_5/misc/shell.js diff --git a/js/src/tests/ecma_5/misc/syntax-error-end-of-for-head-part.js b/js/src/tests/ecma_5/misc/syntax-error-end-of-for-head-part.js new file mode 100644 index 000000000..f715b3e17 --- /dev/null +++ b/js/src/tests/ecma_5/misc/syntax-error-end-of-for-head-part.js @@ -0,0 +1,51 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 672854; +var summary = + "Syntax errors at the end of |for| statement header parts shouldn't cause " + + "crashes"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function checkSyntaxError(str) +{ + try + { + var f = Function("for(w in\\"); + throw new Error("didn't throw, returned " + f); + } + catch (e) + { + assertEq(e instanceof SyntaxError, true, + "expected SyntaxError, got " + e); + } +} + +checkSyntaxError("for(var w in \\"); +checkSyntaxError("for(w in \\"); +checkSyntaxError("for(var w\\"); +checkSyntaxError("for(w\\"); +checkSyntaxError("for(var w;\\"); +checkSyntaxError("for(w;\\"); +checkSyntaxError("for(var w; w >\\"); +checkSyntaxError("for(w; w >\\"); +checkSyntaxError("for(var w; w > 3;\\"); +checkSyntaxError("for(w; w > 3;\\"); +checkSyntaxError("for(var w; w > 3; 5\\"); +checkSyntaxError("for(w; w > 3; 5\\"); +checkSyntaxError("for(var w; w > 3; 5foo"); +checkSyntaxError("for(w; w > 3; 5foo"); + +/******************************************************************************/ + +reportCompare(true, true); + +print("Tests complete!"); diff --git a/js/src/tests/ecma_5/misc/unicode-escaped-keyword.js b/js/src/tests/ecma_5/misc/unicode-escaped-keyword.js new file mode 100644 index 000000000..e17df168c --- /dev/null +++ b/js/src/tests/ecma_5/misc/unicode-escaped-keyword.js @@ -0,0 +1,22 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +function throws(code) { + var type; + try { + eval(code); + } catch (ex) { + type = ex.name; + } + assertEq(type, 'SyntaxError'); +} + +var s = '\\u0073'; +throws('var thi' + s); +throws('switch (' + s + 'witch) {}') +throws('var ' + s + 'witch'); + +if (typeof reportCompare == 'function') + reportCompare(true, true); diff --git a/js/src/tests/ecma_5/misc/unicode-identifier-1d17.js b/js/src/tests/ecma_5/misc/unicode-identifier-1d17.js new file mode 100644 index 000000000..ae763fdf2 --- /dev/null +++ b/js/src/tests/ecma_5/misc/unicode-identifier-1d17.js @@ -0,0 +1,16 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var o = {} +try { + eval('o.\\u1d17 = 42;'); +} +catch (e) { + assertEq('should not fail', true); +} +assertEq(o['\u1d17'], 42); + +if (typeof reportCompare == 'function') + reportCompare(true, true); diff --git a/js/src/tests/ecma_5/misc/unicode-identifier-82f1.js b/js/src/tests/ecma_5/misc/unicode-identifier-82f1.js new file mode 100644 index 000000000..313832cc3 --- /dev/null +++ b/js/src/tests/ecma_5/misc/unicode-identifier-82f1.js @@ -0,0 +1,16 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var o = {} +try { + eval('o.\\u82f1 = 42;'); +} +catch (e) { + assertEq('should not fail', true); +} +assertEq(o['\u82f1'], 42); + +if (typeof reportCompare == 'function') + reportCompare(true, true); diff --git a/js/src/tests/ecma_5/misc/unnamed-function.js b/js/src/tests/ecma_5/misc/unnamed-function.js new file mode 100644 index 000000000..d004149c0 --- /dev/null +++ b/js/src/tests/ecma_5/misc/unnamed-function.js @@ -0,0 +1,45 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 376052; +var summary = 'Unnamed function expressions are forbidden in statement context'; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + try + { + eval('(function () {1;})'); + reportCompare(true, true, + "unnamed function expression not in statement context works"); + } + catch(ex) + { + reportCompare(true, false, "threw exception: " + ex); + } + + try + { + eval('function () {1;}'); + reportCompare(true, false, "didn't throw an exception"); + } + catch(ex) + { + reportCompare(ex instanceof SyntaxError, true, + "unnamed function expression not in statement context " + + "should have been a SyntaxError"); + } + + exitFunc ('test'); +} diff --git a/js/src/tests/ecma_5/misc/unwrapped-no-such-method.js b/js/src/tests/ecma_5/misc/unwrapped-no-such-method.js new file mode 100644 index 000000000..d17406e7b --- /dev/null +++ b/js/src/tests/ecma_5/misc/unwrapped-no-such-method.js @@ -0,0 +1,13 @@ +// Our __noSuchMethod__ handling should only be called when |this| is an object. + +var x = ""; +// Reached from interpreter's JSOP_CALLPROP, and js::mjit::ic::CallProp. +try { x.i(); } catch (ex) { } + +// Reached from interpreter's JSOP_CALLELEM, and js::mjit::stubs::CallElem. +try { x[x](); } catch (ex) { } + +// Reached from js::mjit::stubs::CallProp: +try { true.i(); } catch(ex) { } + +reportCompare(true,true); |