Bug 939715: TypedObject PJS API tests (r=nmatsakis).
authorFelix S. Klock II <pnkfelix@pnkfx.org>
Fri, 13 Dec 2013 09:59:00 +0100
changeset 163006 7ede01d9d4185d58dfcc0ae7e2d628b915ecf316
parent 163005 4b29977351c4496dfc4e854449ec28e7fedc4735
child 163007 d46aa338c5182bf47581fd3d3d8037993a4e477b
push id25979
push usercbook@mozilla.com
push dateMon, 13 Jan 2014 11:46:02 +0000
treeherdermozilla-central@ea6657f1d682 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnmatsakis
bugs939715
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 939715: TypedObject PJS API tests (r=nmatsakis).
js/src/tests/ecma_6/TypedObject/method_build.js
js/src/tests/ecma_6/TypedObject/method_filter.js
js/src/tests/ecma_6/TypedObject/method_from.js
js/src/tests/ecma_6/TypedObject/method_map.js
js/src/tests/ecma_6/TypedObject/method_reduce.js
js/src/tests/ecma_6/TypedObject/method_scatter.js
js/src/tests/ecma_6/TypedObject/shell.js
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedObject/method_build.js
@@ -0,0 +1,147 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 939715;
+var summary = 'method type.build';
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+var Handle = TypedObject.Handle;
+
+function oneDimensionalArrayOfUints() {
+  var grain = uint32;
+  var type = grain.array(4);
+  var r1 = type.build(x => x * 2);
+  var r2 = type.build((x, out) => Handle.set(out, x * 2));
+  assertTypedEqual(type, r1, new type([0, 2, 4, 6]));
+  assertTypedEqual(type, r1, r2);
+}
+
+function oneDimensionalArrayOfStructs() {
+  var grain = new StructType({f: uint32});
+  var type = grain.array(4);
+  var r1 = type.build(x => new grain({f: x * 2}));
+  var r2 = type.build((x, out) => { out.f = x * 2; });
+  assertTypedEqual(type, r1, new type([{f:0}, {f:2},
+                                       {f:4}, {f:6}]));
+  assertTypedEqual(type, r1, r2);
+}
+
+// At an attempt at readability, the tests below all try to build up
+// numbers where there is a one-to-one mapping between input dimension
+// and base-10 digit in the output.
+//
+// (Note that leading zeros must be elided in the expected-values to
+// avoid inadvertantly interpreting the numbers as octal constants.)
+
+function twoDimensionalArrayOfStructsWithDepth2() {
+  var grain = new StructType({f: uint32});
+  var type = grain.array(2, 2);
+
+  var r1 = type.build(2, (x, y) => {
+    return new grain({f: x * 10 + y});
+  });
+
+  var r2 = type.build(2, (x, y, out) => {
+    out.f = x * 10 + y;
+  });
+
+  assertTypedEqual(type, r1, new type([[{f: 0}, {f: 1}],
+                                       [{f:10}, {f:11}]]));
+  assertTypedEqual(type, r1, r2);
+}
+
+function twoDimensionalArrayOfStructsWithDepth1() {
+  var grain = new StructType({f: uint32}).array(2);
+  var type = grain.array(2);
+
+  var r1 = type.build((x) => {
+    return new grain([{f: x * 10},
+                      {f: x * 10 + 1}]);
+  });
+
+  var r2 = type.build(1, (x, out) => {
+    out[0].f = x * 10 + 0;
+    out[1].f = x * 10 + 1;
+  });
+
+  assertTypedEqual(type, r1, new type([[{f: 0}, {f: 1}],
+                                       [{f:10}, {f:11}]]));
+  assertTypedEqual(type, r1, r2);
+}
+
+function threeDimensionalArrayOfUintsWithDepth3() {
+  var grain = uint32;
+  var type = grain.array(2).array(2).array(2);
+  var r1 = type.build(3, (x,y,z) => x * 100 + y * 10 + z);
+  var r2 = type.build(3, (x,y,z, out) => Handle.set(out, x * 100 + y * 10 + z));
+  assertTypedEqual(type, r1, new type([[[  0,   1], [ 10,  11]],
+                                       [[100, 101], [110, 111]]]));
+  assertTypedEqual(type, r1, r2);
+}
+
+function threeDimensionalArrayOfUintsWithDepth2() {
+  var grain = uint32.array(2);
+  var type = grain.array(2).array(2);
+  var r1 = type.build(2, (x,y) => [x * 100 + y * 10 + 0, x * 100 + y * 10 + 1]);
+  var r1b = type.build(2, (x,y) => grain.build(z => x * 100 + y * 10 + z));
+  var r1c = type.build(2, (x,y) => grain.build(1, z => x * 100 + y * 10 + z));
+
+  var r2 = type.build(2, (x,y, out) => { out[0] = x * 100 + y * 10 + 0;
+                                         out[1] = x * 100 + y * 10 + 1;
+                                       });
+  assertTypedEqual(type, r1, new type([[[  0,   1], [ 10,  11]],
+                                       [[100, 101], [110, 111]]]));
+  assertTypedEqual(type, r1, r1b);
+  assertTypedEqual(type, r1, r1c);
+  assertTypedEqual(type, r1, r2);
+}
+
+function threeDimensionalArrayOfUintsWithDepth1() {
+  var grain = uint32.array(2).array(2);
+  var type = grain.array(2);
+  var r1 = type.build(1, (x) => grain.build(y => [x * 100 + y * 10 + 0, x * 100 + y * 10 + 1]));
+  var r1b = type.build(1, (x) => grain.build(1, y => [x * 100 + y * 10 + 0, x * 100 + y * 10 + 1]));
+  var r1c = type.build(1, (x) => grain.build(2, (y,z) => x * 100 + y * 10 + z));
+  var r2 = type.build(1, (x, out) => { out[0][0] = x * 100 + 0 * 10 + 0;
+                                       out[0][1] = x * 100 + 0 * 10 + 1;
+                                       out[1][0] = x * 100 + 1 * 10 + 0;
+                                       out[1][1] = x * 100 + 1 * 10 + 1;
+                                     });
+  assertTypedEqual(type, r1, new type([[[  0,   1], [ 10,  11]],
+                                       [[100, 101], [110, 111]]]));
+  assertTypedEqual(type, r1, r1b);
+  assertTypedEqual(type, r1, r1c);
+  assertTypedEqual(type, r1, r2);
+}
+
+function runTests() {
+    print(BUGNUMBER + ": " + summary);
+
+    oneDimensionalArrayOfUints();
+    oneDimensionalArrayOfStructs();
+    twoDimensionalArrayOfStructsWithDepth2();
+    twoDimensionalArrayOfStructsWithDepth1();
+    threeDimensionalArrayOfUintsWithDepth3();
+    threeDimensionalArrayOfUintsWithDepth2();
+    threeDimensionalArrayOfUintsWithDepth1();
+
+    if (typeof reportCompare === "function")
+        reportCompare(true, true);
+    print("Tests complete");
+}
+
+runTests();
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedObject/method_filter.js
@@ -0,0 +1,65 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 939715;
+var summary = 'method instance.filter';
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+var objectType = TypedObject.objectType;
+
+function filterOddsFromVariable() {
+  var length = 100;
+  var Uint32s = uint32.array();
+  var uint32s = new Uint32s(100);
+  for (var i = 0; i < length; i++)
+    uint32s[i] = i;
+
+  var odds = uint32s.filter(i => (i % 2) != 0);
+  assertEq(true, objectType(odds) == Uint32s);
+  assertEq(true, Uint32s.variable);
+  assertEq(50, odds.length);
+  for (var i = 0, j = 1; j < length; i++, j += 2)
+    assertEq(odds[i], j);
+}
+
+function filterOddsFromSized() {
+  var length = 100;
+  var Uint32s = uint32.array(100);
+  var uint32s = new Uint32s();
+  for (var i = 0; i < length; i++)
+    uint32s[i] = i;
+
+  var odds = uint32s.filter(i => (i % 2) != 0);
+  assertEq(true, objectType(odds) == Uint32s.unsized);
+  assertEq(true, objectType(odds).variable);
+  assertEq(50, odds.length);
+  for (var i = 0, j = 1; j < length; i++, j += 2)
+    assertEq(odds[i], j);
+}
+
+function runTests() {
+    print(BUGNUMBER + ": " + summary);
+
+    filterOddsFromVariable();
+    filterOddsFromSized();
+
+    if (typeof reportCompare === "function")
+        reportCompare(true, true);
+    print("Tests complete");
+}
+
+runTests();
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedObject/method_from.js
@@ -0,0 +1,232 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 939715;
+var summary = 'method type.from';
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+var Handle = TypedObject.Handle;
+
+// Test name format:
+
+// from<N>DimArrayOf<G1>sTo<G2>s where <N> is a positive integer (or its
+// equivalent word in English) and <G1> and <G2> are both grain types
+// (potentially an array themselves.)
+
+function fromOneDimArrayOfUint8ToUint32s() {
+  var intype = uint8.array(4);
+  var type = uint32.array(4);
+  var i1 = intype.build(i => i);
+  var r1 = type.from(i1, j => j*2);
+  var r2 = type.from(i1, 1, j => j*2);
+  assertTypedEqual(type, r1, new type([0, 2, 4, 6]));
+  assertTypedEqual(type, r1, r2);
+}
+
+function fromOneDimArrayOfUint32ToUint8s() {
+  var intype = uint32.array(4);
+  var type = uint8.array(4);
+  var i1 = intype.build(i => i);
+  var r1 = type.from(i1, j => j*200);
+  var r2 = type.from(i1, 1, j => j*200);
+  assertTypedEqual(type, r1, new type([0, 200, 400 % 256, 600 % 256]));
+  assertTypedEqual(type, r1, r2);
+}
+
+function fromTwoDimArrayOfUint8ToUint32s() {
+  var intype = uint8.array(4).array(4);
+  var rowtype = uint32.array(4);
+  var type = rowtype.array(4);
+  var i1 = new type([[10, 11, 12, 13],
+                     [20, 21, 22, 23],
+                     [30, 31, 32, 33],
+                     [40, 41, 42, 43]]);
+
+  var r1 = type.from(i1, 2, x => x*2);
+  var r2 = type.from(i1, 1, a => rowtype.from(a, 1, x => x*2));
+  var r3 = type.from(i1, 1,
+    a => rowtype.from(a, 1, (x, j, c, out) => Handle.set(out, x*2)));
+  var r4 = type.from(i1, 1, (a, j, c, out) => { out[0] = a[0]*2;
+                                                out[1] = a[1]*2;
+                                                out[2] = a[2]*2;
+                                                out[3] = a[3]*2; });
+  assertTypedEqual(type, r1, new type([[20, 22, 24, 26],
+                                       [40, 42, 44, 46],
+                                       [60, 62, 64, 66],
+                                       [80, 82, 84, 86]]));
+  assertTypedEqual(type, r1, r2);
+  assertTypedEqual(type, r1, r3);
+  assertTypedEqual(type, r1, r4);
+}
+
+function fromTwoDimArrayOfUint32ToUint8s() {
+  var intype = uint32.array(4).array(4);
+  var rowtype = uint8.array(4);
+  var type = rowtype.array(4);
+  var i1 = new type([[10, 11, 12, 13],
+                     [20, 21, 22, 23],
+                     [30, 31, 32, 33],
+                     [40, 41, 42, 43]]);
+
+  var r1 = type.from(i1, 2, x => x*2);
+  var r2 = type.from(i1, 1, a => rowtype.from(a, 1, x => x*2));
+  var r3 = type.from(i1, 1,
+    a => rowtype.from(a, 1, (x, j, c, out) => Handle.set(out, x*2)));
+  var r4 = type.from(i1, 1, (a, j, c, out) => { out[0] = a[0]*2;
+                                                out[1] = a[1]*2;
+                                                out[2] = a[2]*2;
+                                                out[3] = a[3]*2; });
+  assertTypedEqual(type, r1, new type([[20, 22, 24, 26],
+                                       [40, 42, 44, 46],
+                                       [60, 62, 64, 66],
+                                       [80, 82, 84, 86]]));
+  assertTypedEqual(type, r1, r2);
+  assertTypedEqual(type, r1, r3);
+  assertTypedEqual(type, r1, r4);
+}
+
+function fromOneDimArrayOfArrayOfUint8ToUint32s() {
+  var intype = uint8.array(4).array(4);
+  var type = uint32.array(4);
+  var i1 = new intype([[0xdd, 0xcc, 0xbb, 0xaa],
+                       [0x09, 0x08, 0x07, 0x06],
+                       [0x15, 0x14, 0x13, 0x12],
+                       [0x23, 0x32, 0x41, 0x50]]);
+
+  function combine(a,b,c,d) { return a << 24 | b << 16 | c << 8 | d; }
+
+  var r1 = type.from(i1, x => combine(x[0], x[1], x[2], x[3]));
+  var r2 = type.from(i1, 1,
+    (x, i, c, out) => Handle.set(out, combine(x[0], x[1], x[2], x[3])));
+  assertTypedEqual(type, r1, new type([0xddccbbaa,
+                                       0x09080706,
+                                       0x15141312,
+                                       0x23324150]));
+  assertTypedEqual(type, r1, r2);
+}
+
+function fromOneDimArrayOfUint32ToArrayOfUint8s() {
+  var intype = uint32.array(4);
+  var type = uint8.array(4).array(4);
+  var i1 = new intype([0xddccbbaa,
+                       0x09080706,
+                       0x15141312,
+                       0x23324150]);
+
+  function divide(a) { return [a >> 24 & 0xFF, a >> 16 & 0xFF, a >> 8 & 0xFF, a & 0xFF]; }
+
+  var r1 = type.from(i1, x => divide(x));
+  var r2 = type.from(i1, 1, (x, i, c, out) => {
+                          var [a,b,c,d] = divide(x);
+                          out[0] = a; out[1] = b; out[2] = c; out[3] = d;
+                        });
+  assertTypedEqual(type, r1, new type([[0xdd, 0xcc, 0xbb, 0xaa],
+                                       [0x09, 0x08, 0x07, 0x06],
+                                       [0x15, 0x14, 0x13, 0x12],
+                                       [0x23, 0x32, 0x41, 0x50]]));
+  assertTypedEqual(type, r1, r2);
+}
+
+var Grain = new StructType({f: uint32});
+function wrapG(v) { return new Grain({f: v}); }
+function doubleG(g) { return new Grain({f: g.f * 2}); }
+function tenG(x, y) { return new Grain({f: x * 10 + y}); }
+
+function fromOneDimArrayOfStructsToStructs() {
+  var type = Grain.array(4);
+  var i1 = type.build(wrapG);
+  var r1 = type.from(i1, doubleG);
+  var r2 = type.from(i1, 1, doubleG);
+  var r3 = type.from(i1, 1, (g, j, c, out) => { out.f = g.f * 2; });
+  assertTypedEqual(type, r1, new type([{f:0}, {f:2},
+                                       {f:4}, {f:6}]));
+  assertTypedEqual(type, r1, r2);
+  assertTypedEqual(type, r1, r3);
+}
+
+function fromTwoDimArrayOfStructsToStructs() {
+  var rowtype = Grain.array(2);
+  var type = rowtype.array(2);
+  var i1 = type.build(2, tenG);
+  var r1 = type.from(i1, 2, doubleG);
+  var r2 = type.from(i1, 1, (m) => rowtype.from(m, 1, doubleG));
+  var r3 = type.from(i1, 1,
+    (m, j, c, out) => { out[0].f = m[0].f * 2; out[1].f = m[1].f * 2; });
+  assertTypedEqual(type, r1, new type([[{f:00}, {f:02}],
+                                       [{f:20}, {f:22}]]));
+  assertTypedEqual(type, r1, r2);
+  assertTypedEqual(type, r1, r3);
+}
+
+function fromOneDimArrayOfStructsToArrayOfStructs() {
+  var Line = Grain.array(2);
+  var Box = Line.array(2);
+  var i1 = Line.build(wrapG);
+  var r1 = Box.from(i1, (g) => Line.build((y) => tenG(g.f, y)));
+  var r2 = Box.from(i1, (g) => Line.from(i1, (y) => tenG(g.f, y.f)));
+  var r3 = Box.from(i1,
+    (g, j, c, out) => { out[0] = tenG(g.f, 0); out[1] = tenG(g.f, 1); });
+  assertTypedEqual(Box, r1, new Box([[{f:00}, {f:01}],
+                                     [{f:10}, {f:11}]]));
+  assertTypedEqual(Box, r1, r2);
+  assertTypedEqual(Box, r1, r3);
+}
+
+function fromUntypedArrayToUint32s() {
+  var type = uint32.array(4);
+  var i1 = Array.build(4, i => i);
+  var r1 = type.from(i1, j => j*2);
+  var r2 = type.from(i1, 1, j => j*2);
+  assertTypedEqual(type, r1, new type([0, 2, 4, 6]));
+  assertTypedEqual(type, r1, r2);
+}
+
+function fromUntypedArrayToUint8s() {
+  var type = uint8.array(4);
+  var i1 = Array.build(4, i => i);
+  var r1 = type.from(i1, j => j*200);
+  var r2 = type.from(i1, 1, j => j*200);
+  assertTypedEqual(type, r1, new type([0, 200, 400 % 256, 600 % 256]));
+  assertTypedEqual(type, r1, r2);
+}
+
+function runTests() {
+    print(BUGNUMBER + ": " + summary);
+
+    fromOneDimArrayOfUint8ToUint32s();
+    fromOneDimArrayOfUint32ToUint8s();
+
+    fromTwoDimArrayOfUint8ToUint32s();
+    fromTwoDimArrayOfUint32ToUint8s();
+
+    fromOneDimArrayOfArrayOfUint8ToUint32s();
+    fromOneDimArrayOfUint32ToArrayOfUint8s();
+
+    fromOneDimArrayOfStructsToStructs();
+    fromTwoDimArrayOfStructsToStructs();
+
+    fromOneDimArrayOfStructsToArrayOfStructs();
+
+    fromUntypedArrayToUint32s();
+    fromUntypedArrayToUint8s();
+
+    if (typeof reportCompare === "function")
+        reportCompare(true, true);
+    print("Tests complete");
+}
+
+runTests();
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedObject/method_map.js
@@ -0,0 +1,142 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 939715;
+var summary = 'method instance.map';
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+var Handle = TypedObject.Handle;
+
+// Test name format:
+
+// map<N>DimArrayOf<G1>sTo<G2>s where <N> is a positive integer (or its
+// equivalent word in English) and <G1> and <G2> are both grain types
+// (potentially an array themselves.)
+
+function mapOneDimArrayOfUint8() {
+  var type = uint8.array(4);
+  var i1 = type.build(i => i);
+  var r1 = i1.map(j => j*200);
+  var r2 = i1.map(1, j => j*200);
+  assertTypedEqual(type, r1, new type([0, 200, 400 % 256, 600 % 256]));
+  assertTypedEqual(type, r1, r2);
+}
+
+function mapOneDimArrayOfUint32() {
+  var type = uint32.array(4);
+  var i1 = type.build(i => i);
+  var r1 = i1.map(j => j*200);
+  var r2 = i1.map(1, j => j*200);
+  assertTypedEqual(type, r1, new type([0, 200, 400, 600]));
+  assertTypedEqual(type, r1, r2);
+}
+
+function mapTwoDimArrayOfUint8() {
+  var type = uint8.array(4).array(4);
+  var i1 = new type([[10, 11, 12, 13],
+                     [20, 21, 22, 23],
+                     [30, 31, 32, 33],
+                     [40, 41, 42, 43]]);
+
+  var r1 = i1.map(2, x => x*2);
+  var r2 = i1.map(1, a => a.map(1, x => x*2));
+  var r3 = i1.map(1, a => a.map(1, (x, j, c, out) => Handle.set(out, x*2)));
+  var r4 = i1.map(1, (a, j, c, out) => { out[0] = a[0]*2;
+                                         out[1] = a[1]*2;
+                                         out[2] = a[2]*2;
+                                         out[3] = a[3]*2; });
+  assertTypedEqual(type, r1, new type([[20, 22, 24, 26],
+                                       [40, 42, 44, 46],
+                                       [60, 62, 64, 66],
+                                       [80, 82, 84, 86]]));
+  assertTypedEqual(type, r1, r2);
+  assertTypedEqual(type, r1, r3);
+  assertTypedEqual(type, r1, r4);
+}
+
+function mapTwoDimArrayOfUint32() {
+  var type = uint32.array(4).array(4);
+  var i1 = new type([[10, 11, 12, 13],
+                     [20, 21, 22, 23],
+                     [30, 31, 32, 33],
+                     [40, 41, 42, 43]]);
+
+  var r1 = i1.map(2, x => x*2);
+  var r2 = i1.map(1, a => a.map(1, x => x*2));
+  var r3 = i1.map(1, a => a.map(1, (x, j, c, out) => Handle.set(out, x*2)));
+  var r4 = i1.map(1, (a, j, c, out) => { out[0] = a[0]*2;
+                                         out[1] = a[1]*2;
+                                         out[2] = a[2]*2;
+                                         out[3] = a[3]*2; });
+  assertTypedEqual(type, r1, new type([[20, 22, 24, 26],
+                                       [40, 42, 44, 46],
+                                       [60, 62, 64, 66],
+                                       [80, 82, 84, 86]]));
+  assertTypedEqual(type, r1, r2);
+  assertTypedEqual(type, r1, r3);
+  assertTypedEqual(type, r1, r4);
+}
+
+var Grain = new StructType({f: uint32});
+function wrapG(v) { return new Grain({f: v}); }
+function doubleG(g) { return new Grain({f: g.f * 2}); }
+function tenG(x, y) { return new Grain({f: x * 10 + y}); }
+
+function mapOneDimArrayOfStructs() {
+  var type = Grain.array(4);
+  var i1 = type.build(wrapG);
+  var r1 = i1.map(doubleG);
+  var r2 = i1.map(1, doubleG);
+  var r3 = i1.map(1, (g, j, c, out) => { out.f = g.f * 2; });
+  assertTypedEqual(type, r1, new type([{f:0}, {f:2},
+                                       {f:4}, {f:6}]));
+  assertTypedEqual(type, r1, r2);
+  assertTypedEqual(type, r1, r3);
+}
+
+function mapTwoDimArrayOfStructs() {
+  var rowtype = Grain.array(2);
+  var type = rowtype.array(2);
+  var i1 = type.build(2, tenG);
+  var r1 = i1.map(2, doubleG);
+  var r2 = i1.map(1, (m) => m.map(1, doubleG));
+  var r3 = i1.map(1, (m, j, c, out) => { out[0].f = m[0].f * 2;
+                                         out[1].f = m[1].f * 2; });
+  assertTypedEqual(type, r1, new type([[{f:00}, {f:02}],
+                                       [{f:20}, {f:22}]]));
+  assertTypedEqual(type, r1, r2);
+  assertTypedEqual(type, r1, r3);
+}
+
+function runTests() {
+    print(BUGNUMBER + ": " + summary);
+
+    mapOneDimArrayOfUint8();
+    mapOneDimArrayOfUint32();
+
+    mapTwoDimArrayOfUint8();
+    mapTwoDimArrayOfUint32();
+
+    mapOneDimArrayOfStructs();
+    mapTwoDimArrayOfStructs();
+
+    if (typeof reportCompare === "function")
+        reportCompare(true, true);
+    print("Tests complete");
+}
+
+runTests();
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedObject/method_reduce.js
@@ -0,0 +1,91 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 939715;
+var summary = 'method instance.reduce';
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+function reduceUint8s() {
+  var uint8Array = uint8.array(5);
+  var array = new uint8Array([128, 129, 130, 131, 132]);
+
+  var sum = array.reduce((a, b) => a + b);
+  assertEq(sum, (128+129+130+131+132) % 256);
+
+  var f64Array = float64.array(5);
+  var floats = new f64Array([128.0, 129.0, 130.0, 131.0, 132.0]);
+
+  // (Note that floating point add is not associative in general;
+  //  we should double-check that the result below is robust.)
+  var fsum = floats.reduce((a, b) => a + b);
+  assertEq(fsum, 128.0+129.0+130.0+131.0+132.0);
+}
+
+function reduceVectors() {
+  var VectorType = uint32.array(3);
+  var VectorsType = VectorType.array(3);
+  var array = new VectorsType([[1, 2, 3],
+                               [4, 5, 6],
+                               [7, 8, 9]]);
+
+  var sum = array.reduce(vectorAdd);
+  assertTypedEqual(VectorType,
+                   sum,
+                   new VectorType([1+4+7,
+                                   2+5+8,
+                                   3+6+9]));
+
+  // The mutated accumulator does not alias the input.
+  assertTypedEqual(VectorsType,
+                   array,
+                   new VectorsType([[1, 2, 3],
+                                    [4, 5, 6],
+                                    [7, 8, 9]]));
+
+  var sum = array.reduce(vectorAddFunctional);
+  assertTypedEqual(VectorType,
+                   sum,
+                   new VectorType([1+4+7,
+                                   2+5+8,
+                                   3+6+9]));
+
+  function vectorAdd(l, r) {
+    assertEq(l.length, r.length);
+    for (var i = 0; i < l.length; i++)
+      l[i] += r[i];
+    return l;
+  }
+
+  function vectorAddFunctional(l, r) {
+    assertEq(l.length, r.length);
+    return VectorType.build(1, i => l[i] + r[i]);
+  }
+
+}
+
+function runTests() {
+    print(BUGNUMBER + ": " + summary);
+
+    reduceUint8s();
+    reduceVectors();
+
+    if (typeof reportCompare === "function")
+        reportCompare(true, true);
+    print("Tests complete");
+}
+
+runTests();
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedObject/method_scatter.js
@@ -0,0 +1,95 @@
+// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
+var BUGNUMBER = 939715;
+var summary = 'method instance.scatter';
+
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var ArrayType = TypedObject.ArrayType;
+var StructType = TypedObject.StructType;
+var uint8 = TypedObject.uint8;
+var uint16 = TypedObject.uint16;
+var uint32 = TypedObject.uint32;
+var uint8Clamped = TypedObject.uint8Clamped;
+var int8 = TypedObject.int8;
+var int16 = TypedObject.int16;
+var int32 = TypedObject.int32;
+var float32 = TypedObject.float32;
+var float64 = TypedObject.float64;
+
+function scatterUint8sPermute() {
+  var uint8Array = uint8.array(5);
+  var array = new uint8Array([124, 120, 122, 123, 121]);
+
+  var perm = array.scatter(uint8Array, [4, 0, 2, 3, 1]);
+  assertTypedEqual(uint8Array, perm, [120, 121, 122, 123, 124]);
+}
+
+function scatterUint8sPermuteIncomplete() {
+  var uint8Array4 = uint8.array(4);
+  var uint8Array5 = uint8.array(5);
+  var array = new uint8Array4([124, 120, 122, 123]);
+
+  var perm;
+  perm = array.scatter(uint8Array5, [4, 0, 2, 3]);
+  assertTypedEqual(uint8Array5, perm, [120,  0, 122, 123, 124]);
+
+  perm = array.scatter(uint8Array5, [4, 0, 2, 3], 77);
+  assertTypedEqual(uint8Array5, perm, [120, 77, 122, 123, 124]);
+}
+
+function scatterUint8sHistogram() {
+  var uint32Array5 = uint32.array(5);
+  var uint32Array3 = uint32.array(3);
+  var array = new uint32Array5([1, 10, 100, 1000, 10000]);
+
+  var hist = array.scatter(uint32Array3, [1, 1, 2, 1, 0], 0, (a,b) => a+b);
+  assertTypedEqual(uint32Array3, hist, [10000, 1011, 100]);
+}
+
+function scatterUint8sCollisionThrows() {
+  var uint32Array5 = uint32.array(5);
+  var uint32Array3 = uint32.array(3);
+  var array = new uint32Array5([1, 10, 100, 1000, 10000]);
+
+  var unset_nonce = new Object();
+  var unset = unset_nonce;
+  try {
+    unset = array.scatter(uint32Array3, [1, 1, 2, 1, 0], 0);
+  } catch (e) {
+    assertEq(unset, unset_nonce);
+  }
+}
+
+function scatterUint8sConflictIsAssocNonCommute() {
+  var uint32Array5 = uint32.array(5);
+  var uint32Array3 = uint32.array(3);
+  var array = new uint32Array5([1, 10, 100, 1000, 10000]);
+
+  // FIXME strawman spec says conflict must be associative, but does
+  // not dictate commutative.  Yet, strawman spec does not appear to
+  // specify operation order; must address incongruence.
+
+  var lfts = array.scatter(uint32Array3, [1, 1, 2, 1, 0], 0, (a,b) => a);
+  assertTypedEqual(uint32Array3, lfts, [10000, 1, 100]);
+  var rgts = array.scatter(uint32Array3, [1, 1, 2, 1, 0], 0, (a,b) => b);
+  assertTypedEqual(uint32Array3, rgts, [10000, 1000, 100]);
+}
+
+function runTests() {
+    print(BUGNUMBER + ": " + summary);
+
+    scatterUint8sPermute();
+    scatterUint8sPermuteIncomplete();
+    scatterUint8sHistogram();
+    scatterUint8sCollisionThrows();
+    scatterUint8sConflictIsAssocNonCommute();
+
+    if (typeof reportCompare === "function")
+        reportCompare(true, true);
+    print("Tests complete");
+}
+
+runTests();
--- a/js/src/tests/ecma_6/TypedObject/shell.js
+++ b/js/src/tests/ecma_6/TypedObject/shell.js
@@ -0,0 +1,33 @@
+// Checks that |a_orig| and |b_orig| are:
+//   1. Both instances of |type|, and
+//   2. Are structurally equivalent (as dictated by the structure of |type|).
+function assertTypedEqual(type, a_orig, b_orig) {
+  try {
+    recur(type, a_orig, b_orig);
+  } catch (e) {
+    print("failure during "+
+          "assertTypedEqual("+type.toSource()+", "+a_orig.toSource()+", "+b_orig.toSource()+")");
+    throw e;
+  }
+
+  function recur(type, a, b) {
+    if (type instanceof ArrayType) {
+      assertEq(a.length, type.length);
+      assertEq(b.length, type.length);
+      for (var i = 0; i < type.length; i++)
+        recur(type.elementType, a[i], b[i]);
+      } else if (type instanceof StructType) {
+        for (var idx in type.fieldNames) {
+          var fieldName = type.fieldNames[idx];
+          if (type.fieldTypes[fieldName] !== undefined) {
+            recur(type.fieldTypes[fieldName], a[fieldName], b[fieldName]);
+          } else {
+            throw new Error("assertTypedEqual no type for "+
+                            "fieldName: "+fieldName+" in type: "+type.toSource());
+          }
+        }
+      } else {
+        assertEq(a, b);
+      }
+  }
+}