summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/Math/Pow.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/non262/Math/Pow.js')
-rw-r--r--js/src/tests/non262/Math/Pow.js117
1 files changed, 117 insertions, 0 deletions
diff --git a/js/src/tests/non262/Math/Pow.js b/js/src/tests/non262/Math/Pow.js
new file mode 100644
index 0000000000..281c716a76
--- /dev/null
+++ b/js/src/tests/non262/Math/Pow.js
@@ -0,0 +1,117 @@
+// |reftest| skip-if(!xulRuntime.shell)
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var BUGNUMBER = 1135708;
+var summary = "Implement the exponentiation operator";
+
+print(BUGNUMBER + ": " + summary);
+
+// Constant folding
+assertEq(2 ** 2 ** 3, 256);
+assertEq(1 ** 1 ** 4, 1);
+
+// No folding
+var two = 2;
+var three = 3;
+var four = 4;
+assertEq(two ** two ** three, 256);
+assertEq(1 ** 1 ** four, 1);
+
+// Operator precedence
+assertEq(2 ** 3 / 2 ** 3, 1);
+assertEq(2 ** 3 * 2 ** 3, 64);
+assertEq(2 ** 3 + 2 ** 3, 16);
+
+// With parentheses
+assertEq((2 ** 3) ** 2, 64);
+assertEq(2 ** (3 ** 2), 512);
+
+// Assignment operator
+var x = 2;
+assertEq(x **= 2 ** 3, 256);
+assertEq(x, 256);
+
+// Loop to test baseline and ION
+for (var i=0; i<10000; i++) {
+ assertEq((2 ** 3) ** 2, 64);
+ assertEq(2 ** (3 ** 2), 512);
+ var x = 2;
+ assertEq(x **= 2 ** 3, 256);
+ assertEq(x, 256);
+}
+
+// Comments should not be confused with exp operator
+var a, c, e;
+a = c = e = 2;
+assertEq(a**/**b**/c/**/**/**d**/e, 16);
+
+// Two stars separated should not parse as exp operator
+assertThrowsInstanceOf(function() { return Reflect.parse("2 * * 3"); }, SyntaxError);
+
+// Left-hand side expression must not be a unary expression.
+for (let unaryOp of ["delete", "typeof", "void", "+", "-", "!", "~"]) {
+ assertThrowsInstanceOf(() => eval(unaryOp + " a ** 2"), SyntaxError);
+ assertThrowsInstanceOf(() => eval(unaryOp + " " + unaryOp + " a ** 2"), SyntaxError);
+}
+
+// Test the other |delete| operators (DELETENAME and DELETEEXPR are already tested above).
+assertThrowsInstanceOf(() => eval("delete a.name ** 2"), SyntaxError);
+assertThrowsInstanceOf(() => eval("delete a[0] ** 2"), SyntaxError);
+
+// Unary expression lhs is valid if parenthesized.
+for (let unaryOp of ["delete", "void", "+", "-", "!", "~"]) {
+ let a = 0;
+ eval("(" + unaryOp + " a) ** 2");
+ eval("(" + unaryOp + " " + unaryOp + " a) ** 2");
+}
+{
+ let a = {};
+ (delete a.name) ** 2;
+ (delete a[0]) ** 2;
+}
+
+// Check if error propagation works
+var thrower = {
+ get value() {
+ throw new Error();
+ }
+};
+
+assertThrowsInstanceOf(function() { return thrower.value ** 2; }, Error);
+assertThrowsInstanceOf(function() { return 2 ** thrower.value; }, Error);
+assertThrowsInstanceOf(function() { return 2 ** thrower.value ** 2; }, Error);
+
+var convertibleToPrimitive = {
+ valueOf: function() {
+ throw new Error("oops");
+ }
+};
+
+assertThrowsInstanceOf(function() { return convertibleToPrimitive ** 3; }, Error);
+assertThrowsInstanceOf(function() { return 3 ** convertibleToPrimitive; }, Error);
+
+assertEq(NaN ** 2, NaN);
+assertEq(2 ** NaN, NaN);
+assertEq(2 ** "3", 8);
+assertEq("2" ** 3, 8);
+
+// Reflect.parse generates a correct parse tree for simplest case
+var parseTree = Reflect.parse("a ** b");
+assertEq(parseTree.body[0].type, "ExpressionStatement");
+assertEq(parseTree.body[0].expression.operator, "**");
+assertEq(parseTree.body[0].expression.left.name, "a");
+assertEq(parseTree.body[0].expression.right.name, "b");
+
+// Reflect.parse generates a tree following the right-associativity rule
+var parseTree = Reflect.parse("a ** b ** c");
+assertEq(parseTree.body[0].type, "ExpressionStatement");
+assertEq(parseTree.body[0].expression.left.name, "a");
+assertEq(parseTree.body[0].expression.right.operator, "**");
+assertEq(parseTree.body[0].expression.right.left.name, "b");
+assertEq(parseTree.body[0].expression.right.right.name, "c");
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);