blob: 06479ad4e826a3e94f40770f2d965d367197c81d [file] [log] [blame]
Ben Murdoch257744e2011-11-30 15:57:28 +00001// 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
28
29var should_throw_on_null_and_undefined =
30 [Object.prototype.toLocaleString,
31 Object.prototype.valueOf,
32 Object.prototype.hasOwnProperty,
33 Object.prototype.isPrototypeOf,
34 Object.prototype.propertyIsEnumerable,
35 Array.prototype.concat,
36 Array.prototype.join,
37 Array.prototype.pop,
38 Array.prototype.push,
39 Array.prototype.reverse,
40 Array.prototype.shift,
41 Array.prototype.slice,
42 Array.prototype.sort,
43 Array.prototype.splice,
44 Array.prototype.unshift,
45 Array.prototype.indexOf,
46 Array.prototype.lastIndexOf,
47 Array.prototype.every,
48 Array.prototype.some,
49 Array.prototype.forEach,
50 Array.prototype.map,
51 Array.prototype.filter,
52 Array.prototype.reduce,
53 Array.prototype.reduceRight,
54 String.prototype.charAt,
55 String.prototype.charCodeAt,
56 String.prototype.concat,
57 String.prototype.indexOf,
58 String.prototype.lastIndexOf,
59 String.prototype.localeCompare,
60 String.prototype.match,
61 String.prototype.replace,
62 String.prototype.search,
63 String.prototype.slice,
64 String.prototype.split,
65 String.prototype.substring,
66 String.prototype.toLowerCase,
67 String.prototype.toLocaleLowerCase,
68 String.prototype.toUpperCase,
69 String.prototype.toLocaleUpperCase,
70 String.prototype.trim,
71 Number.prototype.toLocaleString,
72 Error.prototype.toString];
73
74// Non generic natives do not work on any input other than the specific
75// type, but since this change will allow call to be invoked with undefined
76// or null as this we still explicitly test that we throw on these here.
77var non_generic =
78 [Array.prototype.toString,
79 Array.prototype.toLocaleString,
80 Function.prototype.toString,
81 Function.prototype.call,
82 Function.prototype.apply,
83 String.prototype.toString,
84 String.prototype.valueOf,
85 Boolean.prototype.toString,
86 Boolean.prototype.valueOf,
87 Number.prototype.toString,
88 Number.prototype.valueOf,
89 Number.prototype.toFixed,
90 Number.prototype.toExponential,
91 Number.prototype.toPrecision,
92 Date.prototype.toString,
93 Date.prototype.toDateString,
94 Date.prototype.toTimeString,
95 Date.prototype.toLocaleString,
96 Date.prototype.toLocaleDateString,
97 Date.prototype.toLocaleTimeString,
98 Date.prototype.valueOf,
99 Date.prototype.getTime,
100 Date.prototype.getFullYear,
101 Date.prototype.getUTCFullYear,
102 Date.prototype.getMonth,
103 Date.prototype.getUTCMonth,
104 Date.prototype.getDate,
105 Date.prototype.getUTCDate,
106 Date.prototype.getDay,
107 Date.prototype.getUTCDay,
108 Date.prototype.getHours,
109 Date.prototype.getUTCHours,
110 Date.prototype.getMinutes,
111 Date.prototype.getUTCMinutes,
112 Date.prototype.getSeconds,
113 Date.prototype.getUTCSeconds,
114 Date.prototype.getMilliseconds,
115 Date.prototype.getUTCMilliseconds,
116 Date.prototype.getTimezoneOffset,
117 Date.prototype.setTime,
118 Date.prototype.setMilliseconds,
119 Date.prototype.setUTCMilliseconds,
120 Date.prototype.setSeconds,
121 Date.prototype.setUTCSeconds,
122 Date.prototype.setMinutes,
123 Date.prototype.setUTCMinutes,
124 Date.prototype.setHours,
125 Date.prototype.setUTCHours,
126 Date.prototype.setDate,
127 Date.prototype.setUTCDate,
128 Date.prototype.setMonth,
129 Date.prototype.setUTCMonth,
130 Date.prototype.setFullYear,
131 Date.prototype.setUTCFullYear,
132 Date.prototype.toUTCString,
133 Date.prototype.toISOString,
134 Date.prototype.toJSON,
135 RegExp.prototype.exec,
136 RegExp.prototype.test,
137 RegExp.prototype.toString];
138
139
140// Mapping functions.
141var mapping_functions =
142 [Array.prototype.every,
143 Array.prototype.some,
144 Array.prototype.forEach,
145 Array.prototype.map,
146 Array.prototype.filter];
147
148// Reduce functions.
149var reducing_functions =
150 [Array.prototype.reduce,
151 Array.prototype.reduceRight];
152
153// Test that all natives using the ToObject call throw the right exception.
154for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
155 // Sanity check that all functions are correct
156 assertEquals(typeof(should_throw_on_null_and_undefined[i]), "function");
157
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000158 var exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000159 try {
160 // We call all functions with no parameters, which means that essential
161 // parameters will have the undefined value.
162 // The test for whether the "this" value is null or undefined is always
163 // performed before access to the other parameters, so even if the
164 // undefined value is an invalid argument value, it mustn't change
165 // the result of the test.
166 should_throw_on_null_and_undefined[i].call(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000167 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000168 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000169 assertTrue("called_on_null_or_undefined" == e.type ||
170 "null_to_object" == e.type);
171 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000172 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000173
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000174 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000175 try {
176 should_throw_on_null_and_undefined[i].call(undefined);
Ben Murdoch257744e2011-11-30 15:57:28 +0000177 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000178 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000179 assertTrue("called_on_null_or_undefined" == e.type ||
180 "null_to_object" == e.type);
181 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000182 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000183
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000184 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000185 try {
186 should_throw_on_null_and_undefined[i].apply(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000187 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000188 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000189 assertTrue("called_on_null_or_undefined" == e.type ||
190 "null_to_object" == e.type);
191 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000192 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000193
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000194 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000195 try {
196 should_throw_on_null_and_undefined[i].apply(undefined);
Ben Murdoch257744e2011-11-30 15:57:28 +0000197 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000198 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000199 assertTrue("called_on_null_or_undefined" == e.type ||
200 "null_to_object" == e.type);
201 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000202 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000203}
204
205// Test that all natives that are non generic throw on null and undefined.
206for (var i = 0; i < non_generic.length; i++) {
207 // Sanity check that all functions are correct
208 assertEquals(typeof(non_generic[i]), "function");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000209
210 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000211 try {
212 non_generic[i].call(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000213 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000214 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000215 assertTrue(e instanceof TypeError);
216 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000217 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000218
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000219 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000220 try {
221 non_generic[i].call(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000222 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000223 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000224 assertTrue(e instanceof TypeError);
225 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000226 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000227
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000228 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000229 try {
230 non_generic[i].apply(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000231 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000232 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000233 assertTrue(e instanceof TypeError);
234 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000235 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000236
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000237 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000238 try {
239 non_generic[i].apply(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000240 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000241 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000242 assertTrue(e instanceof TypeError);
243 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000244 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000245}
246
247
248// Test that we still throw when calling with thisArg null or undefined
249// through an array mapping function.
250var array = [1,2,3,4,5];
251for (var j = 0; j < mapping_functions.length; j++) {
252 for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000253 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000254 try {
255 mapping_functions[j].call(array,
256 should_throw_on_null_and_undefined[i],
257 null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000258 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000259 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000260 assertTrue("called_on_null_or_undefined" == e.type ||
261 "null_to_object" == e.type);
262 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000263 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000264
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000265 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000266 try {
267 mapping_functions[j].call(array,
268 should_throw_on_null_and_undefined[i],
269 undefined);
Ben Murdoch257744e2011-11-30 15:57:28 +0000270 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000271 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000272 assertTrue("called_on_null_or_undefined" == e.type ||
273 "null_to_object" == e.type);
274 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000275 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000276 }
277}
278
279for (var j = 0; j < mapping_functions.length; j++) {
280 for (var i = 0; i < non_generic.length; i++) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000281 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000282 try {
283 mapping_functions[j].call(array,
284 non_generic[i],
285 null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000286 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000287 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000288 assertTrue(e instanceof TypeError);
289 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000290 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000291
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000292 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000293 try {
294 mapping_functions[j].call(array,
295 non_generic[i],
296 undefined);
Ben Murdoch257744e2011-11-30 15:57:28 +0000297 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000298 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000299 assertTrue(e instanceof TypeError);
300 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000301 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000302 }
303}
304
305
306// Reduce functions do a call with null as this argument.
307for (var j = 0; j < reducing_functions.length; j++) {
308 for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000309 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000310 try {
311 reducing_functions[j].call(array, should_throw_on_null_and_undefined[i]);
Ben Murdoch257744e2011-11-30 15:57:28 +0000312 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000313 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000314 assertTrue("called_on_null_or_undefined" == e.type ||
315 "null_to_object" == e.type);
316 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000317 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000318
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000319 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000320 try {
321 reducing_functions[j].call(array, should_throw_on_null_and_undefined[i]);
Ben Murdoch257744e2011-11-30 15:57:28 +0000322 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000323 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000324 assertTrue("called_on_null_or_undefined" == e.type ||
325 "null_to_object" == e.type);
326 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000327 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000328 }
329}
330
331for (var j = 0; j < reducing_functions.length; j++) {
332 for (var i = 0; i < non_generic.length; i++) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000333 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000334 try {
335 reducing_functions[j].call(array, non_generic[i]);
Ben Murdoch257744e2011-11-30 15:57:28 +0000336 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000337 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000338 assertTrue(e instanceof TypeError);
339 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000340 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000341
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000342 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000343 try {
344 reducing_functions[j].call(array, non_generic[i]);
Ben Murdoch257744e2011-11-30 15:57:28 +0000345 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000346 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000347 assertTrue(e instanceof TypeError);
348 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000349 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000350 }
351}
352
353
354// Object.prototype.toString()
355assertEquals(Object.prototype.toString.call(null),
356 '[object Null]')
357
358assertEquals(Object.prototype.toString.call(undefined),
359 '[object Undefined]')