From 70a4d7e010785cf1857510aed711282b25f0c659 Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Thu, 17 Aug 2017 20:37:46 +0200 Subject: JS - RegExp - match updated spec for `/\b/iu` and `/\B/iu` --- .../RegExp/unicode-ignoreCase-word-boundary.js | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 js/src/tests/ecma_6/RegExp/unicode-ignoreCase-word-boundary.js (limited to 'js/src/tests/ecma_6/RegExp') 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); -- cgit v1.2.3 From 9384b08d877055a806bd61b2a3632897dfe4bbd8 Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Mon, 19 Mar 2018 10:46:14 +0100 Subject: Tests Issue #77 --- js/src/tests/ecma_6/RegExp/prototype.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 js/src/tests/ecma_6/RegExp/prototype.js (limited to 'js/src/tests/ecma_6/RegExp') 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); -- cgit v1.2.3 From 6822460d3b0d4609ee5d4e1ab4b093799ed06580 Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Mon, 19 Mar 2018 15:18:37 +0100 Subject: Bug 1317309: Throw a TypeError when passing a Symbol value to ToAtom Issue #78 [Depends on] Bug 883377: Implement ES6 function "name" property semantics --- js/src/tests/ecma_6/RegExp/compile-symbol.js | 14 ++++++++++++++ js/src/tests/ecma_6/RegExp/constructor-symbol.js | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 js/src/tests/ecma_6/RegExp/compile-symbol.js create mode 100644 js/src/tests/ecma_6/RegExp/constructor-symbol.js (limited to 'js/src/tests/ecma_6/RegExp') 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); -- cgit v1.2.3 From aae3a117342e8959c074ea9f36cefac772f608d3 Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Sat, 24 Mar 2018 15:54:49 +0100 Subject: Bug 1343375: Update RegExp.prototype.replace and .match to call ToLength(lastIndex) for non-global RegExp and handle recompilations [Depends on] Bug 1317397: Implement RegExp.lastIndex changes from ES2017 --- .../RegExp/match-local-tolength-recompilation.js | 75 ++++++++++++++++++++++ .../RegExp/replace-local-tolength-lastindex.js | 22 +++++++ .../RegExp/replace-local-tolength-recompilation.js | 75 ++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 js/src/tests/ecma_6/RegExp/match-local-tolength-recompilation.js create mode 100644 js/src/tests/ecma_6/RegExp/replace-local-tolength-lastindex.js create mode 100644 js/src/tests/ecma_6/RegExp/replace-local-tolength-recompilation.js (limited to 'js/src/tests/ecma_6/RegExp') 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..6cb286b8c --- /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, 0, "Update the expected value to |9001| after fixing 1317397"); + +// 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, 0, "Update the expected value to |9002| after fixing 1317397"); + +if (typeof reportCompare === "function") + reportCompare(true, true); 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..30002c3ed --- /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, 0, "Update the expected value to |9001| after fixing 1317397"); + +// 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, 0, "Update the expected value to |9002| after fixing 1317397"); + +if (typeof reportCompare === "function") + reportCompare(true, true); -- cgit v1.2.3 From 5fd5b2ac2f396eb1d8707a691aa26ad159ad25e3 Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Sat, 24 Mar 2018 16:01:06 +0100 Subject: Bug 1317397: Only set lastIndex for global or sticky RegExps in RegExpBuiltinExec per ES2017 --- js/src/tests/ecma_6/RegExp/compile-lastIndex.js | 34 +++++++++------------- .../RegExp/match-local-tolength-recompilation.js | 4 +-- .../RegExp/replace-local-tolength-recompilation.js | 4 +-- js/src/tests/ecma_6/RegExp/search-trace.js | 2 ++ 4 files changed, 20 insertions(+), 24 deletions(-) (limited to 'js/src/tests/ecma_6/RegExp') 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/match-local-tolength-recompilation.js b/js/src/tests/ecma_6/RegExp/match-local-tolength-recompilation.js index 6cb286b8c..9a992f81f 100644 --- a/js/src/tests/ecma_6/RegExp/match-local-tolength-recompilation.js +++ b/js/src/tests/ecma_6/RegExp/match-local-tolength-recompilation.js @@ -55,7 +55,7 @@ regExp.lastIndex = { } }; regExp[Symbol.match]("a"); -assertEq(regExp.lastIndex, 0, "Update the expected value to |9001| after fixing 1317397"); +assertEq(regExp.lastIndex, 9001); // Case 3.b: Removes sticky flag without match, validate by checking lastIndex. var regExp = new RegExp("a", "y"); @@ -69,7 +69,7 @@ regExp.lastIndex = { } }; regExp[Symbol.match]("a"); -assertEq(regExp.lastIndex, 0, "Update the expected value to |9002| after fixing 1317397"); +assertEq(regExp.lastIndex, 9002); 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 index 30002c3ed..e03177286 100644 --- a/js/src/tests/ecma_6/RegExp/replace-local-tolength-recompilation.js +++ b/js/src/tests/ecma_6/RegExp/replace-local-tolength-recompilation.js @@ -55,7 +55,7 @@ regExp.lastIndex = { } }; regExp[Symbol.replace]("a", ""); -assertEq(regExp.lastIndex, 0, "Update the expected value to |9001| after fixing 1317397"); +assertEq(regExp.lastIndex, 9001); // Case 3.b: Removes sticky flag without match, validate by checking lastIndex. var regExp = new RegExp("a", "y"); @@ -69,7 +69,7 @@ regExp.lastIndex = { } }; regExp[Symbol.replace]("a", ""); -assertEq(regExp.lastIndex, 0, "Update the expected value to |9002| after fixing 1317397"); +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") -- cgit v1.2.3