Bug 1405943 - Part 2: Add tests for pipeline operator. r=arai
authorKoki Takahashi <hakatasiloving@gmail.com>
Tue, 17 Oct 2017 00:10:00 -0400
changeset 386672 0e5d50e17fef
parent 386671 7371550c7fc5
child 386673 189a22dbcaf9
push id32699
push userarchaeopteryx@coole-files.de
push dateTue, 17 Oct 2017 21:52:51 +0000
treeherdermozilla-central@f78d59473334 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1405943
milestone58.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 1405943 - Part 2: Add tests for pipeline operator. r=arai
js/src/tests/ecma_2018/Pipeline/browser.js
js/src/tests/ecma_2018/Pipeline/eval.js
js/src/tests/ecma_2018/Pipeline/evaluation-order.js
js/src/tests/ecma_2018/Pipeline/parse-error.js
js/src/tests/ecma_2018/Pipeline/precedence.js
js/src/tests/ecma_2018/Pipeline/receiver.js
js/src/tests/ecma_2018/Pipeline/reflect-parse.js
js/src/tests/ecma_2018/Pipeline/shell.js
js/src/tests/ecma_2018/Pipeline/type-error.js
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_2018/Pipeline/eval.js
@@ -0,0 +1,19 @@
+const BUGNUMBER = 1405943;
+const summary = "Implement pipeline operator (eval)";
+
+print(BUGNUMBER + ": " + summary);
+
+const testvalue = 10;
+
+if (hasPipeline()) {
+    eval(`
+    // Pipelined eval should be indirect eval call
+    (() => {
+        const testvalue = 20;
+        assertEq("testvalue" |> eval, 10);
+    })();
+    `);
+}
+
+if (typeof reportCompare === "function")
+    reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_2018/Pipeline/evaluation-order.js
@@ -0,0 +1,18 @@
+const BUGNUMBER = 1405943;
+const summary = "Implement pipeline operator (evaluation order)";
+
+print(BUGNUMBER + ": " + summary);
+
+if (hasPipeline()) {
+    eval(`
+    // It tests evaluation order.
+    // Considering the expression A |> B, A should be evaluated before B.
+    let value = null;
+    const result = (value = 10, "42") |> (value = 20, parseInt);
+    assertEq(result, 42);
+    assertEq(value, 20);
+    `);
+}
+
+if (typeof reportCompare === "function")
+    reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_2018/Pipeline/parse-error.js
@@ -0,0 +1,18 @@
+const BUGNUMBER = 1405943;
+const summary = "Implement pipeline operator (parse error)";
+
+print(BUGNUMBER + ": " + summary);
+
+if (hasPipeline()) {
+    // Invalid Token
+    assertThrows(() => Function("2 | > parseInt"), SyntaxError);
+    assertThrows(() => Function("2 ||> parseInt"), SyntaxError);
+    assertThrows(() => Function("2 |>> parseInt"), SyntaxError);
+    assertThrows(() => Function("2 <| parseInt"), SyntaxError);
+    // Invalid Syntax
+    assertThrows(() => Function("2 |>"), SyntaxError);
+    assertThrows(() => Function("|> parseInt"), SyntaxError);
+}
+
+if (typeof reportCompare === "function")
+    reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_2018/Pipeline/precedence.js
@@ -0,0 +1,56 @@
+const BUGNUMBER = 1405943;
+const summary = "Implement pipeline operator (operator precedence)";
+
+print(BUGNUMBER + ": " + summary);
+
+if (hasPipeline()) {
+    // Operator precedence
+    eval(`
+    const double = (n) => n * 2;
+    const increment = (n) => n + 1;
+    const getType = (v) => typeof v;
+    const toString = (v) => v.toString();
+    let a = 8;
+    assertEq(10 |> double |> increment |> double, 42);
+    assertEq(++ a |> double, 18);
+    assertEq(typeof 42 |> toString, "number");
+    assertEq(! true |> toString, "false");
+    assertEq(delete 42 |> toString, "true");
+    assertEq(10 ** 2 |> double, 200);
+    assertEq(10 * 2 |> increment, 21);
+    assertEq(5 + 5 |> double, 20);
+    assertEq(1 << 4 |> double, 32);
+    assertEq(0 < 1 |> toString, "true");
+    assertEq("a" in {} |> toString, "false");
+    assertEq(10 instanceof String |> toString, "false");
+    assertEq(10 == 10 |> toString, "true");
+    assertEq(0b0101 & 0b1101 |> increment, 0b0110);
+    assertEq(false && true |> toString, "false");
+    assertEq(0 |> double ? toString : null, null);
+    assertEq(true ? 20 |> toString : 10, '20');
+    assertEq(true ? 10 : 20 |> toString, 10);
+    a = 10 |> toString;
+    assertEq(a, "10");
+    a = 10;
+    a += 2 |> increment;
+    assertEq(a, 13);
+
+    // Right-side association
+    a = toString;
+    assertThrowsInstanceOf(() => "42" |> parseInt ** 2, TypeError);
+    assertThrowsInstanceOf(() => "42" |> parseInt * 1, TypeError);
+    assertThrowsInstanceOf(() => "42" |> parseInt + 0, TypeError);
+    assertThrowsInstanceOf(() => "42" |> parseInt << 1, TypeError);
+    assertThrowsInstanceOf(() => "42" |> parseInt < 0, TypeError);
+    assertThrowsInstanceOf(() => "42" |> parseInt in {}, TypeError);
+    assertThrowsInstanceOf(() => "42" |> parseInt instanceof String, TypeError);
+    assertThrowsInstanceOf(() => "42" |> parseInt == 255, TypeError);
+    assertThrowsInstanceOf(() => "42" |> parseInt & 0b1111, TypeError);
+    assertThrowsInstanceOf(() => "42" |> parseInt && true, TypeError);
+    assertThrowsInstanceOf(() => Function('"42" |> a = parseInt'), ReferenceError);
+    assertThrowsInstanceOf(() => Function('"42" |> a += parseInt'), ReferenceError);
+    `);
+}
+
+if (typeof reportCompare === "function")
+    reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_2018/Pipeline/receiver.js
@@ -0,0 +1,24 @@
+const BUGNUMBER = 1405943;
+const summary = "Implement pipeline operator (receiver)";
+
+print(BUGNUMBER + ": " + summary);
+
+if (hasPipeline()) {
+    // Receiver
+    eval(`
+    const receiver = {
+        foo: function (value, extra) {
+            assertEq(value, 10);
+            assertEq(extra, undefined);
+            assertEq(arguments.length, 1);
+            assertEq(arguments[0], 10)
+            assertEq(this, receiver);
+        },
+    };
+
+    10 |> receiver.foo;
+    `);
+}
+
+if (typeof reportCompare === "function")
+    reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_2018/Pipeline/reflect-parse.js
@@ -0,0 +1,28 @@
+const BUGNUMBER = 1405943;
+const summary = "Implement pipeline operator (Reflect.parse)";
+
+print(BUGNUMBER + ": " + summary);
+
+if (hasPipeline()) {
+    if (typeof Reflect !== "undefined" && Reflect.parse) {
+        const parseTree1 = Reflect.parse("a |> b");
+        assertEq(parseTree1.body[0].type, "ExpressionStatement");
+        assertEq(parseTree1.body[0].expression.type, "BinaryExpression");
+        assertEq(parseTree1.body[0].expression.operator, "|>");
+        assertEq(parseTree1.body[0].expression.left.name, "a");
+        assertEq(parseTree1.body[0].expression.right.name, "b");
+
+        const parseTree2 = Reflect.parse("a |> b |> c");
+        assertEq(parseTree2.body[0].type, "ExpressionStatement");
+        assertEq(parseTree2.body[0].expression.type, "BinaryExpression");
+        assertEq(parseTree2.body[0].expression.operator, "|>");
+        assertEq(parseTree2.body[0].expression.left.type, "BinaryExpression");
+        assertEq(parseTree2.body[0].expression.left.operator, "|>");
+        assertEq(parseTree2.body[0].expression.left.left.name, "a");
+        assertEq(parseTree2.body[0].expression.left.right.name, "b");
+        assertEq(parseTree2.body[0].expression.right.name, "c");
+    }
+}
+
+if (typeof reportCompare === "function")
+    reportCompare(0, 0);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_2018/Pipeline/shell.js
@@ -0,0 +1,9 @@
+function hasPipeline() {
+    try {
+        Function('a |> a');
+    } catch (e) {
+        return false;
+    }
+
+    return true;
+}
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_2018/Pipeline/type-error.js
@@ -0,0 +1,22 @@
+const BUGNUMBER = 1405943;
+const summary = "Implement pipeline operator (type error)";
+
+print(BUGNUMBER + ": " + summary);
+
+if (hasPipeline()) {
+    // Type error
+    eval(`
+    assertThrowsInstanceOf(() => 10 |> 10, TypeError);
+    assertThrowsInstanceOf(() => 10 |> "foo", TypeError);
+    assertThrowsInstanceOf(() => 10 |> null, TypeError);
+    assertThrowsInstanceOf(() => 10 |> undefined, TypeError);
+    assertThrowsInstanceOf(() => 10 |> true, TypeError);
+    assertThrowsInstanceOf(() => 10 |> { a: 1 }, TypeError);
+    assertThrowsInstanceOf(() => 10 |> [ 0, 1 ], TypeError);
+    assertThrowsInstanceOf(() => 10 |> /regexp/, TypeError);
+    assertThrowsInstanceOf(() => 10 |> Symbol(), TypeError);
+    `);
+}
+
+if (typeof reportCompare === "function")
+    reportCompare(0, 0);