summaryrefslogtreecommitdiffstats
path: root/js/src/tests/ecma_5/misc/function-definition-eval.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/ecma_5/misc/function-definition-eval.js')
-rw-r--r--js/src/tests/ecma_5/misc/function-definition-eval.js348
1 files changed, 348 insertions, 0 deletions
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!");