summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/lexical-environment/redeclaring-global-properties.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/non262/lexical-environment/redeclaring-global-properties.js')
-rw-r--r--js/src/tests/non262/lexical-environment/redeclaring-global-properties.js64
1 files changed, 64 insertions, 0 deletions
diff --git a/js/src/tests/non262/lexical-environment/redeclaring-global-properties.js b/js/src/tests/non262/lexical-environment/redeclaring-global-properties.js
new file mode 100644
index 0000000000..7fb2f82db1
--- /dev/null
+++ b/js/src/tests/non262/lexical-environment/redeclaring-global-properties.js
@@ -0,0 +1,64 @@
+// |reftest| skip-if(!xulRuntime.shell) -- needs evaluate
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+// Attempting to lexically redefine a var is a syntax error.
+evaluate("var a;");
+assertThrowsInstanceOf(() => evaluate("let a;"), SyntaxError);
+
+// Attempting to lexically redefine a configurable global property that's not a
+// var is okay.
+this.b = 42;
+assertEq(b, 42);
+evaluate("let b = 17;");
+assertEq(b, 17);
+
+// Attempting to lexically redefine a configurable global property that wasn't
+// a var initially but was later declared as one, isn't okay.
+this.c = 8675309;
+assertEq(c, 8675309);
+evaluate("var c;");
+assertThrowsInstanceOf(() => evaluate("let c;"), SyntaxError);
+
+// Attempting to lexically redefine a var added by eval code isn't okay.
+assertEq(typeof d, "undefined");
+eval("var d = 33;");
+assertEq(d, 33);
+assertThrowsInstanceOf(() => evaluate("let d;"), SyntaxError);
+
+// Attempting to lexically redefine a var added by eval code, then deleted *as a
+// name*, is okay. (The |var| will add the name to the global environment
+// record's [[VarNames]], but deletion will go through the global environment
+// record's DeleteBinding and so will remove it.)
+assertEq(typeof e, "undefined");
+eval("var e = 'ohia';");
+assertEq(e, "ohia");
+delete e;
+assertEq(this.hasOwnProperty("e"), false);
+evaluate("let e = 3.141592654;");
+assertEq(e, 3.141592654);
+
+// Attempting to lexically redefine a var added by eval code, then deleted *as a
+// property*, isn't okay. (Deletion by property doesn't go through the global
+// environment record's DeleteBinding algorithm, and so the name isn't removed
+// from [[VarNames]].) And it remains non-okay even if the var is subsequently
+// deleted as a name, because if the property doesn't exist, it's not removed
+// from [[VarNames]]. But if we add the global property again and then delete
+// by name, it *will* get removed from [[VarNames]].
+assertEq(typeof f, "undefined");
+eval("var f = 8675309;");
+assertEq(f, 8675309);
+delete this.f;
+assertEq(this.hasOwnProperty("f"), false);
+assertThrowsInstanceOf(() => evaluate("let f;"), SyntaxError);
+delete f;
+assertThrowsInstanceOf(() => evaluate("let f;"), SyntaxError);
+this.f = 999;
+assertThrowsInstanceOf(() => evaluate("let f;"), SyntaxError);
+delete f;
+evaluate("let f;");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
+
+print("Tests complete");