summaryrefslogtreecommitdiffstats
path: root/js/src/tests/ecma_6/RegExp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/tests/ecma_6/RegExp')
-rw-r--r--js/src/tests/ecma_6/RegExp/compile-lastIndex.js34
-rw-r--r--js/src/tests/ecma_6/RegExp/compile-symbol.js14
-rw-r--r--js/src/tests/ecma_6/RegExp/constructor-symbol.js14
-rw-r--r--js/src/tests/ecma_6/RegExp/match-local-tolength-recompilation.js75
-rw-r--r--js/src/tests/ecma_6/RegExp/prototype.js31
-rw-r--r--js/src/tests/ecma_6/RegExp/replace-local-tolength-lastindex.js22
-rw-r--r--js/src/tests/ecma_6/RegExp/replace-local-tolength-recompilation.js75
-rw-r--r--js/src/tests/ecma_6/RegExp/search-trace.js2
-rw-r--r--js/src/tests/ecma_6/RegExp/unicode-ignoreCase-word-boundary.js25
9 files changed, 272 insertions, 20 deletions
diff --git a/js/src/tests/ecma_6/RegExp/compile-lastIndex.js b/js/src/tests/ecma_6/RegExp/compile-lastIndex.js
index 80c820f43..5bd7e0b98 100644
--- a/js/src/tests/ecma_6/RegExp/compile-lastIndex.js
+++ b/js/src/tests/ecma_6/RegExp/compile-lastIndex.js
@@ -17,15 +17,12 @@ print(BUGNUMBER + ": " + summary);
var regex = /foo/i;
-// Aside from making .lastIndex non-writable, this has two incidental effects
+// Aside from making .lastIndex non-writable, this has one incidental effect
// ubiquitously tested through the remainder of this test:
//
// * RegExp.prototype.compile will do everything it ordinarily does, BUT it
// will throw a TypeError when attempting to zero .lastIndex immediately
// before succeeding overall.
-// * RegExp.prototype.test for a non-global and non-sticky regular expression,
-// in case of a match, will return true (as normal). BUT if no match is
-// found, it will throw a TypeError when attempting to modify .lastIndex.
//
// Ain't it great?
Object.defineProperty(regex, "lastIndex", { value: 42, writable: false });
@@ -40,8 +37,8 @@ assertEq(regex.lastIndex, 42);
assertEq(regex.test("foo"), true);
assertEq(regex.test("FOO"), true);
-assertThrowsInstanceOf(() => regex.test("bar"), TypeError);
-assertThrowsInstanceOf(() => regex.test("BAR"), TypeError);
+assertEq(regex.test("bar"), false);
+assertEq(regex.test("BAR"), false);
assertThrowsInstanceOf(() => regex.compile("bar"), TypeError);
@@ -52,10 +49,10 @@ assertEq(regex.unicode, false);
assertEq(regex.sticky, false);
assertEq(Object.getOwnPropertyDescriptor(regex, "lastIndex").writable, false);
assertEq(regex.lastIndex, 42);
-assertThrowsInstanceOf(() => regex.test("foo"), TypeError);
-assertThrowsInstanceOf(() => regex.test("FOO"), TypeError);
+assertEq(regex.test("foo"), false);
+assertEq(regex.test("FOO"), false);
assertEq(regex.test("bar"), true);
-assertThrowsInstanceOf(() => regex.test("BAR"), TypeError);
+assertEq(regex.test("BAR"), false);
assertThrowsInstanceOf(() => regex.compile("^baz", "m"), TypeError);
@@ -66,19 +63,16 @@ assertEq(regex.unicode, false);
assertEq(regex.sticky, false);
assertEq(Object.getOwnPropertyDescriptor(regex, "lastIndex").writable, false);
assertEq(regex.lastIndex, 42);
-assertThrowsInstanceOf(() => regex.test("foo"), TypeError);
-assertThrowsInstanceOf(() => regex.test("FOO"), TypeError);
-assertThrowsInstanceOf(() => regex.test("bar"), TypeError);
-assertThrowsInstanceOf(() => regex.test("BAR"), TypeError);
+assertEq(regex.test("foo"), false);
+assertEq(regex.test("FOO"), false);
+assertEq(regex.test("bar"), false);
+assertEq(regex.test("BAR"), false);
assertEq(regex.test("baz"), true);
-assertThrowsInstanceOf(() => regex.test("BAZ"), TypeError);
-assertThrowsInstanceOf(() => regex.test("012345678901234567890123456789012345678901baz"),
- TypeError);
+assertEq(regex.test("BAZ"), false);
+assertEq(regex.test("012345678901234567890123456789012345678901baz"), false);
assertEq(regex.test("012345678901234567890123456789012345678901\nbaz"), true);
-assertThrowsInstanceOf(() => regex.test("012345678901234567890123456789012345678901BAZ"),
- TypeError);
-assertThrowsInstanceOf(() => regex.test("012345678901234567890123456789012345678901\nBAZ"),
- TypeError);
+assertEq(regex.test("012345678901234567890123456789012345678901BAZ"), false);
+assertEq(regex.test("012345678901234567890123456789012345678901\nBAZ"), false);
/******************************************************************************/
diff --git a/js/src/tests/ecma_6/RegExp/compile-symbol.js b/js/src/tests/ecma_6/RegExp/compile-symbol.js
new file mode 100644
index 000000000..9eea1124c
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/compile-symbol.js
@@ -0,0 +1,14 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+for (let sym of [Symbol.iterator, Symbol(), Symbol("description")]) {
+ let re = /a/;
+
+ assertEq(re.source, "a");
+ assertThrowsInstanceOf(() => re.compile(sym), TypeError);
+ assertEq(re.source, "a");
+}
+
+if (typeof reportCompare === 'function')
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/RegExp/constructor-symbol.js b/js/src/tests/ecma_6/RegExp/constructor-symbol.js
new file mode 100644
index 000000000..503d7e5a8
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/constructor-symbol.js
@@ -0,0 +1,14 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+for (let sym of [Symbol.iterator, Symbol(), Symbol("description")]) {
+ assertThrowsInstanceOf(() => RegExp(sym), TypeError);
+ assertThrowsInstanceOf(() => new RegExp(sym), TypeError);
+
+ assertThrowsInstanceOf(() => RegExp(sym, "g"), TypeError);
+ assertThrowsInstanceOf(() => new RegExp(sym, "g"), TypeError);
+}
+
+if (typeof reportCompare === 'function')
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/RegExp/match-local-tolength-recompilation.js b/js/src/tests/ecma_6/RegExp/match-local-tolength-recompilation.js
new file mode 100644
index 000000000..9a992f81f
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/match-local-tolength-recompilation.js
@@ -0,0 +1,75 @@
+// Side-effects when calling ToLength(regExp.lastIndex) in
+// RegExp.prototype[@@match] for non-global RegExp can recompile the RegExp.
+
+for (var flag of ["", "y"]) {
+ var regExp = new RegExp("a", flag);
+
+ regExp.lastIndex = {
+ valueOf() {
+ regExp.compile("b");
+ return 0;
+ }
+ };
+
+ var result = regExp[Symbol.match]("b");
+ assertEq(result !== null, true);
+}
+
+// Recompilation modifies flag:
+// Case 1: Adds global flag, validate by checking lastIndex.
+var regExp = new RegExp("a", "");
+regExp.lastIndex = {
+ valueOf() {
+ // |regExp| is now in global mode, RegExpBuiltinExec should update the
+ // lastIndex property to reflect last match.
+ regExp.compile("a", "g");
+ return 0;
+ }
+};
+regExp[Symbol.match]("a");
+assertEq(regExp.lastIndex, 1);
+
+// Case 2: Removes sticky flag with match, validate by checking lastIndex.
+var regExp = new RegExp("a", "y");
+regExp.lastIndex = {
+ valueOf() {
+ // |regExp| is no longer sticky, RegExpBuiltinExec shouldn't modify the
+ // lastIndex property.
+ regExp.compile("a", "");
+ regExp.lastIndex = 9000;
+ return 0;
+ }
+};
+regExp[Symbol.match]("a");
+assertEq(regExp.lastIndex, 9000);
+
+// Case 3.a: Removes sticky flag without match, validate by checking lastIndex.
+var regExp = new RegExp("a", "y");
+regExp.lastIndex = {
+ valueOf() {
+ // |regExp| is no longer sticky, RegExpBuiltinExec shouldn't modify the
+ // lastIndex property.
+ regExp.compile("b", "");
+ regExp.lastIndex = 9001;
+ return 0;
+ }
+};
+regExp[Symbol.match]("a");
+assertEq(regExp.lastIndex, 9001);
+
+// Case 3.b: Removes sticky flag without match, validate by checking lastIndex.
+var regExp = new RegExp("a", "y");
+regExp.lastIndex = {
+ valueOf() {
+ // |regExp| is no longer sticky, RegExpBuiltinExec shouldn't modify the
+ // lastIndex property.
+ regExp.compile("b", "");
+ regExp.lastIndex = 9002;
+ return 10000;
+ }
+};
+regExp[Symbol.match]("a");
+assertEq(regExp.lastIndex, 9002);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/prototype.js b/js/src/tests/ecma_6/RegExp/prototype.js
new file mode 100644
index 000000000..528142ab0
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/prototype.js
@@ -0,0 +1,31 @@
+const t = RegExp.prototype;
+
+const properties = "toSource,toString,compile,exec,test," +
+ "flags,global,ignoreCase,multiline,source,sticky,unicode," +
+ "constructor," +
+ "Symbol(Symbol.match),Symbol(Symbol.replace),Symbol(Symbol.search),Symbol(Symbol.split)";
+assertEq(Reflect.ownKeys(t).map(String).toString(), properties);
+
+
+// Invoking getters on the prototype should not throw
+function getter(name) {
+ return Object.getOwnPropertyDescriptor(t, name).get.call(t);
+}
+
+assertEq(getter("flags"), "");
+assertEq(getter("global"), undefined);
+assertEq(getter("ignoreCase"), undefined);
+assertEq(getter("multiline"), undefined);
+assertEq(getter("source"), "(?:)");
+assertEq(getter("sticky"), undefined);
+assertEq(getter("unicode"), undefined);
+
+assertEq(t.toString(), "/(?:)/");
+
+// The methods don't work with the prototype
+assertThrowsInstanceOf(() => t.compile("b", "i"), TypeError);
+assertThrowsInstanceOf(() => t.test("x"), TypeError);
+assertThrowsInstanceOf(() => t.exec("x"), TypeError);
+
+if (typeof reportCompare === "function")
+ reportCompare(0, 0);
diff --git a/js/src/tests/ecma_6/RegExp/replace-local-tolength-lastindex.js b/js/src/tests/ecma_6/RegExp/replace-local-tolength-lastindex.js
new file mode 100644
index 000000000..7ba840e00
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/replace-local-tolength-lastindex.js
@@ -0,0 +1,22 @@
+// RegExp.prototype[@@replace] always executes ToLength(regExp.lastIndex) for
+// non-global RegExps.
+
+for (var flag of ["", "g", "y", "gy"]) {
+ var regExp = new RegExp("a", flag);
+
+ var called = false;
+ regExp.lastIndex = {
+ valueOf() {
+ assertEq(called, false);
+ called = true;
+ return 0;
+ }
+ };
+
+ assertEq(called, false);
+ regExp[Symbol.replace]("");
+ assertEq(called, !flag.includes("g"));
+}
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/replace-local-tolength-recompilation.js b/js/src/tests/ecma_6/RegExp/replace-local-tolength-recompilation.js
new file mode 100644
index 000000000..e03177286
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/replace-local-tolength-recompilation.js
@@ -0,0 +1,75 @@
+// Side-effects when calling ToLength(regExp.lastIndex) in
+// RegExp.prototype[@@replace] for non-global RegExp can recompile the RegExp.
+
+for (var flag of ["", "y"]) {
+ var regExp = new RegExp("a", flag);
+
+ regExp.lastIndex = {
+ valueOf() {
+ regExp.compile("b");
+ return 0;
+ }
+ };
+
+ var result = regExp[Symbol.replace]("b", "pass");
+ assertEq(result, "pass");
+}
+
+// Recompilation modifies flag:
+// Case 1: Adds global flag, validate by checking lastIndex.
+var regExp = new RegExp("a", "");
+regExp.lastIndex = {
+ valueOf() {
+ // |regExp| is now in global mode, RegExpBuiltinExec should update the
+ // lastIndex property to reflect last match.
+ regExp.compile("a", "g");
+ return 0;
+ }
+};
+regExp[Symbol.replace]("a", "");
+assertEq(regExp.lastIndex, 1);
+
+// Case 2: Removes sticky flag with match, validate by checking lastIndex.
+var regExp = new RegExp("a", "y");
+regExp.lastIndex = {
+ valueOf() {
+ // |regExp| is no longer sticky, RegExpBuiltinExec shouldn't modify the
+ // lastIndex property.
+ regExp.compile("a", "");
+ regExp.lastIndex = 9000;
+ return 0;
+ }
+};
+regExp[Symbol.replace]("a", "");
+assertEq(regExp.lastIndex, 9000);
+
+// Case 3.a: Removes sticky flag without match, validate by checking lastIndex.
+var regExp = new RegExp("a", "y");
+regExp.lastIndex = {
+ valueOf() {
+ // |regExp| is no longer sticky, RegExpBuiltinExec shouldn't modify the
+ // lastIndex property.
+ regExp.compile("b", "");
+ regExp.lastIndex = 9001;
+ return 0;
+ }
+};
+regExp[Symbol.replace]("a", "");
+assertEq(regExp.lastIndex, 9001);
+
+// Case 3.b: Removes sticky flag without match, validate by checking lastIndex.
+var regExp = new RegExp("a", "y");
+regExp.lastIndex = {
+ valueOf() {
+ // |regExp| is no longer sticky, RegExpBuiltinExec shouldn't modify the
+ // lastIndex property.
+ regExp.compile("b", "");
+ regExp.lastIndex = 9002;
+ return 10000;
+ }
+};
+regExp[Symbol.replace]("a", "");
+assertEq(regExp.lastIndex, 9002);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);
diff --git a/js/src/tests/ecma_6/RegExp/search-trace.js b/js/src/tests/ecma_6/RegExp/search-trace.js
index ef14514c6..fc6bee754 100644
--- a/js/src/tests/ecma_6/RegExp/search-trace.js
+++ b/js/src/tests/ecma_6/RegExp/search-trace.js
@@ -56,6 +56,7 @@ assertEq(log,
"get:lastIndex," +
"set:lastIndex," +
"get:exec,call:exec," +
+ "get:lastIndex," +
"set:lastIndex," +
"get:result[index],");
@@ -70,6 +71,7 @@ assertEq(log,
"get:lastIndex," +
"set:lastIndex," +
"get:exec,call:exec," +
+ "get:lastIndex," +
"set:lastIndex,");
if (typeof reportCompare === "function")
diff --git a/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-word-boundary.js b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-word-boundary.js
new file mode 100644
index 000000000..c1a04bd3d
--- /dev/null
+++ b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-word-boundary.js
@@ -0,0 +1,25 @@
+var BUGNUMBER = 1338373;
+var summary = "Word boundary should match U+017F and U+212A in unicode+ignoreCase.";
+
+assertEq(/\b/iu.test('\u017F'), true);
+assertEq(/\b/i.test('\u017F'), false);
+assertEq(/\b/u.test('\u017F'), false);
+assertEq(/\b/.test('\u017F'), false);
+
+assertEq(/\b/iu.test('\u212A'), true);
+assertEq(/\b/i.test('\u212A'), false);
+assertEq(/\b/u.test('\u212A'), false);
+assertEq(/\b/.test('\u212A'), false);
+
+assertEq(/\B/iu.test('\u017F'), false);
+assertEq(/\B/i.test('\u017F'), true);
+assertEq(/\B/u.test('\u017F'), true);
+assertEq(/\B/.test('\u017F'), true);
+
+assertEq(/\B/iu.test('\u212A'), false);
+assertEq(/\B/i.test('\u212A'), true);
+assertEq(/\B/u.test('\u212A'), true);
+assertEq(/\B/.test('\u212A'), true);
+
+if (typeof reportCompare === "function")
+ reportCompare(true, true);