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

Side by Side Diff: test/mjsunit/harmony/typedarrays-reduce.js

Issue 769993002: Implement .reduce() and .reduceRight() on typed arrays Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 years 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
« no previous file with comments | « src/harmony-typedarray.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Flags: --harmony-arrays --allow-natives-syntax
6
7 var typedArrayConstructors = [
8 Uint8Array,
9 Int8Array,
10 Uint16Array,
11 Int16Array,
12 Uint32Array,
13 Int32Array,
14 Uint8ClampedArray,
15 Float32Array,
16 Float64Array];
17
18 function CheckTypedArrayIsNeutered(array) {
19 assertEquals(0, array.byteLength);
20 assertEquals(0, array.byteOffset);
21 assertEquals(0, array.length);
22 }
23
24 function CheckSuperficialFunctionFeatures(obj, funcname) {
25 assertEquals(1, obj[funcname].length);
26 var desc = Object.getOwnPropertyDescriptor(obj, funcname);
27 assertEquals(false, desc.configurable);
28 assertEquals(false, desc.enumerable);
29 assertEquals(false, desc.writable);
30 }
31
32 // The following helpe functions are taken from mjsunit/array-reduce.js
33
34 function clone(v) {
35 // Shallow-copies arrays, returns everything else verbatim.
36 if (v instanceof Array) {
37 // Shallow-copy an array.
38 var newArray = new Array(v.length);
39 for (var i in v) {
40 newArray[i] = v[i];
41 }
42 return newArray;
43 }
44 return v;
45 }
46
47 // Creates a callback function for reduce/reduceRight that tests the number
48 // of arguments and otherwise behaves as "func", but which also
49 // records all calls in an array on the function (as arrays of arguments
50 // followed by result).
51 function makeRecorder(func, testName) {
52 var record = [];
53 var f = function recorder(a, b, i, s) {
54 assertEquals(4, arguments.length, testName + "(number of arguments: " + argu ments.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, testName + "(prev result -> current input)");
61 }
62 var args = [clone(a), clone(b), i, clone(s)];
63 var result = func.apply(this, arguments);
64 args.push(clone(result));
65 record.push(args);
66 return result;
67 };
68 f.record = record;
69 return f;
70 }
71
72 function testReduce(type,
73 testName,
74 expectedResult,
75 expectedCalls,
76 array,
77 combine,
78 init)
79 {
80 var rec = makeRecorder(combine, testName);
81 var result;
82 var performsCall;
83 if (arguments.length > 6) {
84 result = array[type](rec, init);
85 } else {
86 result = array[type](rec);
87 }
88 var calls = rec.record;
89 assertEquals(expectedCalls.length, calls.length,
90 testName + " (number of calls)");
91 for (var i = 0; i < expectedCalls.length; i++) {
92 assertEquals(expectedCalls[i], calls[i],
93 testName + " (call " + (i + 1) + ")");
94 }
95 assertEquals(expectedResult, result, testName + " (result)");
96 }
97
98 function sum(a, b) { return a + b; }
99 function prod(a, b) { return a * b; }
100 function dec(a, b, i, arr) { return a + b * Math.pow(10, arr.length - i - 1); }
101 function accumulate(acc, elem, i) { acc[i] = elem; return acc; }
102
103
104 function TestTypedArrayReduce(constructor) {
105 CheckSuperficialFunctionFeatures(constructor.prototype, "reduce");
106 CheckSuperficialFunctionFeatures(constructor.prototype, "reduceRight");
107
108 var a = constructor.of(2, 4, 6);
109
110 // .reduce()
111 testReduce("reduce", "SimpleReduceSum", 12,
112 [[0, 2, 0, a, 2],
113 [2, 4, 1, a, 6],
114 [6, 6, 2, a, 12]],
115 a, sum, 0);
116
117 testReduce("reduce", "SimpleReduceProd", 48,
118 [[1, 2, 0, a, 2],
119 [2, 4, 1, a, 8],
120 [8, 6, 2, a, 48]],
121 a, prod, 1);
122
123 testReduce("reduce", "SimpleReduceDec", 246,
124 [[0, 2, 0, a, 200],
125 [200, 4, 1, a, 240],
126 [240, 6, 2, a, 246]],
127 a, dec, 0);
128
129 testReduce("reduce", "SimpleReduceAccumulate", [2,4,6],
130 [[[], 2, 0, a, [2]],
131 [[2], 4, 1, a, [2,4]],
132 [[2,4], 6, 2, a, [2,4,6]]],
133 a, accumulate, []);
134
135 testReduce("reduce", "EmptyReduceSum", 0, [], [], sum, 0);
136 testReduce("reduce", "EmptyReduceProd", 1, [], [], prod, 1);
137 testReduce("reduce", "EmptyReduceDec", 0, [], [], dec, 0);
138 testReduce("reduce", "EmptyReduceAccumulate", [], [], [], accumulate, []);
139
140 testReduce("reduce", "EmptyReduceSumNoInit", 0, [], [0], sum);
141 testReduce("reduce", "EmptyReduceProdNoInit", 1, [], [1], prod);
142 testReduce("reduce", "EmptyReduceDecNoInit", 0, [], [0], dec);
143 testReduce("reduce", "EmptyReduceAccumulateNoInit", [], [], [[]], accumulate);
144
145 // .reduceRight()
146 testReduce("reduceRight", "SimpleReduceRightSum", 12,
147 [[0, 6, 2, a, 6],
148 [6, 4, 1, a, 10],
149 [10, 2, 0, a, 12]],
150 a, sum, 0);
151
152 testReduce("reduceRight", "SimpleReduceRightProd", 48,
153 [[1, 6, 2, a, 6],
154 [6, 4, 1, a, 24],
155 [24, 2, 0, a, 48]],
156 a, prod, 1);
157
158 testReduce("reduceRight", "SimpleReduceRightDec", 246,
159 [[0, 6, 2, a, 6],
160 [6, 4, 1, a, 46],
161 [46, 2, 0, a, 246]],
162 a, dec, 0);
163
164 testReduce("reduceRight", "SimpleReduceRightAccumulate", [2, 4, 6],
165 [[[], 6, 2, a, [,,6]],
166 [[,,6], 4, 1, a, [,4,6]],
167 [[,4,6], 2, 0, a, [2,4,6]]],
168 a, accumulate, []);
169
170
171 testReduce("reduceRight", "EmptyReduceRightSum", 0, [], [], sum, 0);
172 testReduce("reduceRight", "EmptyReduceRightProd", 1, [], [], prod, 1);
173 testReduce("reduceRight", "EmptyReduceRightDec", 0, [], [], dec, 0);
174 testReduce("reduceRight", "EmptyReduceRightAccumulate", [],
175 [], [], accumulate, []);
176
177 testReduce("reduceRight", "EmptyReduceRightSumNoInit", 0, [], [0], sum);
178 testReduce("reduceRight", "EmptyReduceRightProdNoInit", 1, [], [1], prod);
179 testReduce("reduceRight", "EmptyReduceRightDecNoInit", 0, [], [0], dec);
180 testReduce("reduceRight", "EmptyReduceRightAccumulateNoInit", [], [], [[]], ac cumulate);
181
182
183 // Test error conditions.
184 assertThrows(function () { a.reduce("not a function"); }, TypeError);
185 assertThrows(function () { a.reduceRight("not a function"); }, TypeError);
186
187 var emptyArray = constructor.of();
188 assertThrows(function () { emptyArray.reduce(sum); }, TypeError);
189 assertThrows(function () { emptyArray.reduceRight(sum); }, TypeError);
190
191 // Modify the original array inside .reduce().
192 count = 0;
193 assertEquals(2 + 4 + 6, a.reduce(function (prev, current, index, array) {
194 count++;
195 array[index] = current + 1;
196 return prev + current;
197 }, 0));
198 assertEquals(a.length, count);
199 assertArrayEquals([3, 5, 7], a);
200
201 // Ditto for .reduceRight().
202 count = 0;
203 assertEquals(3 + 5 + 7, a.reduceRight(function (prev, current, index, array) {
204 count++;
205 array[index] = current - 2;
206 return prev + current;
207 }, 0));
208 assertEquals(a.length, count);
209 assertArrayEquals([1, 3, 5], a);
210
211 // Throw before completing iteration, only the first element
212 // should be modified when throwing mid-way for .reduce().
213 count = 0;
214 var result;
215 a = constructor.of(2, 4, 6);
216 try {
217 result = a.reduce(function (prev, current, index, array) {
218 if (count > 0) throw "meh";
219 array[index] = current + 1;
220 count++;
221 return prev + current;
222 }, 0);
223 } catch (e) {
224 }
225 assertEquals(undefined, result);
226 assertEquals(1, count);
227 assertArrayEquals([3, 4, 6], a);
228
229 // Ditto for .reduceRight().
230 count = 0;
231 try {
232 result = a.reduceRight(function (prev, current, index, array) {
233 if (count > 0) throw "meh";
234 array[index] = current + 1;
235 count++;
236 return prev + count;
237 }, 0);
238 } catch (e) {
239 }
240 assertEquals(undefined, result);
241 assertEquals(1, count);
242 assertArrayEquals([3, 4, 7], a);
243
244 // Neutering the buffer backing the typed array mid-way should
245 // still make .reduce() finish, and the array should keep being
246 // empty after neutering it.
247 count = 0;
248 a.reduce(function (prev, current, index, array) {
249 if (count > 0) %ArrayBufferNeuter(array.buffer);
250 array[index] = current + 1;
251 count++;
252 return prev + current;
253 }, 0);
254 assertEquals(3, count);
255 CheckTypedArrayIsNeutered(a);
256 assertEquals(undefined, a[0]);
257
258 // Ditto for .reduceRight()
259 count = 0;
260 a = constructor.of(2, 4, 6);
261 a.reduceRight(function (prev, current, index, array) {
262 if (count > 0) %ArrayBufferNeuter(array.buffer);
263 array[index] = current + 1;
264 count++;
265 return prev + count;
266 }, 0);
267 assertEquals(3, count);
268 CheckTypedArrayIsNeutered(a);
269 assertEquals(undefined, a[0]);
270
271 // The method must work for typed arrays created from ArrayBuffer.
272 // The length of the ArrayBuffer is chosen so it is a multiple of
273 // all lengths of the typed array items.
274 a = new constructor(new ArrayBuffer(64));
275
276 count = 0;
277 a.reduce(function (a, b) { return count++; }, 0);
278 assertEquals(a.length, count);
279
280 count = 0;
281 a.reduceRight(function (a, b) { return count++; }, 0);
282 assertEquals(a.length, count);
283
284 // Externalizing the array mid-way accessing the .buffer property
285 // should work for .reduce().
286 a = new constructor(2);
287 count = 0;
288 var buffer = undefined;
289 a.reduce(function (prev, current, index, array) {
290 if (count++ > 0)
291 buffer = array.buffer;
292 return 0;
293 }, 0);
294 assertEquals(2, count);
295 assertTrue(!!buffer);
296 assertEquals("ArrayBuffer", %_ClassOf(buffer));
297 assertSame(buffer, a.buffer);
298
299 // Ditto for .reduceRight().
300 count = 0;
301 buffer = undefined;
302 a.reduceRight(function (prev, current, index, array) {
303 if (count++ > 0)
304 buffer = array.buffer;
305 return 0;
306 }, 0);
307 assertEquals(2, count);
308 assertTrue(!!buffer);
309 assertEquals("ArrayBuffer", %_ClassOf(buffer));
310 assertSame(buffer, a.buffer);
311
312 // The .reduce() and .reduceRight() methods should not work
313 // when transplanted to objects that are not typed arrays.
314 assertThrows(function () { constructor.prototype.reduce.call([1, 2, 3], sum); }, TypeError);
315 assertThrows(function () { constructor.prototype.reduce.call("abc", sum); }, T ypeError);
316 assertThrows(function () { constructor.prototype.reduce.call({}, sum); }, Type Error);
317 assertThrows(function () { constructor.prototype.reduce.call(0, sum); }, TypeE rror);
318 assertThrows(function () { constructor.prototype.reduceRight.call([1, 2, 3], s um); }, TypeError);
319 assertThrows(function () { constructor.prototype.reduceRight.call("abc", sum); }, TypeError);
320 assertThrows(function () { constructor.prototype.reduceRight.call({}, sum); }, TypeError);
321 assertThrows(function () { constructor.prototype.reduceRight.call(0, sum); }, TypeError);
322
323 // Method must be useable on instances of other typed arrays.
324 for (var otherConstructor of typedArrayConstructors) {
325 a = otherConstructor.of(2, 4, 6, 8);
326 count = 0;
327 result = constructor.prototype.reduce.call(a,
328 function (prev, current) { count++; return prev + current; }, 0);
329 assertEquals(a.length, count);
330 assertEquals(20, result);
331 count = 0;
332 result = constructor.prototype.reduceRight.call(a,
333 function (prev, current) { count++; return prev + current; }, 0);
334 assertEquals(a.length, count);
335 assertEquals(20, result);
336 }
337 }
338
339 for (var constructor of typedArrayConstructors) {
340 TestTypedArrayReduce(constructor);
341 }
OLDNEW
« no previous file with comments | « src/harmony-typedarray.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698