blob: beca582a02ad3637dc356968ea5915fbf512ab9e [file] [log] [blame]
Steve Block1e0659c2011-05-24 12:43:12 +01001// Copyright 2011 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28function CheckStrictMode(code, exception) {
29 assertDoesNotThrow(code);
30 assertThrows("'use strict';\n" + code, exception);
31 assertThrows('"use strict";\n' + code, exception);
32 assertDoesNotThrow("\
33 function outer() {\
34 function inner() {\n"
35 + code +
36 "\n}\
37 }");
38 assertThrows("\
39 function outer() {\
40 'use strict';\
41 function inner() {\n"
42 + code +
43 "\n}\
44 }", exception);
45}
46
47function CheckFunctionConstructorStrictMode() {
48 var args = [];
49 for (var i = 0; i < arguments.length; i ++) {
50 args[i] = arguments[i];
51 }
52 // Create non-strict function. No exception.
53 args[arguments.length] = "";
54 assertDoesNotThrow(function() {
55 Function.apply(this, args);
56 });
57 // Create strict mode function. Exception expected.
58 args[arguments.length] = "'use strict';";
59 assertThrows(function() {
60 Function.apply(this, args);
61 }, SyntaxError);
62}
63
64// Incorrect 'use strict' directive.
65(function UseStrictEscape() {
66 "use\\x20strict";
67 with ({}) {};
68})();
69
70// 'use strict' in non-directive position.
71(function UseStrictNonDirective() {
72 void(0);
73 "use strict";
74 with ({}) {};
75})();
76
77// Multiple directives, including "use strict".
78assertThrows('\
79"directive 1";\
80"another directive";\
81"use strict";\
82"directive after strict";\
83"and one more";\
84with({}) {}', SyntaxError);
85
86// 'with' disallowed in strict mode.
87CheckStrictMode("with({}) {}", SyntaxError);
88
89// Function named 'eval'.
90CheckStrictMode("function eval() {}", SyntaxError);
91
92// Function named 'arguments'.
93CheckStrictMode("function arguments() {}", SyntaxError);
94
95// Function parameter named 'eval'.
96CheckStrictMode("function foo(a, b, eval, c, d) {}", SyntaxError);
97
98// Function parameter named 'arguments'.
99CheckStrictMode("function foo(a, b, arguments, c, d) {}", SyntaxError);
100
101// Property accessor parameter named 'eval'.
102CheckStrictMode("var o = { set foo(eval) {} }", SyntaxError);
103
104// Property accessor parameter named 'arguments'.
105CheckStrictMode("var o = { set foo(arguments) {} }", SyntaxError);
106
107// Duplicate function parameter name.
108CheckStrictMode("function foo(a, b, c, d, b) {}", SyntaxError);
109
110// Function constructor: eval parameter name.
111CheckFunctionConstructorStrictMode("eval");
112
113// Function constructor: arguments parameter name.
114CheckFunctionConstructorStrictMode("arguments");
115
116// Function constructor: duplicate parameter name.
117CheckFunctionConstructorStrictMode("a", "b", "c", "b");
118CheckFunctionConstructorStrictMode("a,b,c,b");
119
120// catch(eval)
121CheckStrictMode("try{}catch(eval){};", SyntaxError);
122
123// catch(arguments)
124CheckStrictMode("try{}catch(arguments){};", SyntaxError);
125
126// var eval
127CheckStrictMode("var eval;", SyntaxError);
128
129// var arguments
130CheckStrictMode("var arguments;", SyntaxError);
131
132// Strict mode applies to the function in which the directive is used..
133assertThrows('\
134function foo(eval) {\
135 "use strict";\
136}', SyntaxError);
137
138// Strict mode doesn't affect the outer stop of strict code.
139(function NotStrict(eval) {
140 function Strict() {
141 "use strict";
142 }
143 with ({}) {};
144})();
145
146// Octal literal
147CheckStrictMode("var x = 012");
148CheckStrictMode("012");
149CheckStrictMode("'Hello octal\\032'");
150CheckStrictMode("function octal() { return 012; }");
151CheckStrictMode("function octal() { return '\\032'; }");
152
153(function ValidEscape() {
154 "use strict";
155 var x = '\0';
156 var y = "\0";
157})();
158
159// Octal before "use strict"
160assertThrows('\
161 function strict() {\
162 "octal\\032directive";\
163 "use strict";\
164 }', SyntaxError);
165
166// Duplicate data properties.
167CheckStrictMode("var x = { dupe : 1, nondupe: 3, dupe : 2 };", SyntaxError);
168CheckStrictMode("var x = { '1234' : 1, '2345' : 2, '1234' : 3 };", SyntaxError);
169CheckStrictMode("var x = { '1234' : 1, '2345' : 2, 1234 : 3 };", SyntaxError);
170CheckStrictMode("var x = { 3.14 : 1, 2.71 : 2, 3.14 : 3 };", SyntaxError);
171CheckStrictMode("var x = { 3.14 : 1, '3.14' : 2 };", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100172CheckStrictMode("var x = { \
173 123: 1, \
174 123.00000000000000000000000000000000000000000000000000000000000000000001: 2 \
175}", SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100176
177// Non-conflicting data properties.
178(function StrictModeNonDuplicate() {
179 "use strict";
180 var x = { 123 : 1, "0123" : 2 };
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100181 var x = {
182 123: 1,
183 '123.00000000000000000000000000000000000000000000000000000000000000000001':
184 2
185 };
Steve Block1e0659c2011-05-24 12:43:12 +0100186})();
187
188// Two getters (non-strict)
189assertThrows("var x = { get foo() { }, get foo() { } };", SyntaxError);
190assertThrows("var x = { get foo(){}, get 'foo'(){}};", SyntaxError);
191assertThrows("var x = { get 12(){}, get '12'(){}};", SyntaxError);
192
193// Two setters (non-strict)
194assertThrows("var x = { set foo(v) { }, set foo(v) { } };", SyntaxError);
195assertThrows("var x = { set foo(v) { }, set 'foo'(v) { } };", SyntaxError);
196assertThrows("var x = { set 13(v) { }, set '13'(v) { } };", SyntaxError);
197
198// Setter and data (non-strict)
199assertThrows("var x = { foo: 'data', set foo(v) { } };", SyntaxError);
200assertThrows("var x = { set foo(v) { }, foo: 'data' };", SyntaxError);
201assertThrows("var x = { foo: 'data', set 'foo'(v) { } };", SyntaxError);
202assertThrows("var x = { set foo(v) { }, 'foo': 'data' };", SyntaxError);
203assertThrows("var x = { 'foo': 'data', set foo(v) { } };", SyntaxError);
204assertThrows("var x = { set 'foo'(v) { }, foo: 'data' };", SyntaxError);
205assertThrows("var x = { 'foo': 'data', set 'foo'(v) { } };", SyntaxError);
206assertThrows("var x = { set 'foo'(v) { }, 'foo': 'data' };", SyntaxError);
207assertThrows("var x = { 12: 1, set '12'(v){}};", SyntaxError);
208assertThrows("var x = { 12: 1, set 12(v){}};", SyntaxError);
209assertThrows("var x = { '12': 1, set '12'(v){}};", SyntaxError);
210assertThrows("var x = { '12': 1, set 12(v){}};", SyntaxError);
211
212// Getter and data (non-strict)
213assertThrows("var x = { foo: 'data', get foo() { } };", SyntaxError);
214assertThrows("var x = { get foo() { }, foo: 'data' };", SyntaxError);
215assertThrows("var x = { 'foo': 'data', get foo() { } };", SyntaxError);
216assertThrows("var x = { get 'foo'() { }, 'foo': 'data' };", SyntaxError);
217assertThrows("var x = { '12': 1, get '12'(){}};", SyntaxError);
218assertThrows("var x = { '12': 1, get 12(){}};", SyntaxError);
219
220// Assignment to eval or arguments
221CheckStrictMode("function strict() { eval = undefined; }", SyntaxError);
222CheckStrictMode("function strict() { arguments = undefined; }", SyntaxError);
223CheckStrictMode("function strict() { print(eval = undefined); }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100224CheckStrictMode("function strict() { print(arguments = undefined); }",
225 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100226CheckStrictMode("function strict() { var x = eval = undefined; }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100227CheckStrictMode("function strict() { var x = arguments = undefined; }",
228 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100229
230// Compound assignment to eval or arguments
231CheckStrictMode("function strict() { eval *= undefined; }", SyntaxError);
232CheckStrictMode("function strict() { arguments /= undefined; }", SyntaxError);
233CheckStrictMode("function strict() { print(eval %= undefined); }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100234CheckStrictMode("function strict() { print(arguments %= undefined); }",
235 SyntaxError);
236CheckStrictMode("function strict() { var x = eval += undefined; }",
237 SyntaxError);
238CheckStrictMode("function strict() { var x = arguments -= undefined; }",
239 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100240CheckStrictMode("function strict() { eval <<= undefined; }", SyntaxError);
241CheckStrictMode("function strict() { arguments >>= undefined; }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100242CheckStrictMode("function strict() { print(eval >>>= undefined); }",
243 SyntaxError);
244CheckStrictMode("function strict() { print(arguments &= undefined); }",
245 SyntaxError);
246CheckStrictMode("function strict() { var x = eval ^= undefined; }",
247 SyntaxError);
248CheckStrictMode("function strict() { var x = arguments |= undefined; }",
249 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100250
251// Postfix increment with eval or arguments
252CheckStrictMode("function strict() { eval++; }", SyntaxError);
253CheckStrictMode("function strict() { arguments++; }", SyntaxError);
254CheckStrictMode("function strict() { print(eval++); }", SyntaxError);
255CheckStrictMode("function strict() { print(arguments++); }", SyntaxError);
256CheckStrictMode("function strict() { var x = eval++; }", SyntaxError);
257CheckStrictMode("function strict() { var x = arguments++; }", SyntaxError);
258
259// Postfix decrement with eval or arguments
260CheckStrictMode("function strict() { eval--; }", SyntaxError);
261CheckStrictMode("function strict() { arguments--; }", SyntaxError);
262CheckStrictMode("function strict() { print(eval--); }", SyntaxError);
263CheckStrictMode("function strict() { print(arguments--); }", SyntaxError);
264CheckStrictMode("function strict() { var x = eval--; }", SyntaxError);
265CheckStrictMode("function strict() { var x = arguments--; }", SyntaxError);
266
267// Prefix increment with eval or arguments
268CheckStrictMode("function strict() { ++eval; }", SyntaxError);
269CheckStrictMode("function strict() { ++arguments; }", SyntaxError);
270CheckStrictMode("function strict() { print(++eval); }", SyntaxError);
271CheckStrictMode("function strict() { print(++arguments); }", SyntaxError);
272CheckStrictMode("function strict() { var x = ++eval; }", SyntaxError);
273CheckStrictMode("function strict() { var x = ++arguments; }", SyntaxError);
274
275// Prefix decrement with eval or arguments
276CheckStrictMode("function strict() { --eval; }", SyntaxError);
277CheckStrictMode("function strict() { --arguments; }", SyntaxError);
278CheckStrictMode("function strict() { print(--eval); }", SyntaxError);
279CheckStrictMode("function strict() { print(--arguments); }", SyntaxError);
280CheckStrictMode("function strict() { var x = --eval; }", SyntaxError);
281CheckStrictMode("function strict() { var x = --arguments; }", SyntaxError);
282
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100283// Use of const in strict mode is disallowed in anticipation of ES Harmony.
284CheckStrictMode("const x = 0;", SyntaxError);
285CheckStrictMode("for (const x = 0; false;) {}", SyntaxError);
286CheckStrictMode("function strict() { const x = 0; }", SyntaxError);
287
288// Strict mode only allows functions in SourceElements
289CheckStrictMode("if (true) { function invalid() {} }", SyntaxError);
290CheckStrictMode("for (;false;) { function invalid() {} }", SyntaxError);
291CheckStrictMode("{ function invalid() {} }", SyntaxError);
292CheckStrictMode("try { function invalid() {} } catch(e) {}", SyntaxError);
293CheckStrictMode("try { } catch(e) { function invalid() {} }", SyntaxError);
294CheckStrictMode("function outer() {{ function invalid() {} }}", SyntaxError);
295
296// Delete of an unqualified identifier
297CheckStrictMode("delete unqualified;", SyntaxError);
298CheckStrictMode("function strict() { delete unqualified; }", SyntaxError);
299CheckStrictMode("function function_name() { delete function_name; }",
300 SyntaxError);
301CheckStrictMode("function strict(parameter) { delete parameter; }",
302 SyntaxError);
303CheckStrictMode("function strict() { var variable; delete variable; }",
304 SyntaxError);
305CheckStrictMode("var variable; delete variable;", SyntaxError);
306
307(function TestStrictDelete() {
308 "use strict";
309 // "delete this" is allowed in strict mode and should work.
310 function strict_delete() { delete this; }
311 strict_delete();
312})();
313
Steve Block1e0659c2011-05-24 12:43:12 +0100314// Prefix unary operators other than delete, ++, -- are valid in strict mode
315(function StrictModeUnaryOperators() {
316 "use strict";
317 var x = [void eval, typeof eval, +eval, -eval, ~eval, !eval];
318 var y = [void arguments, typeof arguments,
319 +arguments, -arguments, ~arguments, !arguments];
320})();
321
322// 7.6.1.2 Future Reserved Words
323var future_reserved_words = [
324 "class",
325 "enum",
326 "export",
327 "extends",
328 "import",
329 "super",
330 "implements",
331 "interface",
332 "let",
333 "package",
334 "private",
335 "protected",
336 "public",
337 "static",
338 "yield" ];
339
340function testFutureReservedWord(word) {
341 // Simple use of each reserved word
342 CheckStrictMode("var " + word + " = 1;", SyntaxError);
343
344 // object literal properties
345 eval("var x = { " + word + " : 42 };");
346 eval("var x = { get " + word + " () {} };");
347 eval("var x = { set " + word + " (value) {} };");
348
349 // object literal with string literal property names
350 eval("var x = { '" + word + "' : 42 };");
351 eval("var x = { get '" + word + "' () { } };");
352 eval("var x = { set '" + word + "' (value) { } };");
353 eval("var x = { get '" + word + "' () { 'use strict'; } };");
354 eval("var x = { set '" + word + "' (value) { 'use strict'; } };");
355
356 // Function names and arguments, strict and non-strict contexts
357 CheckStrictMode("function " + word + " () {}", SyntaxError);
358 CheckStrictMode("function foo (" + word + ") {}", SyntaxError);
359 CheckStrictMode("function foo (" + word + ", " + word + ") {}", SyntaxError);
360 CheckStrictMode("function foo (a, " + word + ") {}", SyntaxError);
361 CheckStrictMode("function foo (" + word + ", a) {}", SyntaxError);
362 CheckStrictMode("function foo (a, " + word + ", b) {}", SyntaxError);
363 CheckStrictMode("var foo = function (" + word + ") {}", SyntaxError);
364
365 // Function names and arguments when the body is strict
366 assertThrows("function " + word + " () { 'use strict'; }", SyntaxError);
367 assertThrows("function foo (" + word + ") 'use strict'; {}", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100368 assertThrows("function foo (" + word + ", " + word + ") { 'use strict'; }",
369 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100370 assertThrows("function foo (a, " + word + ") { 'use strict'; }", SyntaxError);
371 assertThrows("function foo (" + word + ", a) { 'use strict'; }", SyntaxError);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100372 assertThrows("function foo (a, " + word + ", b) { 'use strict'; }",
373 SyntaxError);
374 assertThrows("var foo = function (" + word + ") { 'use strict'; }",
375 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100376
377 // get/set when the body is strict
378 eval("var x = { get " + word + " () { 'use strict'; } };");
379 eval("var x = { set " + word + " (value) { 'use strict'; } };");
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100380 assertThrows("var x = { get foo(" + word + ") { 'use strict'; } };",
381 SyntaxError);
382 assertThrows("var x = { set foo(" + word + ") { 'use strict'; } };",
383 SyntaxError);
Steve Block1e0659c2011-05-24 12:43:12 +0100384}
385
386for (var i = 0; i < future_reserved_words.length; i++) {
387 testFutureReservedWord(future_reserved_words[i]);
388}
389
Ben Murdoch8b112d22011-06-08 16:22:53 +0100390function testAssignToUndefined(test, should_throw) {
Steve Block1e0659c2011-05-24 12:43:12 +0100391 try {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100392 test();
Steve Block1e0659c2011-05-24 12:43:12 +0100393 } catch (e) {
394 assertTrue(should_throw, "strict mode");
395 assertInstanceof(e, ReferenceError, "strict mode");
396 return;
397 }
398 assertFalse(should_throw, "strict mode");
399}
400
Steve Block1e0659c2011-05-24 12:43:12 +0100401function repeat(n, f) {
Ben Murdoch8b112d22011-06-08 16:22:53 +0100402 for (var i = 0; i < n; i ++) { f(); }
Steve Block1e0659c2011-05-24 12:43:12 +0100403}
404
Ben Murdoch8b112d22011-06-08 16:22:53 +0100405function assignToUndefined() {
406 "use strict";
407 possibly_undefined_variable_for_strict_mode_test = "should throw?";
408}
409
410testAssignToUndefined(assignToUndefined, true);
411testAssignToUndefined(assignToUndefined, true);
412testAssignToUndefined(assignToUndefined, true);
413
Steve Block1e0659c2011-05-24 12:43:12 +0100414possibly_undefined_variable_for_strict_mode_test = "value";
Ben Murdoch8b112d22011-06-08 16:22:53 +0100415
416testAssignToUndefined(assignToUndefined, false);
417testAssignToUndefined(assignToUndefined, false);
418testAssignToUndefined(assignToUndefined, false);
419
Steve Block1e0659c2011-05-24 12:43:12 +0100420delete possibly_undefined_variable_for_strict_mode_test;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100421
422testAssignToUndefined(assignToUndefined, true);
423testAssignToUndefined(assignToUndefined, true);
424testAssignToUndefined(assignToUndefined, true);
425
426repeat(10, function() { testAssignToUndefined(assignToUndefined, true); });
427possibly_undefined_variable_for_strict_mode_test = "value";
428repeat(10, function() { testAssignToUndefined(assignToUndefined, false); });
429delete possibly_undefined_variable_for_strict_mode_test;
430repeat(10, function() { testAssignToUndefined(assignToUndefined, true); });
Steve Block1e0659c2011-05-24 12:43:12 +0100431possibly_undefined_variable_for_strict_mode_test = undefined;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100432repeat(10, function() { testAssignToUndefined(assignToUndefined, false); });
433
434function assignToUndefinedWithEval() {
435 "use strict";
436 possibly_undefined_variable_for_strict_mode_test_with_eval = "should throw?";
437 eval("");
438}
439
440testAssignToUndefined(assignToUndefinedWithEval, true);
441testAssignToUndefined(assignToUndefinedWithEval, true);
442testAssignToUndefined(assignToUndefinedWithEval, true);
443
444possibly_undefined_variable_for_strict_mode_test_with_eval = "value";
445
446testAssignToUndefined(assignToUndefinedWithEval, false);
447testAssignToUndefined(assignToUndefinedWithEval, false);
448testAssignToUndefined(assignToUndefinedWithEval, false);
449
450delete possibly_undefined_variable_for_strict_mode_test_with_eval;
451
452testAssignToUndefined(assignToUndefinedWithEval, true);
453testAssignToUndefined(assignToUndefinedWithEval, true);
454testAssignToUndefined(assignToUndefinedWithEval, true);
455
456repeat(10, function() {
457 testAssignToUndefined(assignToUndefinedWithEval, true);
458 });
459possibly_undefined_variable_for_strict_mode_test_with_eval = "value";
460repeat(10, function() {
461 testAssignToUndefined(assignToUndefinedWithEval, false);
462 });
463delete possibly_undefined_variable_for_strict_mode_test_with_eval;
464repeat(10, function() {
465 testAssignToUndefined(assignToUndefinedWithEval, true);
466 });
467possibly_undefined_variable_for_strict_mode_test_with_eval = undefined;
468repeat(10, function() {
469 testAssignToUndefined(assignToUndefinedWithEval, false);
470 });
471
472
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100473
474(function testDeleteNonConfigurable() {
475 function delete_property(o) {
476 "use strict";
477 delete o.property;
478 }
479 function delete_element(o, i) {
480 "use strict";
481 delete o[i];
482 }
483
484 var object = {};
485
486 Object.defineProperty(object, "property", { value: "property_value" });
487 Object.defineProperty(object, "1", { value: "one" });
488 Object.defineProperty(object, 7, { value: "seven" });
489 Object.defineProperty(object, 3.14, { value: "pi" });
490
491 assertThrows(function() { delete_property(object); }, TypeError);
492 assertEquals(object.property, "property_value");
493 assertThrows(function() { delete_element(object, "1"); }, TypeError);
494 assertThrows(function() { delete_element(object, 1); }, TypeError);
495 assertEquals(object[1], "one");
496 assertThrows(function() { delete_element(object, "7"); }, TypeError);
497 assertThrows(function() { delete_element(object, 7); }, TypeError);
498 assertEquals(object[7], "seven");
499 assertThrows(function() { delete_element(object, "3.14"); }, TypeError);
500 assertThrows(function() { delete_element(object, 3.14); }, TypeError);
501 assertEquals(object[3.14], "pi");
502})();
503
504// Not transforming this in Function.call and Function.apply.
505(function testThisTransformCallApply() {
506 function non_strict() {
507 return this;
508 }
509 function strict() {
510 "use strict";
511 return this;
512 }
513
514 var global_object = (function() { return this; })();
515 var object = {};
516
517 // Non-strict call.
518 assertTrue(non_strict.call(null) === global_object);
519 assertTrue(non_strict.call(undefined) === global_object);
520 assertEquals(typeof non_strict.call(7), "object");
521 assertEquals(typeof non_strict.call("Hello"), "object");
522 assertTrue(non_strict.call(object) === object);
523
524 // Non-strict apply.
525 assertTrue(non_strict.apply(null) === global_object);
526 assertTrue(non_strict.apply(undefined) === global_object);
527 assertEquals(typeof non_strict.apply(7), "object");
528 assertEquals(typeof non_strict.apply("Hello"), "object");
529 assertTrue(non_strict.apply(object) === object);
530
531 // Strict call.
532 assertTrue(strict.call(null) === null);
533 assertTrue(strict.call(undefined) === undefined);
534 assertEquals(typeof strict.call(7), "number");
535 assertEquals(typeof strict.call("Hello"), "string");
536 assertTrue(strict.call(object) === object);
537
538 // Strict apply.
539 assertTrue(strict.apply(null) === null);
540 assertTrue(strict.apply(undefined) === undefined);
541 assertEquals(typeof strict.apply(7), "number");
542 assertEquals(typeof strict.apply("Hello"), "string");
543 assertTrue(strict.apply(object) === object);
544})();
545
546(function testThisTransform() {
547 try {
548 function strict() {
549 "use strict";
550 return typeof(this);
551 }
552 function nonstrict() {
553 return typeof(this);
554 }
555
556 // Concat to avoid symbol.
557 var strict_name = "str" + "ict";
558 var nonstrict_name = "non" + "str" + "ict";
559 var strict_number = 17;
560 var nonstrict_number = 19;
561 var strict_name_get = "str" + "ict" + "get";
562 var nonstrict_name_get = "non" + "str" + "ict" + "get"
563 var strict_number_get = 23;
564 var nonstrict_number_get = 29;
565
566 function install(t) {
567 t.prototype.strict = strict;
568 t.prototype.nonstrict = nonstrict;
569 t.prototype[strict_number] = strict;
570 t.prototype[nonstrict_number] = nonstrict;
571 Object.defineProperty(t.prototype, strict_name_get,
572 { get: function() { return strict; },
573 configurable: true });
574 Object.defineProperty(t.prototype, nonstrict_name_get,
575 { get: function() { return nonstrict; },
576 configurable: true });
577 Object.defineProperty(t.prototype, strict_number_get,
578 { get: function() { return strict; },
579 configurable: true });
580 Object.defineProperty(t.prototype, nonstrict_number_get,
581 { get: function() { return nonstrict; },
582 configurable: true });
583 }
584
585 function cleanup(t) {
586 delete t.prototype.strict;
587 delete t.prototype.nonstrict;
588 delete t.prototype[strict_number];
589 delete t.prototype[nonstrict_number];
590 delete t.prototype[strict_name_get];
591 delete t.prototype[nonstrict_name_get];
592 delete t.prototype[strict_number_get];
593 delete t.prototype[nonstrict_number_get];
594 }
595
596 // Set up fakes
597 install(String);
598 install(Number);
599 install(Boolean)
600
601 function callStrict(o) {
602 return o.strict();
603 }
604 function callNonStrict(o) {
605 return o.nonstrict();
606 }
607 function callKeyedStrict(o) {
608 return o[strict_name]();
609 }
610 function callKeyedNonStrict(o) {
611 return o[nonstrict_name]();
612 }
613 function callIndexedStrict(o) {
614 return o[strict_number]();
615 }
616 function callIndexedNonStrict(o) {
617 return o[nonstrict_number]();
618 }
619 function callStrictGet(o) {
620 return o.strictget();
621 }
622 function callNonStrictGet(o) {
623 return o.nonstrictget();
624 }
625 function callKeyedStrictGet(o) {
626 return o[strict_name_get]();
627 }
628 function callKeyedNonStrictGet(o) {
629 return o[nonstrict_name_get]();
630 }
631 function callIndexedStrictGet(o) {
632 return o[strict_number_get]();
633 }
634 function callIndexedNonStrictGet(o) {
635 return o[nonstrict_number_get]();
636 }
637
638 for (var i = 0; i < 10; i ++) {
639 assertEquals(("hello").strict(), "string");
640 assertEquals(("hello").nonstrict(), "object");
641 assertEquals(("hello")[strict_name](), "string");
642 assertEquals(("hello")[nonstrict_name](), "object");
643 assertEquals(("hello")[strict_number](), "string");
644 assertEquals(("hello")[nonstrict_number](), "object");
645
646 assertEquals((10 + i).strict(), "number");
647 assertEquals((10 + i).nonstrict(), "object");
648 assertEquals((10 + i)[strict_name](), "number");
649 assertEquals((10 + i)[nonstrict_name](), "object");
650 assertEquals((10 + i)[strict_number](), "number");
651 assertEquals((10 + i)[nonstrict_number](), "object");
652
653 assertEquals((true).strict(), "boolean");
654 assertEquals((true).nonstrict(), "object");
655 assertEquals((true)[strict_name](), "boolean");
656 assertEquals((true)[nonstrict_name](), "object");
657 assertEquals((true)[strict_number](), "boolean");
658 assertEquals((true)[nonstrict_number](), "object");
659
660 assertEquals((false).strict(), "boolean");
661 assertEquals((false).nonstrict(), "object");
662 assertEquals((false)[strict_name](), "boolean");
663 assertEquals((false)[nonstrict_name](), "object");
664 assertEquals((false)[strict_number](), "boolean");
665 assertEquals((false)[nonstrict_number](), "object");
666
667 assertEquals(callStrict("howdy"), "string");
668 assertEquals(callNonStrict("howdy"), "object");
669 assertEquals(callKeyedStrict("howdy"), "string");
670 assertEquals(callKeyedNonStrict("howdy"), "object");
671 assertEquals(callIndexedStrict("howdy"), "string");
672 assertEquals(callIndexedNonStrict("howdy"), "object");
673
674 assertEquals(callStrict(17 + i), "number");
675 assertEquals(callNonStrict(17 + i), "object");
676 assertEquals(callKeyedStrict(17 + i), "number");
677 assertEquals(callKeyedNonStrict(17 + i), "object");
678 assertEquals(callIndexedStrict(17 + i), "number");
679 assertEquals(callIndexedNonStrict(17 + i), "object");
680
681 assertEquals(callStrict(true), "boolean");
682 assertEquals(callNonStrict(true), "object");
683 assertEquals(callKeyedStrict(true), "boolean");
684 assertEquals(callKeyedNonStrict(true), "object");
685 assertEquals(callIndexedStrict(true), "boolean");
686 assertEquals(callIndexedNonStrict(true), "object");
687
688 assertEquals(callStrict(false), "boolean");
689 assertEquals(callNonStrict(false), "object");
690 assertEquals(callKeyedStrict(false), "boolean");
691 assertEquals(callKeyedNonStrict(false), "object");
692 assertEquals(callIndexedStrict(false), "boolean");
693 assertEquals(callIndexedNonStrict(false), "object");
694
695 // All of the above, with getters
696 assertEquals(("hello").strictget(), "string");
697 assertEquals(("hello").nonstrictget(), "object");
698 assertEquals(("hello")[strict_name_get](), "string");
699 assertEquals(("hello")[nonstrict_name_get](), "object");
700 assertEquals(("hello")[strict_number_get](), "string");
701 assertEquals(("hello")[nonstrict_number_get](), "object");
702
703 assertEquals((10 + i).strictget(), "number");
704 assertEquals((10 + i).nonstrictget(), "object");
705 assertEquals((10 + i)[strict_name_get](), "number");
706 assertEquals((10 + i)[nonstrict_name_get](), "object");
707 assertEquals((10 + i)[strict_number_get](), "number");
708 assertEquals((10 + i)[nonstrict_number_get](), "object");
709
710 assertEquals((true).strictget(), "boolean");
711 assertEquals((true).nonstrictget(), "object");
712 assertEquals((true)[strict_name_get](), "boolean");
713 assertEquals((true)[nonstrict_name_get](), "object");
714 assertEquals((true)[strict_number_get](), "boolean");
715 assertEquals((true)[nonstrict_number_get](), "object");
716
717 assertEquals((false).strictget(), "boolean");
718 assertEquals((false).nonstrictget(), "object");
719 assertEquals((false)[strict_name_get](), "boolean");
720 assertEquals((false)[nonstrict_name_get](), "object");
721 assertEquals((false)[strict_number_get](), "boolean");
722 assertEquals((false)[nonstrict_number_get](), "object");
723
724 assertEquals(callStrictGet("howdy"), "string");
725 assertEquals(callNonStrictGet("howdy"), "object");
726 assertEquals(callKeyedStrictGet("howdy"), "string");
727 assertEquals(callKeyedNonStrictGet("howdy"), "object");
728 assertEquals(callIndexedStrictGet("howdy"), "string");
729 assertEquals(callIndexedNonStrictGet("howdy"), "object");
730
731 assertEquals(callStrictGet(17 + i), "number");
732 assertEquals(callNonStrictGet(17 + i), "object");
733 assertEquals(callKeyedStrictGet(17 + i), "number");
734 assertEquals(callKeyedNonStrictGet(17 + i), "object");
735 assertEquals(callIndexedStrictGet(17 + i), "number");
736 assertEquals(callIndexedNonStrictGet(17 + i), "object");
737
738 assertEquals(callStrictGet(true), "boolean");
739 assertEquals(callNonStrictGet(true), "object");
740 assertEquals(callKeyedStrictGet(true), "boolean");
741 assertEquals(callKeyedNonStrictGet(true), "object");
742 assertEquals(callIndexedStrictGet(true), "boolean");
743 assertEquals(callIndexedNonStrictGet(true), "object");
744
745 assertEquals(callStrictGet(false), "boolean");
746 assertEquals(callNonStrictGet(false), "object");
747 assertEquals(callKeyedStrictGet(false), "boolean");
748 assertEquals(callKeyedNonStrictGet(false), "object");
749 assertEquals(callIndexedStrictGet(false), "boolean");
750 assertEquals(callIndexedNonStrictGet(false), "object");
751
752 }
753 } finally {
754 // Cleanup
755 cleanup(String);
756 cleanup(Number);
757 cleanup(Boolean);
758 }
759})();
760
761
762(function ObjectEnvironment() {
763 var o = {};
764 Object.defineProperty(o, "foo", { value: "FOO", writable: false });
765 assertThrows(
766 function () {
767 with (o) {
768 (function() {
769 "use strict";
770 foo = "Hello";
771 })();
772 }
773 },
774 TypeError);
775})();
776
777
778(function TestSetPropertyWithoutSetter() {
779 var o = { get foo() { return "Yey"; } };
780 assertThrows(
781 function broken() {
782 "use strict";
783 o.foo = (0xBADBAD00 >> 1);
784 },
785 TypeError);
786})();
787
788
789(function TestSetPropertyNonConfigurable() {
790 var frozen = Object.freeze({});
791 var sealed = Object.seal({});
792
793 function strict(o) {
794 "use strict";
795 o.property = "value";
796 }
797
798 assertThrows(function() { strict(frozen); }, TypeError);
799 assertThrows(function() { strict(sealed); }, TypeError);
800})();
801
802
803(function TestAssignmentToReadOnlyProperty() {
804 "use strict";
805
806 var o = {};
807 Object.defineProperty(o, "property", { value: 7 });
808
809 assertThrows(function() { o.property = "new value"; }, TypeError);
810 assertThrows(function() { o.property += 10; }, TypeError);
811 assertThrows(function() { o.property -= 10; }, TypeError);
812 assertThrows(function() { o.property *= 10; }, TypeError);
813 assertThrows(function() { o.property /= 10; }, TypeError);
814 assertThrows(function() { o.property++; }, TypeError);
815 assertThrows(function() { o.property--; }, TypeError);
816 assertThrows(function() { ++o.property; }, TypeError);
817 assertThrows(function() { --o.property; }, TypeError);
818
819 var name = "prop" + "erty"; // to avoid symbol path.
820 assertThrows(function() { o[name] = "new value"; }, TypeError);
821 assertThrows(function() { o[name] += 10; }, TypeError);
822 assertThrows(function() { o[name] -= 10; }, TypeError);
823 assertThrows(function() { o[name] *= 10; }, TypeError);
824 assertThrows(function() { o[name] /= 10; }, TypeError);
825 assertThrows(function() { o[name]++; }, TypeError);
826 assertThrows(function() { o[name]--; }, TypeError);
827 assertThrows(function() { ++o[name]; }, TypeError);
828 assertThrows(function() { --o[name]; }, TypeError);
829
830 assertEquals(o.property, 7);
831})();
832
833
834(function TestAssignmentToReadOnlyLoop() {
835 var name = "prop" + "erty"; // to avoid symbol path.
836 var o = {};
837 Object.defineProperty(o, "property", { value: 7 });
838
839 function strict(o, name) {
840 "use strict";
841 o[name] = "new value";
842 }
843
844 for (var i = 0; i < 10; i ++) {
845 try {
846 strict(o, name);
847 assertUnreachable();
848 } catch(e) {
849 assertInstanceof(e, TypeError);
850 }
851 }
852})();
853
854
855// Specialized KeyedStoreIC experiencing miss.
856(function testKeyedStoreICStrict() {
857 var o = [9,8,7,6,5,4,3,2,1];
858
859 function test(o, i, v) {
860 "use strict";
861 o[i] = v;
862 }
863
864 for (var i = 0; i < 10; i ++) {
865 test(o, 5, 17); // start specialized for smi indices
866 assertEquals(o[5], 17);
867 test(o, "a", 19);
868 assertEquals(o["a"], 19);
869 test(o, "5", 29);
870 assertEquals(o[5], 29);
871 test(o, 100000, 31);
872 assertEquals(o[100000], 31);
873 }
874})();
875
876
877(function TestSetElementWithoutSetter() {
878 "use strict";
879
880 var o = { };
881 Object.defineProperty(o, 0, { get : function() { } });
882
883 var zero_smi = 0;
884 var zero_number = new Number(0);
885 var zero_symbol = "0";
886 var zero_string = "-0-".substring(1,2);
887
888 assertThrows(function() { o[zero_smi] = "new value"; }, TypeError);
889 assertThrows(function() { o[zero_number] = "new value"; }, TypeError);
890 assertThrows(function() { o[zero_symbol] = "new value"; }, TypeError);
891 assertThrows(function() { o[zero_string] = "new value"; }, TypeError);
892})();
893
894
895(function TestSetElementNonConfigurable() {
896 "use strict";
897 var frozen = Object.freeze({});
898 var sealed = Object.seal({});
899
900 var zero_number = 0;
901 var zero_symbol = "0";
902 var zero_string = "-0-".substring(1,2);
903
904 assertThrows(function() { frozen[zero_number] = "value"; }, TypeError);
905 assertThrows(function() { sealed[zero_number] = "value"; }, TypeError);
906 assertThrows(function() { frozen[zero_symbol] = "value"; }, TypeError);
907 assertThrows(function() { sealed[zero_symbol] = "value"; }, TypeError);
908 assertThrows(function() { frozen[zero_string] = "value"; }, TypeError);
909 assertThrows(function() { sealed[zero_string] = "value"; }, TypeError);
910})();
911
912
913(function TestAssignmentToReadOnlyElement() {
914 "use strict";
915
916 var o = {};
917 Object.defineProperty(o, 7, { value: 17 });
918
919 var seven_smi = 7;
920 var seven_number = new Number(7);
921 var seven_symbol = "7";
922 var seven_string = "-7-".substring(1,2);
923
924 // Index with number.
925 assertThrows(function() { o[seven_smi] = "value"; }, TypeError);
926 assertThrows(function() { o[seven_smi] += 10; }, TypeError);
927 assertThrows(function() { o[seven_smi] -= 10; }, TypeError);
928 assertThrows(function() { o[seven_smi] *= 10; }, TypeError);
929 assertThrows(function() { o[seven_smi] /= 10; }, TypeError);
930 assertThrows(function() { o[seven_smi]++; }, TypeError);
931 assertThrows(function() { o[seven_smi]--; }, TypeError);
932 assertThrows(function() { ++o[seven_smi]; }, TypeError);
933 assertThrows(function() { --o[seven_smi]; }, TypeError);
934
935 assertThrows(function() { o[seven_number] = "value"; }, TypeError);
936 assertThrows(function() { o[seven_number] += 10; }, TypeError);
937 assertThrows(function() { o[seven_number] -= 10; }, TypeError);
938 assertThrows(function() { o[seven_number] *= 10; }, TypeError);
939 assertThrows(function() { o[seven_number] /= 10; }, TypeError);
940 assertThrows(function() { o[seven_number]++; }, TypeError);
941 assertThrows(function() { o[seven_number]--; }, TypeError);
942 assertThrows(function() { ++o[seven_number]; }, TypeError);
943 assertThrows(function() { --o[seven_number]; }, TypeError);
944
945 assertThrows(function() { o[seven_symbol] = "value"; }, TypeError);
946 assertThrows(function() { o[seven_symbol] += 10; }, TypeError);
947 assertThrows(function() { o[seven_symbol] -= 10; }, TypeError);
948 assertThrows(function() { o[seven_symbol] *= 10; }, TypeError);
949 assertThrows(function() { o[seven_symbol] /= 10; }, TypeError);
950 assertThrows(function() { o[seven_symbol]++; }, TypeError);
951 assertThrows(function() { o[seven_symbol]--; }, TypeError);
952 assertThrows(function() { ++o[seven_symbol]; }, TypeError);
953 assertThrows(function() { --o[seven_symbol]; }, TypeError);
954
955 assertThrows(function() { o[seven_string] = "value"; }, TypeError);
956 assertThrows(function() { o[seven_string] += 10; }, TypeError);
957 assertThrows(function() { o[seven_string] -= 10; }, TypeError);
958 assertThrows(function() { o[seven_string] *= 10; }, TypeError);
959 assertThrows(function() { o[seven_string] /= 10; }, TypeError);
960 assertThrows(function() { o[seven_string]++; }, TypeError);
961 assertThrows(function() { o[seven_string]--; }, TypeError);
962 assertThrows(function() { ++o[seven_string]; }, TypeError);
963 assertThrows(function() { --o[seven_string]; }, TypeError);
964
965 assertEquals(o[seven_number], 17);
966 assertEquals(o[seven_symbol], 17);
967 assertEquals(o[seven_string], 17);
968})();
969
970
971(function TestAssignmentToReadOnlyLoop() {
972 "use strict";
973
974 var o = {};
975 Object.defineProperty(o, 7, { value: 17 });
976
977 var seven_smi = 7;
978 var seven_number = new Number(7);
979 var seven_symbol = "7";
980 var seven_string = "-7-".substring(1,2);
981
982 for (var i = 0; i < 10; i ++) {
983 assertThrows(function() { o[seven_smi] = "value" }, TypeError);
984 assertThrows(function() { o[seven_number] = "value" }, TypeError);
985 assertThrows(function() { o[seven_symbol] = "value" }, TypeError);
986 assertThrows(function() { o[seven_string] = "value" }, TypeError);
987 }
988
989 assertEquals(o[7], 17);
990})();
991
992
993(function TestAssignmentToStringLength() {
994 "use strict";
995
996 var str_val = "string";
997 var str_obj = new String(str_val);
998 var str_cat = str_val + str_val + str_obj;
999
1000 assertThrows(function() { str_val.length = 1; }, TypeError);
1001 assertThrows(function() { str_obj.length = 1; }, TypeError);
1002 assertThrows(function() { str_cat.length = 1; }, TypeError);
1003})();
Steve Block44f0eee2011-05-26 01:26:41 +01001004
1005
1006(function TestArgumentsAliasing() {
1007 function strict(a, b) {
1008 "use strict";
1009 a = "c";
1010 b = "d";
1011 return [a, b, arguments[0], arguments[1]];
1012 }
1013
1014 function nonstrict(a, b) {
1015 a = "c";
1016 b = "d";
1017 return [a, b, arguments[0], arguments[1]];
1018 }
1019
1020 assertEquals(["c", "d", "a", "b"], strict("a", "b"));
1021 assertEquals(["c", "d", "c", "d"], nonstrict("a", "b"));
1022})();
1023
1024
1025function CheckPillDescriptor(func, name) {
1026
1027 function CheckPill(pill) {
1028 assertEquals("function", typeof pill);
1029 assertInstanceof(pill, Function);
1030 pill.property = "value";
1031 assertEquals(pill.value, undefined);
1032 assertThrows(function() { 'use strict'; pill.property = "value"; },
1033 TypeError);
1034 assertThrows(pill, TypeError);
1035 assertEquals(pill.prototype, (function(){}).prototype);
1036 var d = Object.getOwnPropertyDescriptor(pill, "prototype");
1037 assertFalse(d.writable);
1038 assertFalse(d.configurable);
1039 assertFalse(d.enumerable);
1040 }
1041
1042 var descriptor = Object.getOwnPropertyDescriptor(func, name);
1043 CheckPill(descriptor.get)
1044 CheckPill(descriptor.set);
1045 assertFalse(descriptor.enumerable);
1046 assertFalse(descriptor.configurable);
1047}
1048
1049
1050(function TestStrictFunctionPills() {
1051 function strict() {
1052 "use strict";
1053 }
1054 assertThrows(function() { strict.caller; }, TypeError);
1055 assertThrows(function() { strict.arguments; }, TypeError);
1056
1057 var another = new Function("'use strict'");
1058 assertThrows(function() { another.caller; }, TypeError);
1059 assertThrows(function() { another.arguments; }, TypeError);
1060
1061 var third = (function() { "use strict"; return function() {}; })();
1062 assertThrows(function() { third.caller; }, TypeError);
1063 assertThrows(function() { third.arguments; }, TypeError);
1064
1065 CheckPillDescriptor(strict, "caller");
1066 CheckPillDescriptor(strict, "arguments");
1067 CheckPillDescriptor(another, "caller");
1068 CheckPillDescriptor(another, "arguments");
1069 CheckPillDescriptor(third, "caller");
1070 CheckPillDescriptor(third, "arguments");
1071})();
1072
1073
1074(function TestStrictFunctionWritablePrototype() {
1075 "use strict";
1076 function TheClass() {
1077 }
1078 assertThrows(function() { TheClass.caller; }, TypeError);
1079 assertThrows(function() { TheClass.arguments; }, TypeError);
1080
1081 // Strict functions must have writable prototype.
1082 TheClass.prototype = {
1083 func: function() { return "func_value"; },
1084 get accessor() { return "accessor_value"; },
1085 property: "property_value",
1086 };
1087
1088 var o = new TheClass();
1089 assertEquals(o.func(), "func_value");
1090 assertEquals(o.accessor, "accessor_value");
1091 assertEquals(o.property, "property_value");
1092})();
1093
1094
1095(function TestStrictArgumentPills() {
1096 function strict() {
1097 "use strict";
1098 return arguments;
1099 }
1100
1101 var args = strict();
1102 CheckPillDescriptor(args, "caller");
1103 CheckPillDescriptor(args, "callee");
1104
1105 args = strict(17, "value", strict);
1106 assertEquals(17, args[0])
1107 assertEquals("value", args[1])
1108 assertEquals(strict, args[2]);
1109 CheckPillDescriptor(args, "caller");
1110 CheckPillDescriptor(args, "callee");
1111
1112 function outer() {
1113 "use strict";
1114 function inner() {
1115 return arguments;
1116 }
1117 return inner;
1118 }
1119
1120 var args = outer()();
1121 CheckPillDescriptor(args, "caller");
1122 CheckPillDescriptor(args, "callee");
1123
1124 args = outer()(17, "value", strict);
1125 assertEquals(17, args[0])
1126 assertEquals("value", args[1])
1127 assertEquals(strict, args[2]);
1128 CheckPillDescriptor(args, "caller");
1129 CheckPillDescriptor(args, "callee");
1130})();
1131
1132
1133(function TestNonStrictFunctionCallerPillSimple() {
1134 function return_my_caller() {
1135 return return_my_caller.caller;
1136 }
1137
1138 function strict() {
1139 "use strict";
1140 return_my_caller();
1141 }
1142 assertThrows(strict, TypeError);
1143
1144 function non_strict() {
1145 return return_my_caller();
1146 }
1147 assertSame(non_strict(), non_strict);
1148})();
1149
1150
1151(function TestNonStrictFunctionCallerPill() {
1152 function strict(n) {
1153 "use strict";
1154 non_strict(n);
1155 }
1156
1157 function recurse(n, then) {
1158 if (n > 0) {
1159 recurse(n - 1);
1160 } else {
1161 return then();
1162 }
1163 }
1164
1165 function non_strict(n) {
1166 recurse(n, function() { non_strict.caller; });
1167 }
1168
1169 function test(n) {
1170 try {
1171 recurse(n, function() { strict(n); });
1172 } catch(e) {
1173 return e instanceof TypeError;
1174 }
1175 return false;
1176 }
1177
1178 for (var i = 0; i < 10; i ++) {
1179 assertEquals(test(i), true);
1180 }
1181})();