Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / v8 / test / mjsunit / array-splice.js
1 // Copyright 2010 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 // Check that splicing array of holes keeps it as array of holes
29 (function() {
30   for (var i = 0; i < 7; i++) {
31     var array = new Array(10);
32     var spliced = array.splice(1, 1, 'one', 'two');
33     assertEquals(1, spliced.length);
34     assertFalse(0 in spliced, "0 in spliced");
35
36     assertEquals(11, array.length);
37     assertFalse(0 in array, "0 in array");
38     assertTrue(1 in array);
39     assertTrue(2 in array);
40     assertFalse(3 in array, "3 in array");
41   }
42 })();
43
44
45 // Check various variants of empty array's splicing.
46 (function() {
47   for (var i = 0; i < 7; i++) {
48     assertEquals([], [].splice(0, 0));
49     assertEquals([], [].splice(1, 0));
50     assertEquals([], [].splice(0, 1));
51     assertEquals([], [].splice(-1, 0));
52   }
53 })();
54
55
56 // Check that even if result array is empty, receiver gets sliced.
57 (function() {
58   for (var i = 0; i < 7; i++) {
59     var a = [1, 2, 3];
60     assertEquals([], a.splice(1, 0, 'a', 'b', 'c'));
61     assertEquals([1, 'a', 'b', 'c', 2, 3], a);
62   }
63 })();
64
65
66 // Check various forms of arguments omission.
67 (function() {
68   var array;
69   for (var i = 0; i < 7; i++) {
70     array = [1, 2, 3]
71     assertEquals([], array.splice());
72     assertEquals([1, 2, 3], array);
73
74     // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
75     // given differently from when an undefined delete count is given.
76     // This does not follow ECMA-262, but we do the same for
77     // compatibility.
78     array = [1, 2, 3]
79     assertEquals([1, 2, 3], array.splice(0));
80     assertEquals([], array);
81
82     array = [1, 2, 3]
83     assertEquals([1, 2, 3], array.splice(undefined));
84     assertEquals([], array);
85
86     array = [1, 2, 3]
87     assertEquals([1, 2, 3], array.splice("foobar"));
88     assertEquals([], array);
89
90     array = [1, 2, 3]
91     assertEquals([], array.splice(undefined, undefined));
92     assertEquals([1, 2, 3], array);
93
94     array = [1, 2, 3]
95     assertEquals([], array.splice("foobar", undefined));
96     assertEquals([1, 2, 3], array);
97
98     array = [1, 2, 3]
99     assertEquals([], array.splice(undefined, "foobar"));
100     assertEquals([1, 2, 3], array);
101
102     array = [1, 2, 3]
103     assertEquals([], array.splice("foobar", "foobar"));
104     assertEquals([1, 2, 3], array);
105   }
106 })();
107
108
109 // Check variants of negatives and positive indices.
110 (function() {
111   var array, spliced;
112   for (var i = 0; i < 7; i++) {
113     array = [1, 2, 3, 4, 5, 6, 7];
114     spliced = array.splice(-100);
115     assertEquals([], array);
116     assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
117
118     array = [1, 2, 3, 4, 5, 6, 7];
119     spliced = array.splice(-3);
120     assertEquals([1, 2, 3, 4], array);
121     assertEquals([5, 6, 7], spliced);
122
123     array = [1, 2, 3, 4, 5, 6, 7];
124     spliced = array.splice(4);
125     assertEquals([1, 2, 3, 4], array);
126     assertEquals([5, 6, 7], spliced);
127
128     array = [1, 2, 3, 4, 5, 6, 7];
129     spliced = array.splice(6);
130     assertEquals([1, 2, 3, 4, 5, 6], array);
131     assertEquals([7], spliced);
132
133     array = [1, 2, 3, 4, 5, 6, 7];
134     spliced = array.splice(7);
135     assertEquals([1, 2, 3, 4, 5, 6, 7], array);
136     assertEquals([], spliced);
137
138     array = [1, 2, 3, 4, 5, 6, 7];
139     spliced = array.splice(8);
140     assertEquals([1, 2, 3, 4, 5, 6, 7], array);
141     assertEquals([], spliced);
142
143     array = [1, 2, 3, 4, 5, 6, 7];
144     spliced = array.splice(100);
145     assertEquals([1, 2, 3, 4, 5, 6, 7], array);
146     assertEquals([], spliced);
147
148     array = [1, 2, 3, 4, 5, 6, 7];
149     spliced = array.splice(0, -100);
150     assertEquals([1, 2, 3, 4, 5, 6, 7], array);
151     assertEquals([], spliced);
152
153     array = [1, 2, 3, 4, 5, 6, 7];
154     spliced = array.splice(0, -3);
155     assertEquals([1, 2, 3, 4, 5, 6, 7], array);
156     assertEquals([], spliced);
157
158     array = [1, 2, 3, 4, 5, 6, 7];
159     spliced = array.splice(0, 4);
160     assertEquals([5, 6, 7], array);
161     assertEquals([1, 2, 3, 4], spliced);
162
163     array = [1, 2, 3, 4, 5, 6, 7];
164     spliced = array.splice(0, 6);
165     assertEquals([7], array);
166     assertEquals([1, 2, 3, 4, 5, 6], spliced);
167
168     array = [1, 2, 3, 4, 5, 6, 7];
169     spliced = array.splice(0, 7);
170     assertEquals([], array);
171     assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
172
173     array = [1, 2, 3, 4, 5, 6, 7];
174     spliced = array.splice(0, 8);
175     assertEquals([], array);
176     assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
177
178     array = [1, 2, 3, 4, 5, 6, 7];
179     spliced = array.splice(0, 100);
180     assertEquals([], array);
181     assertEquals([1, 2, 3, 4, 5, 6, 7], spliced);
182
183     // Some exotic cases.
184     obj = { toString: function() { throw 'Exception'; } };
185
186     // Throwing an exception in conversion:
187     try {
188       [1, 2, 3].splice(obj, 3);
189       throw 'Should have thrown';
190     } catch (e) {
191       assertEquals('Exception', e);
192     }
193
194     try {
195       [1, 2, 3].splice(0, obj, 3);
196       throw 'Should have thrown';
197     } catch (e) {
198       assertEquals('Exception', e);
199     }
200
201     array = [1, 2, 3];
202     array.splice(0, 3, obj);
203     assertEquals(1, array.length);
204
205     // Custom conversion:
206     array = [1, 2, 3];
207     spliced = array.splice({valueOf: function() { return 1; }},
208                            {toString: function() { return 2; }},
209                            'one', 'two');
210     assertEquals([2, 3], spliced);
211     assertEquals([1, 'one', 'two'], array);
212   }
213 })();
214
215
216 // Nasty: modify the array in ToInteger.
217 (function() {
218   var array = [];
219   var spliced;
220
221   for (var i = 0; i < 13; i++) {
222     bad_start = { valueOf: function() { array.push(2*i); return -1; } };
223     bad_count = { valueOf: function() { array.push(2*i + 1); return 1; } };
224     spliced = array.splice(bad_start, bad_count);
225     // According to the spec (15.4.4.12), length is calculated before
226     // performing ToInteger on arguments.  However, v8 ignores elements
227     // we add while converting, so we need corrective pushes.
228     array.push(2*i); array.push(2*i + 1);
229     if (i == 0) {
230       assertEquals([], spliced);  // Length was 0, nothing to get.
231       assertEquals([0, 1], array);
232     } else {
233       // When we start splice, array is [0 .. 2*i - 1], so we get
234       // as a result [2*i], this element is removed from the array,
235       // but [2 * i, 2 * i + 1] are added.
236       assertEquals([2 * i - 1], spliced);
237       assertEquals(2 * i, array[i]);
238       assertEquals(2 * i + 1, array[i + 1]);
239     }
240   }
241 })();
242
243
244 // Now check the case with array of holes and some elements on prototype.
245 (function() {
246   var len = 9;
247
248   var at3 = "@3";
249   var at7 = "@7";
250
251   for (var i = 0; i < 7; i++) {
252     var array = new Array(len);
253     var array_proto = [];
254     array_proto[3] = at3;
255     array_proto[7] = at7;
256     array.__proto__ = array_proto;
257
258     var spliced = array.splice(2, 2, 'one', undefined, 'two');
259
260     // Second hole (at index 3) of array turns into
261     // value of Array.prototype[3] while copying.
262     assertEquals([, at3], spliced);
263     assertEquals([, , 'one', undefined, 'two', , , at7, at7, ,], array);
264
265     // ... but array[3] and array[7] is actually a hole:
266     assertTrue(delete array_proto[3]);
267     assertEquals(undefined, array[3]);
268     assertTrue(delete array_proto[7]);
269     assertEquals(undefined, array[7]);
270
271     // and now check hasOwnProperty
272     assertFalse(array.hasOwnProperty(0), "array.hasOwnProperty(0)");
273     assertFalse(array.hasOwnProperty(1), "array.hasOwnProperty(1)");
274     assertTrue(array.hasOwnProperty(2));
275     assertTrue(array.hasOwnProperty(3));
276     assertTrue(array.hasOwnProperty(4));
277     assertFalse(array.hasOwnProperty(5), "array.hasOwnProperty(5)");
278     assertFalse(array.hasOwnProperty(6), "array.hasOwnProperty(6)");
279     assertFalse(array.hasOwnProperty(7), "array.hasOwnProperty(7)");
280     assertTrue(array.hasOwnProperty(8));
281     assertFalse(array.hasOwnProperty(9), "array.hasOwnProperty(9)");
282
283     // and now check couple of indices above length.
284     assertFalse(array.hasOwnProperty(10), "array.hasOwnProperty(10)");
285     assertFalse(array.hasOwnProperty(15), "array.hasOwnProperty(15)");
286     assertFalse(array.hasOwnProperty(31), "array.hasOwnProperty(31)");
287     assertFalse(array.hasOwnProperty(63), "array.hasOwnProperty(63)");
288     assertFalse(array.hasOwnProperty(Math.pow(2, 32) - 2),
289                 "array.hasOwnProperty(Math.pow(2, 32) - 2)");
290   }
291 })();
292
293
294 // Now check the case with array of holes and some elements on prototype.
295 (function() {
296   var len = 9;
297
298   var at3 = "@3";
299   var at7 = "@7";
300
301   for (var i = 0; i < 7; i++) {
302     var array = new Array(len);
303     Array.prototype[3] = at3;
304     Array.prototype[7] = at7;
305
306     var spliced = array.splice(2, 2, 'one', undefined, 'two');
307
308     // Second hole (at index 3) of array turns into
309     // value of Array.prototype[3] while copying.
310     assertEquals([, at3], spliced);
311     assertEquals([, , 'one', undefined, 'two', , , at7, at7, ,], array);
312
313     // ... but array[3] and array[7] is actually a hole:
314     assertTrue(delete Array.prototype[3]);
315     assertEquals(undefined, array[3]);
316     assertTrue(delete Array.prototype[7]);
317     assertEquals(undefined, array[7]);
318
319     // and now check hasOwnProperty
320     assertFalse(array.hasOwnProperty(0), "array.hasOwnProperty(0)");
321     assertFalse(array.hasOwnProperty(1), "array.hasOwnProperty(1)");
322     assertTrue(array.hasOwnProperty(2));
323     assertTrue(array.hasOwnProperty(3));
324     assertTrue(array.hasOwnProperty(4));
325     assertFalse(array.hasOwnProperty(5), "array.hasOwnProperty(5)");
326     assertFalse(array.hasOwnProperty(6), "array.hasOwnProperty(6)");
327     assertFalse(array.hasOwnProperty(7), "array.hasOwnProperty(7)");
328     assertTrue(array.hasOwnProperty(8));
329     assertFalse(array.hasOwnProperty(9), "array.hasOwnProperty(9)");
330
331     // and now check couple of indices above length.
332     assertFalse(array.hasOwnProperty(10), "array.hasOwnProperty(10)");
333     assertFalse(array.hasOwnProperty(15), "array.hasOwnProperty(15)");
334     assertFalse(array.hasOwnProperty(31), "array.hasOwnProperty(31)");
335     assertFalse(array.hasOwnProperty(63), "array.hasOwnProperty(63)");
336     assertFalse(array.hasOwnProperty(Math.pow(2, 32) - 2),
337                 "array.hasOwnProperty(Math.pow(2, 32) - 2)");
338   }
339 })();
340
341
342 // Check the case of JS builtin .splice()
343 (function() {
344   for (var i = 0; i < 7; i++) {
345     var array = [1, 2, 3, 4];
346     Array.prototype[3] = 'foo';  // To force JS builtin.
347
348     var spliced = array.splice();
349
350     assertEquals([], spliced);
351     assertEquals([1, 2, 3, 4], array);
352   }
353 })();
354
355
356 // Check the behaviour when approaching maximal values for length.
357 (function() {
358   for (var i = 0; i < 7; i++) {
359     try {
360       new Array(Math.pow(2, 32) - 3).splice(-1, 0, 1, 2, 3, 4, 5);
361       throw 'Should have thrown RangeError';
362     } catch (e) {
363       assertTrue(e instanceof RangeError);
364     }
365
366     // Check smi boundary
367     var bigNum = (1 << 30) - 3;
368     var array = new Array(bigNum);
369     array.splice(-1, 0, 1, 2, 3, 4, 5, 6, 7);
370     assertEquals(bigNum + 7, array.length);
371   }
372 })();
373
374 (function() {
375   for (var i = 0; i < 7; i++) {
376     var a = [7, 8, 9];
377     a.splice(0, 0, 1, 2, 3, 4, 5, 6);
378     assertEquals([1, 2, 3, 4, 5, 6, 7, 8, 9], a);
379     assertFalse(a.hasOwnProperty(10), "a.hasOwnProperty(10)");
380     assertEquals(undefined, a[10]);
381   }
382 })();