Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / v8 / test / mjsunit / array-slice.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 slicing array of holes keeps it as array of holes
29 (function() {
30   var array = new Array(10);
31   for (var i = 0; i < 7; i++) {
32     var sliced = array.slice();
33     assertEquals(array.length, sliced.length);
34     assertFalse(0 in sliced);
35   }
36 })();
37
38
39 // Check various variants of empty array's slicing.
40 (function() {
41   for (var i = 0; i < 7; i++) {
42     assertEquals([], [].slice(0, 0));
43     assertEquals([], [].slice(1, 0));
44     assertEquals([], [].slice(0, 1));
45     assertEquals([], [].slice(-1, 0));
46   }
47 })();
48
49
50 // Check various forms of arguments omission.
51 (function() {
52   var array = new Array(7);
53
54   for (var i = 0; i < 7; i++) {
55     assertEquals(array, array.slice());
56     assertEquals(array, array.slice(0));
57     assertEquals(array, array.slice(undefined));
58     assertEquals(array, array.slice("foobar"));
59     assertEquals(array, array.slice(undefined, undefined));
60   }
61 })();
62
63
64 // Check variants of negatives and positive indices.
65 (function() {
66   var array = new Array(7);
67
68   for (var i = 0; i < 7; i++) {
69     assertEquals(7, array.slice(-100).length);
70     assertEquals(3, array.slice(-3).length);
71     assertEquals(3, array.slice(4).length);
72     assertEquals(1, array.slice(6).length);
73     assertEquals(0, array.slice(7).length);
74     assertEquals(0, array.slice(8).length);
75     assertEquals(0, array.slice(100).length);
76
77     assertEquals(0, array.slice(0, -100).length);
78     assertEquals(4, array.slice(0, -3).length);
79     assertEquals(4, array.slice(0, 4).length);
80     assertEquals(6, array.slice(0, 6).length);
81     assertEquals(7, array.slice(0, 7).length);
82     assertEquals(7, array.slice(0, 8).length);
83     assertEquals(7, array.slice(0, 100).length);
84
85     // Some exotic cases.
86
87     obj = { toString: function() { throw 'Exception'; } };
88
89     // More than 2 arguments:
90     assertEquals(7, array.slice(0, 7, obj, null, undefined).length);
91
92     // Custom conversion:
93     assertEquals(1, array.slice({valueOf: function() { return 1; }},
94                                 {toString: function() { return 2; }}).length);
95
96     // Throwing an exception in conversion:
97     try {
98       assertEquals(7, array.slice(0, obj).length);
99       throw 'Should have thrown';
100     } catch (e) {
101       assertEquals('Exception', e);
102     }
103   }
104 })();
105
106
107 // Nasty: modify the array in ToInteger.
108 (function() {
109   var array = [];
110   var expected = []
111   bad_guy = { valueOf: function() { array.push(array.length); return -1; } };
112
113   for (var i = 0; i < 13; i++) {
114     var sliced = array.slice(bad_guy);
115     expected.push(i);
116     assertEquals(expected, array);
117     // According to the spec (15.4.4.10), length is calculated before
118     // performing ToInteger on arguments.
119     if (i == 0) {
120       assertEquals([], sliced);  // Length was 0, nothing to get.
121     } else {
122       // Actually out of array [0..i] we get [i - 1] as length is i.
123       assertEquals([i - 1], sliced);
124     }
125   }
126 })();
127
128
129 // Now check the case with array of holes and some elements on prototype.
130 // Note: that is important that this test runs before the next one
131 // as the next one tampers Array.prototype.
132 (function() {
133   var len = 9;
134   var array = new Array(len);
135
136   var at3 = "@3";
137   var at7 = "@7";
138
139   for (var i = 0; i < 7; i++) {
140     var array_proto = [];
141     array_proto[3] = at3;
142     array_proto[7] = at7;
143     array.__proto__ = array_proto;
144
145     assertEquals(len, array.length);
146     for (var i = 0; i < array.length; i++) {
147       assertEquals(array[i], array_proto[i]);
148     }
149
150     var sliced = array.slice();
151
152     assertEquals(len, sliced.length);
153
154     assertTrue(delete array_proto[3]);
155     assertTrue(delete array_proto[7]);
156
157     // Note that slice copies values from prototype into the array.
158     assertEquals(array[3], undefined);
159     assertFalse(array.hasOwnProperty(3));
160     assertEquals(sliced[3], at3);
161     assertTrue(sliced.hasOwnProperty(3));
162
163     assertEquals(array[7], undefined);
164     assertFalse(array.hasOwnProperty(7));
165     assertEquals(sliced[7], at7);
166     assertTrue(sliced.hasOwnProperty(7));
167
168     // ... but keeps the rest as holes:
169     array_proto[5] = "@5";
170     assertEquals(array[5], array_proto[5]);
171     assertFalse(array.hasOwnProperty(5));
172   }
173 })();
174
175
176 // Now check the case with array of holes and some elements on prototype.
177 (function() {
178   var len = 9;
179   var array = new Array(len);
180
181   var at3 = "@3";
182   var at7 = "@7";
183
184   for (var i = 0; i < 7; i++) {
185     Array.prototype[3] = at3;
186     Array.prototype[7] = at7;
187
188     assertEquals(len, array.length);
189     for (var i = 0; i < array.length; i++) {
190       assertEquals(array[i], Array.prototype[i]);
191     }
192
193     var sliced = array.slice();
194
195     assertEquals(len, sliced.length);
196
197     assertTrue(delete Array.prototype[3]);
198     assertTrue(delete Array.prototype[7]);
199
200     // Note that slice copies values from prototype into the array.
201     assertEquals(array[3], undefined);
202     assertFalse(array.hasOwnProperty(3));
203     assertEquals(sliced[3], at3);
204     assertTrue(sliced.hasOwnProperty(3));
205
206     assertEquals(array[7], undefined);
207     assertFalse(array.hasOwnProperty(7));
208     assertEquals(sliced[7], at7);
209     assertTrue(sliced.hasOwnProperty(7));
210
211     // ... but keeps the rest as holes:
212     Array.prototype[5] = "@5";
213     assertEquals(array[5], Array.prototype[5]);
214     assertFalse(array.hasOwnProperty(5));
215     assertEquals(sliced[5], Array.prototype[5]);
216     assertFalse(sliced.hasOwnProperty(5));
217
218     assertTrue(delete Array.prototype[5]);
219   }
220 })();
221
222 // Check slicing on arguments object.
223 (function() {
224   function func(expected, a0, a1, a2) {
225     assertEquals(expected, Array.prototype.slice.call(arguments, 1));
226   }
227
228   func([]);
229   func(['a'], 'a');
230   func(['a', 1], 'a', 1);
231   func(['a', 1, undefined], 'a', 1, undefined);
232   func(['a', 1, undefined, void(0)], 'a', 1, undefined, void(0));
233 })();
234
235 // Check slicing on arguments object when missing arguments get assigined.
236 (function() {
237   function func(x, y) {
238     assertEquals(1, arguments.length);
239     assertEquals(undefined, y);
240     y = 239;
241     assertEquals(1, arguments.length);  // arguments length is the same.
242     assertEquals([x], Array.prototype.slice.call(arguments, 0));
243   }
244
245   func('a');
246 })();
247
248 // Check slicing on arguments object when length property has been set.
249 (function() {
250   function func(x, y) {
251     assertEquals(1, arguments.length);
252     arguments.length = 7;
253     assertEquals([x,,,,,,,], Array.prototype.slice.call(arguments, 0));
254   }
255
256   func('a');
257 })();
258
259 // Check slicing on arguments object when length property has been set to
260 // some strange value.
261 (function() {
262   function func(x, y) {
263     assertEquals(1, arguments.length);
264     arguments.length = 'foobar';
265     assertEquals([], Array.prototype.slice.call(arguments, 0));
266   }
267
268   func('a');
269 })();
270
271 // Check slicing on arguments object when extra argument has been added
272 // via indexed assignment.
273 (function() {
274   function func(x, y) {
275     assertEquals(1, arguments.length);
276     arguments[3] = 239;
277     assertEquals([x], Array.prototype.slice.call(arguments, 0));
278   }
279
280   func('a');
281 })();
282
283 // Check slicing on arguments object when argument has been deleted by index.
284 (function() {
285   function func(x, y, z) {
286     assertEquals(3, arguments.length);
287     delete arguments[1];
288     assertEquals([x,,z], Array.prototype.slice.call(arguments, 0));
289   }
290
291   func('a', 'b', 'c');
292 })();
293
294 // Check slicing of holey objects with elements in the prototype
295 (function() {
296   function f() {
297     delete arguments[1];
298     arguments.__proto__[1] = 5;
299     var result = Array.prototype.slice.call(arguments);
300     delete arguments.__proto__[1];
301     assertEquals([1,5,3], result);
302   }
303   f(1,2,3);
304 })();