blob: 88df353a60c2ae9f96447c0a765af7e40c482229 [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,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000070 String.prototype.trim];
Ben Murdoch257744e2011-11-30 15:57:28 +000071
72// Non generic natives do not work on any input other than the specific
73// type, but since this change will allow call to be invoked with undefined
74// or null as this we still explicitly test that we throw on these here.
75var non_generic =
76 [Array.prototype.toString,
77 Array.prototype.toLocaleString,
78 Function.prototype.toString,
79 Function.prototype.call,
80 Function.prototype.apply,
81 String.prototype.toString,
82 String.prototype.valueOf,
83 Boolean.prototype.toString,
84 Boolean.prototype.valueOf,
85 Number.prototype.toString,
86 Number.prototype.valueOf,
87 Number.prototype.toFixed,
88 Number.prototype.toExponential,
89 Number.prototype.toPrecision,
90 Date.prototype.toString,
91 Date.prototype.toDateString,
92 Date.prototype.toTimeString,
93 Date.prototype.toLocaleString,
94 Date.prototype.toLocaleDateString,
95 Date.prototype.toLocaleTimeString,
96 Date.prototype.valueOf,
97 Date.prototype.getTime,
98 Date.prototype.getFullYear,
99 Date.prototype.getUTCFullYear,
100 Date.prototype.getMonth,
101 Date.prototype.getUTCMonth,
102 Date.prototype.getDate,
103 Date.prototype.getUTCDate,
104 Date.prototype.getDay,
105 Date.prototype.getUTCDay,
106 Date.prototype.getHours,
107 Date.prototype.getUTCHours,
108 Date.prototype.getMinutes,
109 Date.prototype.getUTCMinutes,
110 Date.prototype.getSeconds,
111 Date.prototype.getUTCSeconds,
112 Date.prototype.getMilliseconds,
113 Date.prototype.getUTCMilliseconds,
114 Date.prototype.getTimezoneOffset,
115 Date.prototype.setTime,
116 Date.prototype.setMilliseconds,
117 Date.prototype.setUTCMilliseconds,
118 Date.prototype.setSeconds,
119 Date.prototype.setUTCSeconds,
120 Date.prototype.setMinutes,
121 Date.prototype.setUTCMinutes,
122 Date.prototype.setHours,
123 Date.prototype.setUTCHours,
124 Date.prototype.setDate,
125 Date.prototype.setUTCDate,
126 Date.prototype.setMonth,
127 Date.prototype.setUTCMonth,
128 Date.prototype.setFullYear,
129 Date.prototype.setUTCFullYear,
130 Date.prototype.toUTCString,
131 Date.prototype.toISOString,
132 Date.prototype.toJSON,
133 RegExp.prototype.exec,
134 RegExp.prototype.test,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100135 RegExp.prototype.toString,
136 Error.prototype.toString];
Ben Murdoch257744e2011-11-30 15:57:28 +0000137
138
139// Mapping functions.
140var mapping_functions =
141 [Array.prototype.every,
142 Array.prototype.some,
143 Array.prototype.forEach,
144 Array.prototype.map,
145 Array.prototype.filter];
146
147// Reduce functions.
148var reducing_functions =
149 [Array.prototype.reduce,
150 Array.prototype.reduceRight];
151
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000152function checkExpectedMessage(e) {
153 assertTrue(e.message.indexOf("called on null or undefined") >= 0 ||
154 e.message.indexOf("invoked on undefined or null value") >= 0 ||
155 e.message.indexOf("Cannot convert undefined or null to object") >= 0);
156}
157
Ben Murdoch257744e2011-11-30 15:57:28 +0000158// Test that all natives using the ToObject call throw the right exception.
159for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
160 // Sanity check that all functions are correct
161 assertEquals(typeof(should_throw_on_null_and_undefined[i]), "function");
162
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000163 var exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000164 try {
165 // We call all functions with no parameters, which means that essential
166 // parameters will have the undefined value.
167 // The test for whether the "this" value is null or undefined is always
168 // performed before access to the other parameters, so even if the
169 // undefined value is an invalid argument value, it mustn't change
170 // the result of the test.
171 should_throw_on_null_and_undefined[i].call(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000172 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000173 exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000174 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000175 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000176 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000177
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000178 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000179 try {
180 should_throw_on_null_and_undefined[i].call(undefined);
Ben Murdoch257744e2011-11-30 15:57:28 +0000181 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000182 exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000183 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000184 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000185 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000186
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000187 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000188 try {
189 should_throw_on_null_and_undefined[i].apply(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000190 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000191 exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000192 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000193 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000194 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000195
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000196 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000197 try {
198 should_throw_on_null_and_undefined[i].apply(undefined);
Ben Murdoch257744e2011-11-30 15:57:28 +0000199 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000200 exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000201 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000202 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000203 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000204}
205
206// Test that all natives that are non generic throw on null and undefined.
207for (var i = 0; i < non_generic.length; i++) {
208 // Sanity check that all functions are correct
209 assertEquals(typeof(non_generic[i]), "function");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000210
211 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000212 try {
213 non_generic[i].call(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000214 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000215 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000216 assertTrue(e instanceof TypeError);
217 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000218 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000219
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000220 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000221 try {
222 non_generic[i].call(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000223 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000224 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000225 assertTrue(e instanceof TypeError);
226 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000227 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000228
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000229 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000230 try {
231 non_generic[i].apply(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000232 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000233 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000234 assertTrue(e instanceof TypeError);
235 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000236 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000237
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000238 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000239 try {
240 non_generic[i].apply(null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000241 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000242 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000243 assertTrue(e instanceof TypeError);
244 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000245 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000246}
247
248
249// Test that we still throw when calling with thisArg null or undefined
250// through an array mapping function.
251var array = [1,2,3,4,5];
252for (var j = 0; j < mapping_functions.length; j++) {
253 for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000254 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000255 try {
256 mapping_functions[j].call(array,
257 should_throw_on_null_and_undefined[i],
258 null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000259 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000260 exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000261 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000262 }
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 Murdochb8a8cc12014-11-26 15:28:44 +0000272 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000273 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000274 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000275 }
276}
277
278for (var j = 0; j < mapping_functions.length; j++) {
279 for (var i = 0; i < non_generic.length; i++) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000280 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000281 try {
282 mapping_functions[j].call(array,
283 non_generic[i],
284 null);
Ben Murdoch257744e2011-11-30 15:57:28 +0000285 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000286 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000287 assertTrue(e instanceof TypeError);
288 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000289 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000290
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000291 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000292 try {
293 mapping_functions[j].call(array,
294 non_generic[i],
295 undefined);
Ben Murdoch257744e2011-11-30 15:57:28 +0000296 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000297 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000298 assertTrue(e instanceof TypeError);
299 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000300 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000301 }
302}
303
304
305// Reduce functions do a call with null as this argument.
306for (var j = 0; j < reducing_functions.length; j++) {
307 for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000308 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000309 try {
310 reducing_functions[j].call(array, should_throw_on_null_and_undefined[i]);
Ben Murdoch257744e2011-11-30 15:57:28 +0000311 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000312 exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000313 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000314 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000315 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000316
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000317 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000318 try {
319 reducing_functions[j].call(array, should_throw_on_null_and_undefined[i]);
Ben Murdoch257744e2011-11-30 15:57:28 +0000320 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000321 exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000322 checkExpectedMessage(e);
Ben Murdoch257744e2011-11-30 15:57:28 +0000323 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000324 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000325 }
326}
327
328for (var j = 0; j < reducing_functions.length; j++) {
329 for (var i = 0; i < non_generic.length; i++) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000330 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000331 try {
332 reducing_functions[j].call(array, non_generic[i]);
Ben Murdoch257744e2011-11-30 15:57:28 +0000333 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000334 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000335 assertTrue(e instanceof TypeError);
336 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000337 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000338
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000339 exception = false;
Ben Murdoch257744e2011-11-30 15:57:28 +0000340 try {
341 reducing_functions[j].call(array, non_generic[i]);
Ben Murdoch257744e2011-11-30 15:57:28 +0000342 } catch (e) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000343 exception = true;
Ben Murdoch257744e2011-11-30 15:57:28 +0000344 assertTrue(e instanceof TypeError);
345 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000346 assertTrue(exception);
Ben Murdoch257744e2011-11-30 15:57:28 +0000347 }
348}
349
350
351// Object.prototype.toString()
352assertEquals(Object.prototype.toString.call(null),
353 '[object Null]')
354
355assertEquals(Object.prototype.toString.call(undefined),
356 '[object Undefined]')