1// Copyright 2008 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// Tests for non-standard array iteration functions.
29//
30// See
31//
32// <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array>
33//
34// for an explanation of each of the functions.
35
36//
37// Array.prototype.filter
38//
39(function() {
40  // Simple use.
41  var a = [0,1];
42  assertArrayEquals([0], a.filter(function(n) { return n == 0; }));
43  assertArrayEquals([0,1], a);
44
45  // Use specified object as this object when calling the function.
46  var o = { value: 42 }
47  a = [1,42,3,42,4];
48  assertArrayEquals([42,42],
49      a.filter(function(n) { return this.value == n }, o))
50
51  // Modify original array.
52  a = [1,42,3,42,4];
53  assertArrayEquals([42,42],
54      a.filter(function(n, index, array) {
55          array[index] = 43; return 42 == n;
56      }));
57  assertArrayEquals([43,43,43,43,43], a);
58
59  // Only loop through initial part of array eventhough elements are
60  // added.
61  a = [1,1];
62  assertArrayEquals([],
63      a.filter(function(n, index, array) { array.push(n+1); return n == 2; }));
64  assertArrayEquals([1,1,2,2], a);
65
66  // Respect holes.
67  a = new Array(20);
68  var count = 0;
69  a[2] = 2;
70  a[15] = 2;
71  a[17] = 4;
72  var a = a.filter(function(n) { count++; return n == 2; });
73  assertEquals(3, count);
74  for (var i in a) assertEquals(2, a[i]);
75
76  // Create a new object in each function call when receiver is a
77  // primitive value. See ECMA-262, Annex C.
78  a = [];
79  [1, 2].filter(function() { a.push(this) }, "");
80  assertTrue(a[0] !== a[1]);
81
82  // Do not create a new object otherwise.
83  a = [];
84  [1, 2].filter(function() { a.push(this) }, {});
85  assertEquals(a[0], a[1]);
86
87  // In strict mode primitive values should not be coerced to an object.
88  a = [];
89  [1, 2].filter(function() { 'use strict'; a.push(this); }, "");
90  assertEquals("", a[0]);
91  assertEquals(a[0], a[1]);
92
93})();
94
95
96//
97// Array.prototype.forEach
98//
99(function() {
100  // Simple use.
101  var a = [0,1];
102  var count = 0;
103  a.forEach(function(n) { count++; });
104  assertEquals(2, count);
105
106  // Use specified object as this object when calling the function.
107  var o = { value: 42 }
108  var result = [];
109  a.forEach(function(n) { result.push(this.value); }, o);
110  assertArrayEquals([42,42], result);
111
112  // Modify original array.
113  a = [0,1];
114  count = 0;
115  a.forEach(function(n, index, array) { array[index] = n + 1; count++; });
116  assertEquals(2, count);
117  assertArrayEquals([1,2], a);
118
119  // Only loop through initial part of array eventhough elements are
120  // added.
121  a = [1,1];
122  count = 0;
123  a.forEach(function(n, index, array) { array.push(n+1); count++; });
124  assertEquals(2, count);
125  assertArrayEquals([1,1,2,2], a);
126
127  // Respect holes.
128  a = new Array(20);
129  count = 0;
130  a[15] = 2;
131  a.forEach(function(n) { count++; });
132  assertEquals(1, count);
133
134  // Create a new object in each function call when receiver is a
135  // primitive value. See ECMA-262, Annex C.
136  a = [];
137  [1, 2].forEach(function() { a.push(this) }, "");
138  assertTrue(a[0] !== a[1]);
139
140  // Do not create a new object otherwise.
141  a = [];
142  [1, 2].forEach(function() { a.push(this) }, {});
143  assertEquals(a[0], a[1]);
144
145  // In strict mode primitive values should not be coerced to an object.
146  a = [];
147  [1, 2].forEach(function() { 'use strict'; a.push(this); }, "");
148  assertEquals("", a[0]);
149  assertEquals(a[0], a[1]);
150
151})();
152
153
154//
155// Array.prototype.every
156//
157(function() {
158  // Simple use.
159  var a = [0,1];
160  assertFalse(a.every(function(n) { return n == 0 }));
161  a = [0,0];
162  assertTrue(a.every(function(n) { return n == 0 }));
163  assertTrue([].every(function(n) { return n == 0}));
164
165  // Use specified object as this object when calling the function.
166  var o = { value: 42 }
167  a = [0];
168  assertFalse(a.every(function(n) { return this.value == n; }, o));
169  a = [42];
170  assertTrue(a.every(function(n) { return this.value == n; }, o));
171
172  // Modify original array.
173  a = [0,1];
174  assertFalse(
175      a.every(function(n, index, array) {
176        array[index] = n + 1; return n == 1;
177      }));
178  assertArrayEquals([1,1], a);
179
180  // Only loop through initial part of array eventhough elements are
181  // added.
182  a = [1,1];
183  assertTrue(
184      a.every(function(n, index, array) {
185        array.push(n + 1); return n == 1;
186      }));
187  assertArrayEquals([1,1,2,2], a);
188
189  // Respect holes.
190  a = new Array(20);
191  var count = 0;
192  a[2] = 2;
193  a[15] = 2;
194  assertTrue(a.every(function(n) { count++; return n == 2; }));
195  assertEquals(2, count);
196
197  // Create a new object in each function call when receiver is a
198  // primitive value. See ECMA-262, Annex C.
199  a = [];
200  [1, 2].every(function() { a.push(this); return true; }, "");
201  assertTrue(a[0] !== a[1]);
202
203  // Do not create a new object otherwise.
204  a = [];
205  [1, 2].every(function() { a.push(this); return true; }, {});
206  assertEquals(a[0], a[1]);
207
208  // In strict mode primitive values should not be coerced to an object.
209  a = [];
210  [1, 2].every(function() { 'use strict'; a.push(this); return true; }, "");
211  assertEquals("", a[0]);
212  assertEquals(a[0], a[1]);
213
214})();
215
216//
217// Array.prototype.map
218//
219(function() {
220  var a = [0,1,2,3,4];
221
222  // Simple use.
223  var result = [1,2,3,4,5];
224  assertArrayEquals(result, a.map(function(n) { return n + 1; }));
225  assertEquals(a, a);
226
227  // Use specified object as this object when calling the function.
228  var o = { delta: 42 }
229  result = [42,43,44,45,46];
230  assertArrayEquals(result, a.map(function(n) { return this.delta + n; }, o));
231
232  // Modify original array.
233  a = [0,1,2,3,4];
234  result = [1,2,3,4,5];
235  assertArrayEquals(result,
236      a.map(function(n, index, array) {
237        array[index] = n + 1; return n + 1;
238      }));
239  assertArrayEquals(result, a);
240
241  // Only loop through initial part of array eventhough elements are
242  // added.
243  a = [0,1,2,3,4];
244  result = [1,2,3,4,5];
245  assertArrayEquals(result,
246      a.map(function(n, index, array) { array.push(n); return n + 1; }));
247  assertArrayEquals([0,1,2,3,4,0,1,2,3,4], a);
248
249  // Respect holes.
250  a = new Array(20);
251  a[15] = 2;
252  a = a.map(function(n) { return 2*n; });
253  for (var i in a) assertEquals(4, a[i]);
254
255  // Create a new object in each function call when receiver is a
256  // primitive value. See ECMA-262, Annex C.
257  a = [];
258  [1, 2].map(function() { a.push(this) }, "");
259  assertTrue(a[0] !== a[1]);
260
261  // Do not create a new object otherwise.
262  a = [];
263  [1, 2].map(function() { a.push(this) }, {});
264  assertEquals(a[0], a[1]);
265
266  // In strict mode primitive values should not be coerced to an object.
267  a = [];
268  [1, 2].map(function() { 'use strict'; a.push(this); }, "");
269  assertEquals("", a[0]);
270  assertEquals(a[0], a[1]);
271
272})();
273
274//
275// Array.prototype.some
276//
277(function() {
278  var a = [0,1,2,3,4];
279
280  // Simple use.
281  assertTrue(a.some(function(n) { return n == 3}));
282  assertFalse(a.some(function(n) { return n == 5}));
283
284  // Use specified object as this object when calling the function.
285  var o = { element: 42 };
286  a = [1,42,3];
287  assertTrue(a.some(function(n) { return this.element == n; }, o));
288  a = [1];
289  assertFalse(a.some(function(n) { return this.element == n; }, o));
290
291  // Modify original array.
292  a = [0,1,2,3];
293  assertTrue(
294      a.some(function(n, index, array) {
295        array[index] = n + 1; return n == 2; }));
296  assertArrayEquals([1,2,3,3], a);
297
298  // Only loop through initial part when elements are added.
299  a = [0,1,2];
300  assertFalse(
301      a.some(function(n, index, array) { array.push(42); return n == 42; }));
302  assertArrayEquals([0,1,2,42,42,42], a);
303
304  // Respect holes.
305  a = new Array(20);
306  var count = 0;
307  a[2] = 42;
308  a[10] = 2;
309  a[15] = 42;
310  assertTrue(a.some(function(n) { count++; return n == 2; }));
311  assertEquals(2, count);
312
313  // Create a new object in each function call when receiver is a
314  // primitive value. See ECMA-262, Annex C.
315  a = [];
316  [1, 2].some(function() { a.push(this) }, "");
317  assertTrue(a[0] !== a[1]);
318
319  // Do not create a new object otherwise.
320  a = [];
321  [1, 2].some(function() { a.push(this) }, {});
322  assertEquals(a[0], a[1]);
323
324  // In strict mode primitive values should not be coerced to an object.
325  a = [];
326  [1, 2].some(function() { 'use strict'; a.push(this); }, "");
327  assertEquals("", a[0]);
328  assertEquals(a[0], a[1]);
329
330})();
331