summaryrefslogtreecommitdiffstats
path: root/test/mjsunit/strict-mode.js
diff options
context:
space:
mode:
Diffstat (limited to 'test/mjsunit/strict-mode.js')
-rw-r--r--test/mjsunit/strict-mode.js178
1 files changed, 178 insertions, 0 deletions
diff --git a/test/mjsunit/strict-mode.js b/test/mjsunit/strict-mode.js
index 69be19c2..84ccb30f 100644
--- a/test/mjsunit/strict-mode.js
+++ b/test/mjsunit/strict-mode.js
@@ -957,3 +957,181 @@ repeat(10, function() { testAssignToUndefined(false); });
assertThrows(function() { str_obj.length = 1; }, TypeError);
assertThrows(function() { str_cat.length = 1; }, TypeError);
})();
+
+
+(function TestArgumentsAliasing() {
+ function strict(a, b) {
+ "use strict";
+ a = "c";
+ b = "d";
+ return [a, b, arguments[0], arguments[1]];
+ }
+
+ function nonstrict(a, b) {
+ a = "c";
+ b = "d";
+ return [a, b, arguments[0], arguments[1]];
+ }
+
+ assertEquals(["c", "d", "a", "b"], strict("a", "b"));
+ assertEquals(["c", "d", "c", "d"], nonstrict("a", "b"));
+})();
+
+
+function CheckPillDescriptor(func, name) {
+
+ function CheckPill(pill) {
+ assertEquals("function", typeof pill);
+ assertInstanceof(pill, Function);
+ pill.property = "value";
+ assertEquals(pill.value, undefined);
+ assertThrows(function() { 'use strict'; pill.property = "value"; },
+ TypeError);
+ assertThrows(pill, TypeError);
+ assertEquals(pill.prototype, (function(){}).prototype);
+ var d = Object.getOwnPropertyDescriptor(pill, "prototype");
+ assertFalse(d.writable);
+ assertFalse(d.configurable);
+ assertFalse(d.enumerable);
+ }
+
+ var descriptor = Object.getOwnPropertyDescriptor(func, name);
+ CheckPill(descriptor.get)
+ CheckPill(descriptor.set);
+ assertFalse(descriptor.enumerable);
+ assertFalse(descriptor.configurable);
+}
+
+
+(function TestStrictFunctionPills() {
+ function strict() {
+ "use strict";
+ }
+ assertThrows(function() { strict.caller; }, TypeError);
+ assertThrows(function() { strict.arguments; }, TypeError);
+
+ var another = new Function("'use strict'");
+ assertThrows(function() { another.caller; }, TypeError);
+ assertThrows(function() { another.arguments; }, TypeError);
+
+ var third = (function() { "use strict"; return function() {}; })();
+ assertThrows(function() { third.caller; }, TypeError);
+ assertThrows(function() { third.arguments; }, TypeError);
+
+ CheckPillDescriptor(strict, "caller");
+ CheckPillDescriptor(strict, "arguments");
+ CheckPillDescriptor(another, "caller");
+ CheckPillDescriptor(another, "arguments");
+ CheckPillDescriptor(third, "caller");
+ CheckPillDescriptor(third, "arguments");
+})();
+
+
+(function TestStrictFunctionWritablePrototype() {
+ "use strict";
+ function TheClass() {
+ }
+ assertThrows(function() { TheClass.caller; }, TypeError);
+ assertThrows(function() { TheClass.arguments; }, TypeError);
+
+ // Strict functions must have writable prototype.
+ TheClass.prototype = {
+ func: function() { return "func_value"; },
+ get accessor() { return "accessor_value"; },
+ property: "property_value",
+ };
+
+ var o = new TheClass();
+ assertEquals(o.func(), "func_value");
+ assertEquals(o.accessor, "accessor_value");
+ assertEquals(o.property, "property_value");
+})();
+
+
+(function TestStrictArgumentPills() {
+ function strict() {
+ "use strict";
+ return arguments;
+ }
+
+ var args = strict();
+ CheckPillDescriptor(args, "caller");
+ CheckPillDescriptor(args, "callee");
+
+ args = strict(17, "value", strict);
+ assertEquals(17, args[0])
+ assertEquals("value", args[1])
+ assertEquals(strict, args[2]);
+ CheckPillDescriptor(args, "caller");
+ CheckPillDescriptor(args, "callee");
+
+ function outer() {
+ "use strict";
+ function inner() {
+ return arguments;
+ }
+ return inner;
+ }
+
+ var args = outer()();
+ CheckPillDescriptor(args, "caller");
+ CheckPillDescriptor(args, "callee");
+
+ args = outer()(17, "value", strict);
+ assertEquals(17, args[0])
+ assertEquals("value", args[1])
+ assertEquals(strict, args[2]);
+ CheckPillDescriptor(args, "caller");
+ CheckPillDescriptor(args, "callee");
+})();
+
+
+(function TestNonStrictFunctionCallerPillSimple() {
+ function return_my_caller() {
+ return return_my_caller.caller;
+ }
+
+ function strict() {
+ "use strict";
+ return_my_caller();
+ }
+ assertThrows(strict, TypeError);
+
+ function non_strict() {
+ return return_my_caller();
+ }
+ assertSame(non_strict(), non_strict);
+})();
+
+
+(function TestNonStrictFunctionCallerPill() {
+ function strict(n) {
+ "use strict";
+ non_strict(n);
+ }
+
+ function recurse(n, then) {
+ if (n > 0) {
+ recurse(n - 1);
+ } else {
+ return then();
+ }
+ }
+
+ function non_strict(n) {
+ recurse(n, function() { non_strict.caller; });
+ }
+
+ function test(n) {
+ try {
+ recurse(n, function() { strict(n); });
+ } catch(e) {
+ return e instanceof TypeError;
+ }
+ return false;
+ }
+
+ for (var i = 0; i < 10; i ++) {
+ assertEquals(test(i), true);
+ }
+})();