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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/harmony-typedarray.js ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/mjsunit/harmony/typedarrays-reduce.js
diff --git a/test/mjsunit/harmony/typedarrays-reduce.js b/test/mjsunit/harmony/typedarrays-reduce.js
new file mode 100644
index 0000000000000000000000000000000000000000..b13aaea31ef4ba055ad6f058b0afbdd41f858a86
--- /dev/null
+++ b/test/mjsunit/harmony/typedarrays-reduce.js
@@ -0,0 +1,341 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-arrays --allow-natives-syntax
+
+var typedArrayConstructors = [
+ Uint8Array,
+ Int8Array,
+ Uint16Array,
+ Int16Array,
+ Uint32Array,
+ Int32Array,
+ Uint8ClampedArray,
+ Float32Array,
+ Float64Array];
+
+function CheckTypedArrayIsNeutered(array) {
+ assertEquals(0, array.byteLength);
+ assertEquals(0, array.byteOffset);
+ assertEquals(0, array.length);
+}
+
+function CheckSuperficialFunctionFeatures(obj, funcname) {
+ assertEquals(1, obj[funcname].length);
+ var desc = Object.getOwnPropertyDescriptor(obj, funcname);
+ assertEquals(false, desc.configurable);
+ assertEquals(false, desc.enumerable);
+ assertEquals(false, desc.writable);
+}
+
+// The following helpe functions are taken from mjsunit/array-reduce.js
+
+function clone(v) {
+ // Shallow-copies arrays, returns everything else verbatim.
+ if (v instanceof Array) {
+ // Shallow-copy an array.
+ var newArray = new Array(v.length);
+ for (var i in v) {
+ newArray[i] = v[i];
+ }
+ return newArray;
+ }
+ return v;
+}
+
+// Creates a callback function for reduce/reduceRight that tests the number
+// of arguments and otherwise behaves as "func", but which also
+// records all calls in an array on the function (as arrays of arguments
+// followed by result).
+function makeRecorder(func, testName) {
+ var record = [];
+ var f = function recorder(a, b, i, s) {
+ assertEquals(4, arguments.length, testName + "(number of arguments: " + arguments.length + ")");
+ assertEquals("number", typeof(i), testName + "(index must be number)");
+ assertEquals(s[i], b, testName + "(current argument is at index)");
+ if (record.length > 0) {
+ var prevRecord = record[record.length - 1];
+ var prevResult = prevRecord[prevRecord.length - 1];
+ assertEquals(prevResult, a, testName + "(prev result -> current input)");
+ }
+ var args = [clone(a), clone(b), i, clone(s)];
+ var result = func.apply(this, arguments);
+ args.push(clone(result));
+ record.push(args);
+ return result;
+ };
+ f.record = record;
+ return f;
+}
+
+function testReduce(type,
+ testName,
+ expectedResult,
+ expectedCalls,
+ array,
+ combine,
+ init)
+{
+ var rec = makeRecorder(combine, testName);
+ var result;
+ var performsCall;
+ if (arguments.length > 6) {
+ result = array[type](rec, init);
+ } else {
+ result = array[type](rec);
+ }
+ var calls = rec.record;
+ assertEquals(expectedCalls.length, calls.length,
+ testName + " (number of calls)");
+ for (var i = 0; i < expectedCalls.length; i++) {
+ assertEquals(expectedCalls[i], calls[i],
+ testName + " (call " + (i + 1) + ")");
+ }
+ assertEquals(expectedResult, result, testName + " (result)");
+}
+
+function sum(a, b) { return a + b; }
+function prod(a, b) { return a * b; }
+function dec(a, b, i, arr) { return a + b * Math.pow(10, arr.length - i - 1); }
+function accumulate(acc, elem, i) { acc[i] = elem; return acc; }
+
+
+function TestTypedArrayReduce(constructor) {
+ CheckSuperficialFunctionFeatures(constructor.prototype, "reduce");
+ CheckSuperficialFunctionFeatures(constructor.prototype, "reduceRight");
+
+ var a = constructor.of(2, 4, 6);
+
+ // .reduce()
+ testReduce("reduce", "SimpleReduceSum", 12,
+ [[0, 2, 0, a, 2],
+ [2, 4, 1, a, 6],
+ [6, 6, 2, a, 12]],
+ a, sum, 0);
+
+ testReduce("reduce", "SimpleReduceProd", 48,
+ [[1, 2, 0, a, 2],
+ [2, 4, 1, a, 8],
+ [8, 6, 2, a, 48]],
+ a, prod, 1);
+
+ testReduce("reduce", "SimpleReduceDec", 246,
+ [[0, 2, 0, a, 200],
+ [200, 4, 1, a, 240],
+ [240, 6, 2, a, 246]],
+ a, dec, 0);
+
+ testReduce("reduce", "SimpleReduceAccumulate", [2,4,6],
+ [[[], 2, 0, a, [2]],
+ [[2], 4, 1, a, [2,4]],
+ [[2,4], 6, 2, a, [2,4,6]]],
+ a, accumulate, []);
+
+ testReduce("reduce", "EmptyReduceSum", 0, [], [], sum, 0);
+ testReduce("reduce", "EmptyReduceProd", 1, [], [], prod, 1);
+ testReduce("reduce", "EmptyReduceDec", 0, [], [], dec, 0);
+ testReduce("reduce", "EmptyReduceAccumulate", [], [], [], accumulate, []);
+
+ testReduce("reduce", "EmptyReduceSumNoInit", 0, [], [0], sum);
+ testReduce("reduce", "EmptyReduceProdNoInit", 1, [], [1], prod);
+ testReduce("reduce", "EmptyReduceDecNoInit", 0, [], [0], dec);
+ testReduce("reduce", "EmptyReduceAccumulateNoInit", [], [], [[]], accumulate);
+
+ // .reduceRight()
+ testReduce("reduceRight", "SimpleReduceRightSum", 12,
+ [[0, 6, 2, a, 6],
+ [6, 4, 1, a, 10],
+ [10, 2, 0, a, 12]],
+ a, sum, 0);
+
+ testReduce("reduceRight", "SimpleReduceRightProd", 48,
+ [[1, 6, 2, a, 6],
+ [6, 4, 1, a, 24],
+ [24, 2, 0, a, 48]],
+ a, prod, 1);
+
+ testReduce("reduceRight", "SimpleReduceRightDec", 246,
+ [[0, 6, 2, a, 6],
+ [6, 4, 1, a, 46],
+ [46, 2, 0, a, 246]],
+ a, dec, 0);
+
+ testReduce("reduceRight", "SimpleReduceRightAccumulate", [2, 4, 6],
+ [[[], 6, 2, a, [,,6]],
+ [[,,6], 4, 1, a, [,4,6]],
+ [[,4,6], 2, 0, a, [2,4,6]]],
+ a, accumulate, []);
+
+
+ testReduce("reduceRight", "EmptyReduceRightSum", 0, [], [], sum, 0);
+ testReduce("reduceRight", "EmptyReduceRightProd", 1, [], [], prod, 1);
+ testReduce("reduceRight", "EmptyReduceRightDec", 0, [], [], dec, 0);
+ testReduce("reduceRight", "EmptyReduceRightAccumulate", [],
+ [], [], accumulate, []);
+
+ testReduce("reduceRight", "EmptyReduceRightSumNoInit", 0, [], [0], sum);
+ testReduce("reduceRight", "EmptyReduceRightProdNoInit", 1, [], [1], prod);
+ testReduce("reduceRight", "EmptyReduceRightDecNoInit", 0, [], [0], dec);
+ testReduce("reduceRight", "EmptyReduceRightAccumulateNoInit", [], [], [[]], accumulate);
+
+
+ // Test error conditions.
+ assertThrows(function () { a.reduce("not a function"); }, TypeError);
+ assertThrows(function () { a.reduceRight("not a function"); }, TypeError);
+
+ var emptyArray = constructor.of();
+ assertThrows(function () { emptyArray.reduce(sum); }, TypeError);
+ assertThrows(function () { emptyArray.reduceRight(sum); }, TypeError);
+
+ // Modify the original array inside .reduce().
+ count = 0;
+ assertEquals(2 + 4 + 6, a.reduce(function (prev, current, index, array) {
+ count++;
+ array[index] = current + 1;
+ return prev + current;
+ }, 0));
+ assertEquals(a.length, count);
+ assertArrayEquals([3, 5, 7], a);
+
+ // Ditto for .reduceRight().
+ count = 0;
+ assertEquals(3 + 5 + 7, a.reduceRight(function (prev, current, index, array) {
+ count++;
+ array[index] = current - 2;
+ return prev + current;
+ }, 0));
+ assertEquals(a.length, count);
+ assertArrayEquals([1, 3, 5], a);
+
+ // Throw before completing iteration, only the first element
+ // should be modified when throwing mid-way for .reduce().
+ count = 0;
+ var result;
+ a = constructor.of(2, 4, 6);
+ try {
+ result = a.reduce(function (prev, current, index, array) {
+ if (count > 0) throw "meh";
+ array[index] = current + 1;
+ count++;
+ return prev + current;
+ }, 0);
+ } catch (e) {
+ }
+ assertEquals(undefined, result);
+ assertEquals(1, count);
+ assertArrayEquals([3, 4, 6], a);
+
+ // Ditto for .reduceRight().
+ count = 0;
+ try {
+ result = a.reduceRight(function (prev, current, index, array) {
+ if (count > 0) throw "meh";
+ array[index] = current + 1;
+ count++;
+ return prev + count;
+ }, 0);
+ } catch (e) {
+ }
+ assertEquals(undefined, result);
+ assertEquals(1, count);
+ assertArrayEquals([3, 4, 7], a);
+
+ // Neutering the buffer backing the typed array mid-way should
+ // still make .reduce() finish, and the array should keep being
+ // empty after neutering it.
+ count = 0;
+ a.reduce(function (prev, current, index, array) {
+ if (count > 0) %ArrayBufferNeuter(array.buffer);
+ array[index] = current + 1;
+ count++;
+ return prev + current;
+ }, 0);
+ assertEquals(3, count);
+ CheckTypedArrayIsNeutered(a);
+ assertEquals(undefined, a[0]);
+
+ // Ditto for .reduceRight()
+ count = 0;
+ a = constructor.of(2, 4, 6);
+ a.reduceRight(function (prev, current, index, array) {
+ if (count > 0) %ArrayBufferNeuter(array.buffer);
+ array[index] = current + 1;
+ count++;
+ return prev + count;
+ }, 0);
+ assertEquals(3, count);
+ CheckTypedArrayIsNeutered(a);
+ assertEquals(undefined, a[0]);
+
+ // The method must work for typed arrays created from ArrayBuffer.
+ // The length of the ArrayBuffer is chosen so it is a multiple of
+ // all lengths of the typed array items.
+ a = new constructor(new ArrayBuffer(64));
+
+ count = 0;
+ a.reduce(function (a, b) { return count++; }, 0);
+ assertEquals(a.length, count);
+
+ count = 0;
+ a.reduceRight(function (a, b) { return count++; }, 0);
+ assertEquals(a.length, count);
+
+ // Externalizing the array mid-way accessing the .buffer property
+ // should work for .reduce().
+ a = new constructor(2);
+ count = 0;
+ var buffer = undefined;
+ a.reduce(function (prev, current, index, array) {
+ if (count++ > 0)
+ buffer = array.buffer;
+ return 0;
+ }, 0);
+ assertEquals(2, count);
+ assertTrue(!!buffer);
+ assertEquals("ArrayBuffer", %_ClassOf(buffer));
+ assertSame(buffer, a.buffer);
+
+ // Ditto for .reduceRight().
+ count = 0;
+ buffer = undefined;
+ a.reduceRight(function (prev, current, index, array) {
+ if (count++ > 0)
+ buffer = array.buffer;
+ return 0;
+ }, 0);
+ assertEquals(2, count);
+ assertTrue(!!buffer);
+ assertEquals("ArrayBuffer", %_ClassOf(buffer));
+ assertSame(buffer, a.buffer);
+
+ // The .reduce() and .reduceRight() methods should not work
+ // when transplanted to objects that are not typed arrays.
+ assertThrows(function () { constructor.prototype.reduce.call([1, 2, 3], sum); }, TypeError);
+ assertThrows(function () { constructor.prototype.reduce.call("abc", sum); }, TypeError);
+ assertThrows(function () { constructor.prototype.reduce.call({}, sum); }, TypeError);
+ assertThrows(function () { constructor.prototype.reduce.call(0, sum); }, TypeError);
+ assertThrows(function () { constructor.prototype.reduceRight.call([1, 2, 3], sum); }, TypeError);
+ assertThrows(function () { constructor.prototype.reduceRight.call("abc", sum); }, TypeError);
+ assertThrows(function () { constructor.prototype.reduceRight.call({}, sum); }, TypeError);
+ assertThrows(function () { constructor.prototype.reduceRight.call(0, sum); }, TypeError);
+
+ // Method must be useable on instances of other typed arrays.
+ for (var otherConstructor of typedArrayConstructors) {
+ a = otherConstructor.of(2, 4, 6, 8);
+ count = 0;
+ result = constructor.prototype.reduce.call(a,
+ function (prev, current) { count++; return prev + current; }, 0);
+ assertEquals(a.length, count);
+ assertEquals(20, result);
+ count = 0;
+ result = constructor.prototype.reduceRight.call(a,
+ function (prev, current) { count++; return prev + current; }, 0);
+ assertEquals(a.length, count);
+ assertEquals(20, result);
+ }
+}
+
+for (var constructor of typedArrayConstructors) {
+ TestTypedArrayReduce(constructor);
+}
« 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