Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: test/mjsunit/array-reduce.js

Issue 88022: Add Array.prototype.reduce and .reduceRight. (Closed)
Patch Set: Created 11 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2009 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 /**
29 * @fileoverview Test reduce and reduceRight
Christian Plesner Hansen 2009/04/21 09:39:17 This is an excellent test!
30 */
31
32 function clone(v) {
33 // Shallow-copies arrays, returns everything else verbatim.
34 if (v instanceof Array) {
35 // Shallow-copy an array.
36 var newArray = new Array(v.length);
37 for (var i in v) {
38 newArray[i] = v[i];
39 }
40 return newArray;
41 }
42 return v;
43 }
44
45
46 // Creates a callback function for reduce/reduceRight that tests the number
47 // of arguments and otherwise behaves as "func", but which also
48 // records all calls in an array on the function (as arrays of arguments
49 // followed by result).
50 function makeRecorder(func, testName) {
51 var record = [];
52 var f = function recorder(a, b, i, s) {
53 assertEquals(4, arguments.length,
54 testName + "(number of arguments: " + arguments.length + ")");
55 assertEquals("number", typeof(i), testName + "(index must be number)");
56 assertEquals(s[i], b, testName + "(current argument is at index)");
57 if (record.length > 0) {
58 var prevRecord = record[record.length - 1];
59 var prevResult = prevRecord[prevRecord.length - 1];
60 assertEquals(prevResult, a,
61 testName + "(prev result -> current input)");
62 }
63 var args = [clone(a), clone(b), i, clone(s)];
64 var result = func.apply(this, arguments);
65 args.push(clone(result));
66 record.push(args);
67 return result;
68 };
69 f.record = record;
70 return f;
71 }
72
73
74 function testReduce(type,
75 testName,
76 expectedResult,
77 expectedCalls,
78 array,
79 combine,
80 init) {
81 var rec = makeRecorder(combine);
82 var result;
83 var performsCall;
84 if (arguments.length > 6) {
85 result = array[type](rec, init);
86 } else {
87 result = array[type](rec);
88 }
89 var calls = rec.record;
90 assertEquals(expectedCalls.length, calls.length,
91 testName + " (number of calls)");
92 for (var i = 0; i < expectedCalls.length; i++) {
93 assertEquals(expectedCalls[i], calls[i],
94 testName + " (call " + (i + 1) + ")");
95 }
96 assertEquals(expectedResult, result, testName + " (result)");
97 }
98
99
100 function sum(a, b) { return a + b; }
101 function prod(a, b) { return a * b; }
102 function dec(a, b, i, arr) { return a + b * Math.pow(10, arr.length - i - 1); }
103 function accumulate(acc, elem, i) { acc[i] = elem; return acc; }
104
105 // ---- Test Reduce[Left]
106
107 var simpleArray = [2,4,6]
108
109 testReduce("reduce", "SimpleReduceSum", 12,
110 [[0, 2, 0, simpleArray, 2],
111 [2, 4, 1, simpleArray, 6],
112 [6, 6, 2, simpleArray, 12]],
113 simpleArray, sum, 0);
114
115 testReduce("reduce", "SimpleReduceProd", 48,
116 [[1, 2, 0, simpleArray, 2],
117 [2, 4, 1, simpleArray, 8],
118 [8, 6, 2, simpleArray, 48]],
119 simpleArray, prod, 1);
120
121 testReduce("reduce", "SimpleReduceDec", 246,
122 [[0, 2, 0, simpleArray, 200],
123 [200, 4, 1, simpleArray, 240],
124 [240, 6, 2, simpleArray, 246]],
125 simpleArray, dec, 0);
126
127 testReduce("reduce", "SimpleReduceAccumulate", simpleArray,
128 [[[], 2, 0, simpleArray, [2]],
129 [[2], 4, 1, simpleArray, [2, 4]],
130 [[2,4], 6, 2, simpleArray, simpleArray]],
131 simpleArray, accumulate, []);
132
133
134 testReduce("reduce", "EmptyReduceSum", 0, [], [], sum, 0);
135 testReduce("reduce", "EmptyReduceProd", 1, [], [], prod, 1);
136 testReduce("reduce", "EmptyReduceDec", 0, [], [], dec, 0);
137 testReduce("reduce", "EmptyReduceAccumulate", [], [], [], accumulate, []);
138
139 testReduce("reduce", "EmptyReduceSumNoInit", 0, [], [0], sum);
140 testReduce("reduce", "EmptyReduceProdNoInit", 1, [], [1], prod);
141 testReduce("reduce", "EmptyReduceDecNoInit", 0, [], [0], dec);
142 testReduce("reduce", "EmptyReduceAccumulateNoInit", [], [], [[]], accumulate);
143
144
145 var simpleSparseArray = [,,,2,,4,,6,,];
146 testReduce("reduce", "SimpleSparseReduceSum", 12,
147 [[0, 2, 3, simpleSparseArray, 2],
148 [2, 4, 5, simpleSparseArray, 6],
149 [6, 6, 7, simpleSparseArray, 12]],
150 simpleSparseArray, sum, 0);
151
152 testReduce("reduce", "SimpleSparseReduceProd", 48,
153 [[1, 2, 3, simpleSparseArray, 2],
154 [2, 4, 5, simpleSparseArray, 8],
155 [8, 6, 7, simpleSparseArray, 48]],
156 simpleSparseArray, prod, 1);
157
158 testReduce("reduce", "SimpleSparseReduceDec", 204060,
159 [[0, 2, 3, simpleSparseArray, 200000],
160 [200000, 4, 5, simpleSparseArray, 204000],
161 [204000, 6, 7, simpleSparseArray, 204060]],
162 simpleSparseArray, dec, 0);
163
164 testReduce("reduce", "SimpleSparseReduceAccumulate", [,,,2,,4,,6],
165 [[[], 2, 3, simpleSparseArray, [,,,2]],
166 [[,,,2], 4, 5, simpleSparseArray, [,,,2,,4]],
167 [[,,,2,,4], 6, 7, simpleSparseArray, [,,,2,,4,,6]]],
168 simpleSparseArray, accumulate, []);
169
170
171 testReduce("reduce", "EmptySparseReduceSumNoInit", 0, [], [,,0,,], sum);
172 testReduce("reduce", "EmptySparseReduceProdNoInit", 1, [], [,,1,,], prod);
173 testReduce("reduce", "EmptySparseReduceDecNoInit", 0, [], [,,0,,], dec);
174 testReduce("reduce", "EmptySparseReduceAccumulateNoInit",
175 [], [], [,,[],,], accumulate);
176
177
178 var verySparseArray = new Array(500000);
179 verySparseArray[100000] = 2;
180 verySparseArray[250000] = 4;
181 verySparseArray[450000] = 6;
182 var verySparseSlice2 = verySparseArray.slice(0, 100001);
183 var verySparseSlice4 = verySparseArray.slice(0, 250001);
184 var verySparseSlice6 = verySparseArray.slice(0, 450001);
185
186 testReduce("reduce", "VerySparseReduceSum", 12,
187 [[0, 2, 100000, verySparseArray, 2],
188 [2, 4, 250000, verySparseArray, 6],
189 [6, 6, 450000, verySparseArray, 12]],
190 verySparseArray, sum, 0);
191
192 testReduce("reduce", "VerySparseReduceProd", 48,
193 [[1, 2, 100000, verySparseArray, 2],
194 [2, 4, 250000, verySparseArray, 8],
195 [8, 6, 450000, verySparseArray, 48]],
196 verySparseArray, prod, 1);
197
198 testReduce("reduce", "VerySparseReduceDec", Infinity,
199 [[0, 2, 100000, verySparseArray, Infinity],
200 [Infinity, 4, 250000, verySparseArray, Infinity],
201 [Infinity, 6, 450000, verySparseArray, Infinity]],
202 verySparseArray, dec, 0);
203
204 testReduce("reduce", "SimpleSparseReduceAccumulate",
205 verySparseSlice6,
206 [[[], 2, 100000, verySparseArray, verySparseSlice2],
207 [verySparseSlice2, 4, 250000, verySparseArray, verySparseSlice4],
208 [verySparseSlice4, 6, 450000, verySparseArray, verySparseSlice6]],
209 verySparseArray, accumulate, []);
210
211
212 testReduce("reduce", "VerySparseReduceSumNoInit", 12,
213 [[2, 4, 250000, verySparseArray, 6],
214 [6, 6, 450000, verySparseArray, 12]],
215 verySparseArray, sum);
216
217 testReduce("reduce", "VerySparseReduceProdNoInit", 48,
218 [[2, 4, 250000, verySparseArray, 8],
219 [8, 6, 450000, verySparseArray, 48]],
220 verySparseArray, prod);
221
222 testReduce("reduce", "VerySparseReduceDecNoInit", Infinity,
223 [[2, 4, 250000, verySparseArray, Infinity],
224 [Infinity, 6, 450000, verySparseArray, Infinity]],
225 verySparseArray, dec);
226
227 testReduce("reduce", "SimpleSparseReduceAccumulateNoInit",
228 2,
229 [[2, 4, 250000, verySparseArray, 2],
230 [2, 6, 450000, verySparseArray, 2]],
231 verySparseArray, accumulate);
232
233
234 // ---- Test ReduceRight
235
236 testReduce("reduceRight", "SimpleReduceRightSum", 12,
237 [[0, 6, 2, simpleArray, 6],
238 [6, 4, 1, simpleArray, 10],
239 [10, 2, 0, simpleArray, 12]],
240 simpleArray, sum, 0);
241
242 testReduce("reduceRight", "SimpleReduceRightProd", 48,
243 [[1, 6, 2, simpleArray, 6],
244 [6, 4, 1, simpleArray, 24],
245 [24, 2, 0, simpleArray, 48]],
246 simpleArray, prod, 1);
247
248 testReduce("reduceRight", "SimpleReduceRightDec", 246,
249 [[0, 6, 2, simpleArray, 6],
250 [6, 4, 1, simpleArray, 46],
251 [46, 2, 0, simpleArray, 246]],
252 simpleArray, dec, 0);
253
254 testReduce("reduceRight", "SimpleReduceRightAccumulate", simpleArray,
255 [[[], 6, 2, simpleArray, [,,6]],
256 [[,,6], 4, 1, simpleArray, [,4,6]],
257 [[,4,6], 2, 0, simpleArray, simpleArray]],
258 simpleArray, accumulate, []);
259
260
261 testReduce("reduceRight", "EmptyReduceRightSum", 0, [], [], sum, 0);
262 testReduce("reduceRight", "EmptyReduceRightProd", 1, [], [], prod, 1);
263 testReduce("reduceRight", "EmptyReduceRightDec", 0, [], [], dec, 0);
264 testReduce("reduceRight", "EmptyReduceRightAccumulate", [],
265 [], [], accumulate, []);
266
267 testReduce("reduceRight", "EmptyReduceRightSumNoInit", 0, [], [0], sum);
268 testReduce("reduceRight", "EmptyReduceRightProdNoInit", 1, [], [1], prod);
269 testReduce("reduceRight", "EmptyReduceRightDecNoInit", 0, [], [0], dec);
270 testReduce("reduceRight", "EmptyReduceRightAccumulateNoInit",
271 [], [], [[]], accumulate);
272
273
274 testReduce("reduceRight", "SimpleSparseReduceRightSum", 12,
275 [[0, 6, 7, simpleSparseArray, 6],
276 [6, 4, 5, simpleSparseArray, 10],
277 [10, 2, 3, simpleSparseArray, 12]],
278 simpleSparseArray, sum, 0);
279
280 testReduce("reduceRight", "SimpleSparseReduceRightProd", 48,
281 [[1, 6, 7, simpleSparseArray, 6],
282 [6, 4, 5, simpleSparseArray, 24],
283 [24, 2, 3, simpleSparseArray, 48]],
284 simpleSparseArray, prod, 1);
285
286 testReduce("reduceRight", "SimpleSparseReduceRightDec", 204060,
287 [[0, 6, 7, simpleSparseArray, 60],
288 [60, 4, 5, simpleSparseArray, 4060],
289 [4060, 2, 3, simpleSparseArray, 204060]],
290 simpleSparseArray, dec, 0);
291
292 testReduce("reduceRight", "SimpleSparseReduceRightAccumulate", [,,,2,,4,,6],
293 [[[], 6, 7, simpleSparseArray, [,,,,,,,6]],
294 [[,,,,,,,6], 4, 5, simpleSparseArray, [,,,,,4,,6]],
295 [[,,,,,4,,6], 2, 3, simpleSparseArray, [,,,2,,4,,6]]],
296 simpleSparseArray, accumulate, []);
297
298
299 testReduce("reduceRight", "EmptySparseReduceRightSumNoInit",
300 0, [], [,,0,,], sum);
301 testReduce("reduceRight", "EmptySparseReduceRightProdNoInit",
302 1, [], [,,1,,], prod);
303 testReduce("reduceRight", "EmptySparseReduceRightDecNoInit",
304 0, [], [,,0,,], dec);
305 testReduce("reduceRight", "EmptySparseReduceRightAccumulateNoInit",
306 [], [], [,,[],,], accumulate);
307
308
309 var verySparseSuffix6 = new Array(450001);
310 verySparseSuffix6[450000] = 6;
311 var verySparseSuffix4 = new Array(450001);
312 verySparseSuffix4[250000] = 4;
313 verySparseSuffix4[450000] = 6;
314 var verySparseSuffix2 = verySparseSlice6;
315
316
317 testReduce("reduceRight", "VerySparseReduceRightSum", 12,
318 [[0, 6, 450000, verySparseArray, 6],
319 [6, 4, 250000, verySparseArray, 10],
320 [10, 2, 100000, verySparseArray, 12]],
321 verySparseArray, sum, 0);
322
323 testReduce("reduceRight", "VerySparseReduceRightProd", 48,
324 [[1, 6, 450000, verySparseArray, 6],
325 [6, 4, 250000, verySparseArray, 24],
326 [24, 2, 100000, verySparseArray, 48]],
327 verySparseArray, prod, 1);
328
329 testReduce("reduceRight", "VerySparseReduceRightDec", Infinity,
330 [[0, 6, 450000, verySparseArray, Infinity],
331 [Infinity, 4, 250000, verySparseArray, Infinity],
332 [Infinity, 2, 100000, verySparseArray, Infinity]],
333 verySparseArray, dec, 0);
334
335 testReduce("reduceRight", "SimpleSparseReduceRightAccumulate",
336 verySparseSuffix2,
337 [[[], 6, 450000, verySparseArray, verySparseSuffix6],
338 [verySparseSuffix6, 4, 250000, verySparseArray, verySparseSuffix4],
339 [verySparseSuffix4, 2, 100000, verySparseArray, verySparseSuffix2]],
340 verySparseArray, accumulate, []);
341
342
343 testReduce("reduceRight", "VerySparseReduceRightSumNoInit", 12,
344 [[6, 4, 250000, verySparseArray, 10],
345 [10, 2, 100000, verySparseArray, 12]],
346 verySparseArray, sum);
347
348 testReduce("reduceRight", "VerySparseReduceRightProdNoInit", 48,
349 [[6, 4, 250000, verySparseArray, 24],
350 [24, 2, 100000, verySparseArray, 48]],
351 verySparseArray, prod);
352
353 testReduce("reduceRight", "VerySparseReduceRightDecNoInit", Infinity,
354 [[6, 4, 250000, verySparseArray, Infinity],
355 [Infinity, 2, 100000, verySparseArray, Infinity]],
356 verySparseArray, dec);
357
358 testReduce("reduceRight", "SimpleSparseReduceRightAccumulateNoInit",
359 6,
360 [[6, 4, 250000, verySparseArray, 6],
361 [6, 2, 100000, verySparseArray, 6]],
362 verySparseArray, accumulate);
363
364
365 // undefined is an element
366 var undefArray = [,,undefined,,undefined,,];
367
368 testReduce("reduce", "SparseUndefinedReduceAdd", NaN,
369 [[0, undefined, 2, undefArray, NaN],
370 [NaN, undefined, 4, undefArray, NaN],
371 ],
372 undefArray, sum, 0);
373
374 testReduce("reduceRight", "SparseUndefinedReduceRightAdd", NaN,
375 [[0, undefined, 4, undefArray, NaN],
376 [NaN, undefined, 2, undefArray, NaN],
377 ], undefArray, sum, 0);
378
379 testReduce("reduce", "SparseUndefinedReduceAddNoInit", NaN,
380 [[undefined, undefined, 4, undefArray, NaN],
381 ], undefArray, sum);
382
383 testReduce("reduceRight", "SparseUndefinedReduceRightAddNoInit", NaN,
384 [[undefined, undefined, 2, undefArray, NaN],
385 ], undefArray, sum);
386
387
388 // Test error conditions
389
390 try {
391 [1].reduce("not a function");
392 fail("Reduce callback not a function not throwing");
393 } catch (e) {
394 assertTrue(e instanceof TypeError,
395 "reduce callback not a function not throwing TypeError");
396 assertEquals("called_non_callable", e.type,
397 "reduce non function TypeError type");
398 }
399
400 try {
401 [1].reduceRight("not a function");
402 fail("ReduceRight callback not a function not throwing");
403 } catch (e) {
404 assertTrue(e instanceof TypeError,
405 "reduceRight callback not a function not throwing TypeError");
406 assertEquals("called_non_callable", e.type,
407 "reduceRight non function TypeError type");
408 }
409
410
411 try {
412 [].reduce(sum);
413 fail("Reduce no initial value not throwing");
414 } catch (e) {
415 assertTrue(e instanceof TypeError,
416 "reduce no initial value not throwing TypeError");
417 assertEquals("reduce_no_initial", e.type,
418 "reduce no initial TypeError type");
419 }
420
421 try {
422 [].reduceRight(sum);
423 fail("ReduceRight no initial value not throwing");
424 } catch (e) {
425 assertTrue(e instanceof TypeError,
426 "reduceRight no initial value not throwing TypeError");
427 assertEquals("reduce_no_initial", e.type,
428 "reduceRight no initial TypeError type");
429 }
430
431 try {
432 [,,,].reduce(sum);
433 fail("Reduce sparse no initial value not throwing");
434 } catch (e) {
435 assertTrue(e instanceof TypeError,
436 "reduce sparse no initial value not throwing TypeError");
437 assertEquals("reduce_no_initial", e.type,
438 "reduce no initial TypeError type");
439
440 }
441
442 try {
443 [,,,].reduceRight(sum);
444 fail("ReduceRight sparse no initial value not throwing");
445 } catch (e) {
446 assertTrue(e instanceof TypeError,
447 "reduceRight sparse no initial value not throwing TypeError");
448 assertEquals("reduce_no_initial", e.type,
449 "reduceRight no initial TypeError type");
450 }
451
452
453 // Array changing length
454
455 function manipulator(a, b, i, s) {
456 if (s.length % 2) {
457 s[s.length * 3] = i;
458 } else {
459 s.length = s.length >> 1;
460 }
461 return a + b;
462 }
463
464 var arr = [1, 2, 3, 4];
465 testReduce("reduce", "ArrayManipulationShort", 3,
466 [[0, 1, 0, [1, 2, 3, 4], 1],
467 [1, 2, 1, [1, 2], 3],
468 ], arr, manipulator, 0);
469
470 var arr = [1, 2, 3, 4, 5];
471 testReduce("reduce", "ArrayManipulationLonger", 10,
472 [[0, 1, 0, [1, 2, 3, 4, 5], 1],
473 [1, 2, 1, [1, 2, 3, 4, 5,,,,,,,,,,, 0], 3],
474 [3, 3, 2, [1, 2, 3, 4, 5,,,,], 6],
475 [6, 4, 3, [1, 2, 3, 4], 10],
476 ], arr, manipulator, 0);
477
478 function extender(a, b, i, s) {
479 s[s.length] = s.length;
480 return a + b;
481 }
482
483 var arr = [1, 2, 3, 4];
484 testReduce("reduce", "ArrayManipulationExtender", 10,
485 [[0, 1, 0, [1, 2, 3, 4], 1],
486 [1, 2, 1, [1, 2, 3, 4, 4], 3],
487 [3, 3, 2, [1, 2, 3, 4, 4, 5], 6],
488 [6, 4, 3, [1, 2, 3, 4, 4, 5, 6], 10],
489 ], arr, extender, 0);
490
OLDNEW
« src/array.js ('K') | « src/messages.js ('k') | test/mjsunit/mjsunit.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698