From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- js/src/tests/ecma_6/RegExp/RegExpExec-exec.js | 18 + js/src/tests/ecma_6/RegExp/RegExpExec-return.js | 31 + js/src/tests/ecma_6/RegExp/browser.js | 0 js/src/tests/ecma_6/RegExp/class-null.js | 15 + js/src/tests/ecma_6/RegExp/compile-lastIndex.js | 88 + js/src/tests/ecma_6/RegExp/constructor-IsRegExp.js | 86 + .../tests/ecma_6/RegExp/constructor-constructor.js | 78 + .../tests/ecma_6/RegExp/constructor-ordering-2.js | 21 + js/src/tests/ecma_6/RegExp/constructor-ordering.js | 16 + .../ecma_6/RegExp/constructor-regexp-unicode.js | 9 + js/src/tests/ecma_6/RegExp/constructor-regexp.js | 61 + js/src/tests/ecma_6/RegExp/descriptor.js | 25 + js/src/tests/ecma_6/RegExp/escape.js | 70 + .../tests/ecma_6/RegExp/exec-lastIndex-negative.js | 27 + js/src/tests/ecma_6/RegExp/flag-accessors.js | 49 + js/src/tests/ecma_6/RegExp/flags-param-handling.js | 18 + js/src/tests/ecma_6/RegExp/flags.js | 26 + js/src/tests/ecma_6/RegExp/getter-name.js | 16 + js/src/tests/ecma_6/RegExp/ignoreCase-multiple.js | 71 + .../tests/ecma_6/RegExp/lastIndex-nonwritable.js | 27 + js/src/tests/ecma_6/RegExp/match-this.js | 12 + js/src/tests/ecma_6/RegExp/match-trace.js | 147 ++ js/src/tests/ecma_6/RegExp/match.js | 36 + js/src/tests/ecma_6/RegExp/replace-compile.js | 21 + .../tests/ecma_6/RegExp/replace-global-unicode.js | 18 + .../ecma_6/RegExp/replace-sticky-lastIndex.js | 23 + js/src/tests/ecma_6/RegExp/replace-sticky.js | 21 + js/src/tests/ecma_6/RegExp/replace-this.js | 12 + js/src/tests/ecma_6/RegExp/replace-trace.js | 309 +++ js/src/tests/ecma_6/RegExp/replace-twoBytes.js | 44 + js/src/tests/ecma_6/RegExp/replace.js | 34 + js/src/tests/ecma_6/RegExp/search-this.js | 12 + js/src/tests/ecma_6/RegExp/search-trace.js | 76 + js/src/tests/ecma_6/RegExp/search.js | 26 + js/src/tests/ecma_6/RegExp/shell.js | 0 js/src/tests/ecma_6/RegExp/source.js | 29 + js/src/tests/ecma_6/RegExp/split-deleted-flags.js | 11 + js/src/tests/ecma_6/RegExp/split-flags-on-obj.js | 21 + .../tests/ecma_6/RegExp/split-invalid-lastIndex.js | 31 + js/src/tests/ecma_6/RegExp/split-limit.js | 14 + js/src/tests/ecma_6/RegExp/split-obj.js | 12 + js/src/tests/ecma_6/RegExp/split-prop-access.js | 19 + js/src/tests/ecma_6/RegExp/split-this.js | 12 + js/src/tests/ecma_6/RegExp/split-trace.js | 229 ++ js/src/tests/ecma_6/RegExp/split.js | 30 + js/src/tests/ecma_6/RegExp/sticky.js | 126 + js/src/tests/ecma_6/RegExp/test-trailing.js | 31 + js/src/tests/ecma_6/RegExp/toString.js | 42 + .../tests/ecma_6/RegExp/unicode-back-reference.js | 39 + js/src/tests/ecma_6/RegExp/unicode-braced.js | 166 ++ .../RegExp/unicode-character-class-escape.js | 75 + js/src/tests/ecma_6/RegExp/unicode-class-braced.js | 236 ++ js/src/tests/ecma_6/RegExp/unicode-class-empty.js | 25 + .../ecma_6/RegExp/unicode-class-ignoreCase.js | 28 + .../ecma_6/RegExp/unicode-class-lead-trail.js | 142 ++ .../tests/ecma_6/RegExp/unicode-class-negated.js | 64 + js/src/tests/ecma_6/RegExp/unicode-class-range.js | 28 + js/src/tests/ecma_6/RegExp/unicode-class-raw.js | 65 + .../ecma_6/RegExp/unicode-disallow-extended.js | 117 + js/src/tests/ecma_6/RegExp/unicode-everything.js | 59 + .../ecma_6/RegExp/unicode-ignoreCase-ascii.js | 45 + .../ecma_6/RegExp/unicode-ignoreCase-escape.js | 71 + .../ecma_6/RegExp/unicode-ignoreCase-negated.js | 19 + js/src/tests/ecma_6/RegExp/unicode-ignoreCase.js | 2643 ++++++++++++++++++++ js/src/tests/ecma_6/RegExp/unicode-index.js | 17 + js/src/tests/ecma_6/RegExp/unicode-lead-trail.js | 218 ++ js/src/tests/ecma_6/RegExp/unicode-raw.js | 139 + 67 files changed, 6346 insertions(+) create mode 100644 js/src/tests/ecma_6/RegExp/RegExpExec-exec.js create mode 100644 js/src/tests/ecma_6/RegExp/RegExpExec-return.js create mode 100644 js/src/tests/ecma_6/RegExp/browser.js create mode 100644 js/src/tests/ecma_6/RegExp/class-null.js create mode 100644 js/src/tests/ecma_6/RegExp/compile-lastIndex.js create mode 100644 js/src/tests/ecma_6/RegExp/constructor-IsRegExp.js create mode 100644 js/src/tests/ecma_6/RegExp/constructor-constructor.js create mode 100644 js/src/tests/ecma_6/RegExp/constructor-ordering-2.js create mode 100644 js/src/tests/ecma_6/RegExp/constructor-ordering.js create mode 100644 js/src/tests/ecma_6/RegExp/constructor-regexp-unicode.js create mode 100644 js/src/tests/ecma_6/RegExp/constructor-regexp.js create mode 100644 js/src/tests/ecma_6/RegExp/descriptor.js create mode 100644 js/src/tests/ecma_6/RegExp/escape.js create mode 100644 js/src/tests/ecma_6/RegExp/exec-lastIndex-negative.js create mode 100644 js/src/tests/ecma_6/RegExp/flag-accessors.js create mode 100644 js/src/tests/ecma_6/RegExp/flags-param-handling.js create mode 100644 js/src/tests/ecma_6/RegExp/flags.js create mode 100644 js/src/tests/ecma_6/RegExp/getter-name.js create mode 100644 js/src/tests/ecma_6/RegExp/ignoreCase-multiple.js create mode 100644 js/src/tests/ecma_6/RegExp/lastIndex-nonwritable.js create mode 100644 js/src/tests/ecma_6/RegExp/match-this.js create mode 100644 js/src/tests/ecma_6/RegExp/match-trace.js create mode 100644 js/src/tests/ecma_6/RegExp/match.js create mode 100644 js/src/tests/ecma_6/RegExp/replace-compile.js create mode 100644 js/src/tests/ecma_6/RegExp/replace-global-unicode.js create mode 100644 js/src/tests/ecma_6/RegExp/replace-sticky-lastIndex.js create mode 100644 js/src/tests/ecma_6/RegExp/replace-sticky.js create mode 100644 js/src/tests/ecma_6/RegExp/replace-this.js create mode 100644 js/src/tests/ecma_6/RegExp/replace-trace.js create mode 100644 js/src/tests/ecma_6/RegExp/replace-twoBytes.js create mode 100644 js/src/tests/ecma_6/RegExp/replace.js create mode 100644 js/src/tests/ecma_6/RegExp/search-this.js create mode 100644 js/src/tests/ecma_6/RegExp/search-trace.js create mode 100644 js/src/tests/ecma_6/RegExp/search.js create mode 100644 js/src/tests/ecma_6/RegExp/shell.js create mode 100644 js/src/tests/ecma_6/RegExp/source.js create mode 100644 js/src/tests/ecma_6/RegExp/split-deleted-flags.js create mode 100644 js/src/tests/ecma_6/RegExp/split-flags-on-obj.js create mode 100644 js/src/tests/ecma_6/RegExp/split-invalid-lastIndex.js create mode 100644 js/src/tests/ecma_6/RegExp/split-limit.js create mode 100644 js/src/tests/ecma_6/RegExp/split-obj.js create mode 100644 js/src/tests/ecma_6/RegExp/split-prop-access.js create mode 100644 js/src/tests/ecma_6/RegExp/split-this.js create mode 100644 js/src/tests/ecma_6/RegExp/split-trace.js create mode 100644 js/src/tests/ecma_6/RegExp/split.js create mode 100644 js/src/tests/ecma_6/RegExp/sticky.js create mode 100644 js/src/tests/ecma_6/RegExp/test-trailing.js create mode 100644 js/src/tests/ecma_6/RegExp/toString.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-back-reference.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-braced.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-character-class-escape.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-class-braced.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-class-empty.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-class-ignoreCase.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-class-lead-trail.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-class-negated.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-class-range.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-class-raw.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-disallow-extended.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-everything.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-ignoreCase-ascii.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-ignoreCase-escape.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-ignoreCase-negated.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-ignoreCase.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-index.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-lead-trail.js create mode 100644 js/src/tests/ecma_6/RegExp/unicode-raw.js (limited to 'js/src/tests/ecma_6/RegExp') diff --git a/js/src/tests/ecma_6/RegExp/RegExpExec-exec.js b/js/src/tests/ecma_6/RegExp/RegExpExec-exec.js new file mode 100644 index 000000000..e92792fcf --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/RegExpExec-exec.js @@ -0,0 +1,18 @@ +var BUGNUMBER = 887016; +var summary = "RegExpExec should throw if exec property of non-RegExp is not callable"; + +print(BUGNUMBER + ": " + summary); + +for (var exec of [null, 0, false, undefined, ""]) { + // RegExp with non-callable exec + var re = /a/; + re.exec = exec; + RegExp.prototype[Symbol.match].call(re, "foo"); + + // non-RegExp with non-callable exec + assertThrowsInstanceOf(() => RegExp.prototype[Symbol.match].call({ exec }, "foo"), + TypeError); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/RegExpExec-return.js b/js/src/tests/ecma_6/RegExp/RegExpExec-return.js new file mode 100644 index 000000000..1148aac07 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/RegExpExec-return.js @@ -0,0 +1,31 @@ +var BUGNUMBER = 887016; +var summary = "RegExpExec should throw if returned value is not an object nor null."; + +print(BUGNUMBER + ": " + summary); + +for (var ret of [null, {}, [], /a/]) { + assertEq(RegExp.prototype[Symbol.match].call({ + get global() { + return false; + }, + exec(S) { + return ret; + } + }, "foo"), ret); +} + +for (ret of [undefined, 1, true, false, Symbol.iterator]) { + assertThrowsInstanceOf(() => { + RegExp.prototype[Symbol.match].call({ + get global() { + return false; + }, + exec(S) { + return ret; + } + }, "foo"); + }, TypeError); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/browser.js b/js/src/tests/ecma_6/RegExp/browser.js new file mode 100644 index 000000000..e69de29bb diff --git a/js/src/tests/ecma_6/RegExp/class-null.js b/js/src/tests/ecma_6/RegExp/class-null.js new file mode 100644 index 000000000..c95e5a4d7 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/class-null.js @@ -0,0 +1,15 @@ +var BUGNUMBER = 1279467; +var summary = "Null in character class in RegExp with unicode flag."; + +print(BUGNUMBER + ": " + summary); + +var m = /([\0]+)/u.exec("\u0000"); +assertEq(m.length, 2); +assertEq(m[0], '\u0000'); +assertEq(m[1], '\u0000'); + +var m = /([\0]+)/u.exec("0"); +assertEq(m, null); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/compile-lastIndex.js b/js/src/tests/ecma_6/RegExp/compile-lastIndex.js new file mode 100644 index 000000000..80c820f43 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/compile-lastIndex.js @@ -0,0 +1,88 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var BUGNUMBER = 1253099; +var summary = + "RegExp.prototype.compile must perform all its steps *except* setting " + + ".lastIndex, then throw, when provided a RegExp whose .lastIndex has been " + + "made non-writable"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var regex = /foo/i; + +// Aside from making .lastIndex non-writable, this has two incidental effects +// 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 }); + +assertEq(regex.global, false); +assertEq(regex.ignoreCase, true); +assertEq(regex.multiline, false); +assertEq(regex.unicode, false); +assertEq(regex.sticky, false); +assertEq(Object.getOwnPropertyDescriptor(regex, "lastIndex").writable, false); +assertEq(regex.lastIndex, 42); + +assertEq(regex.test("foo"), true); +assertEq(regex.test("FOO"), true); +assertThrowsInstanceOf(() => regex.test("bar"), TypeError); +assertThrowsInstanceOf(() => regex.test("BAR"), TypeError); + +assertThrowsInstanceOf(() => regex.compile("bar"), TypeError); + +assertEq(regex.global, false); +assertEq(regex.ignoreCase, false); +assertEq(regex.multiline, false); +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("bar"), true); +assertThrowsInstanceOf(() => regex.test("BAR"), TypeError); + +assertThrowsInstanceOf(() => regex.compile("^baz", "m"), TypeError); + +assertEq(regex.global, false); +assertEq(regex.ignoreCase, false); +assertEq(regex.multiline, true); +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("baz"), true); +assertThrowsInstanceOf(() => regex.test("BAZ"), TypeError); +assertThrowsInstanceOf(() => regex.test("012345678901234567890123456789012345678901baz"), + TypeError); +assertEq(regex.test("012345678901234567890123456789012345678901\nbaz"), true); +assertThrowsInstanceOf(() => regex.test("012345678901234567890123456789012345678901BAZ"), + TypeError); +assertThrowsInstanceOf(() => regex.test("012345678901234567890123456789012345678901\nBAZ"), + TypeError); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/ecma_6/RegExp/constructor-IsRegExp.js b/js/src/tests/ecma_6/RegExp/constructor-IsRegExp.js new file mode 100644 index 000000000..8c735e4b9 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/constructor-IsRegExp.js @@ -0,0 +1,86 @@ +var BUGNUMBER = 1147817; +var summary = "RegExp constructor with pattern with @@match."; + +print(BUGNUMBER + ": " + summary); + +var matchValue; +var constructorValue; + +var matchGet; +var constructorGet; +var sourceGet; +var flagsGet; +function reset() { + matchGet = false; + constructorGet = false; + sourceGet = false; + flagsGet = false; +} +var obj = { + get [Symbol.match]() { + matchGet = true; + return matchValue; + }, + get constructor() { + constructorGet = true; + return constructorValue; + }, + get source() { + sourceGet = true; + return "foo"; + }, + get flags() { + flagsGet = true; + return "i"; + }, + toString() { + return "bar"; + } +}; + +matchValue = true; +constructorValue = function() {}; + +reset(); +assertEq(RegExp(obj).toString(), "/foo/i"); +assertEq(matchGet, true); +assertEq(constructorGet, true); +assertEq(sourceGet, true); +assertEq(flagsGet, true); + +reset(); +assertEq(RegExp(obj, "g").toString(), "/foo/g"); +assertEq(matchGet, true); +assertEq(constructorGet, false); +assertEq(sourceGet, true); +assertEq(flagsGet, false); + +matchValue = false; +constructorValue = function() {}; + +reset(); +assertEq(RegExp(obj).toString(), "/bar/"); +assertEq(matchGet, true); +assertEq(constructorGet, false); +assertEq(sourceGet, false); +assertEq(flagsGet, false); + +reset(); +assertEq(RegExp(obj, "g").toString(), "/bar/g"); +assertEq(matchGet, true); +assertEq(constructorGet, false); +assertEq(sourceGet, false); +assertEq(flagsGet, false); + +matchValue = true; +constructorValue = RegExp; + +reset(); +assertEq(RegExp(obj), obj); +assertEq(matchGet, true); +assertEq(constructorGet, true); +assertEq(sourceGet, false); +assertEq(flagsGet, false); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/constructor-constructor.js b/js/src/tests/ecma_6/RegExp/constructor-constructor.js new file mode 100644 index 000000000..528f4978c --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/constructor-constructor.js @@ -0,0 +1,78 @@ +var BUGNUMBER = 1147817; +var summary = "RegExp constructor should check pattern.constructor."; + +print(BUGNUMBER + ": " + summary); + +var g = newGlobal(); + +var re = /foo/; +assertEq(RegExp(re), re); +re.constructor = 10; +assertEq(RegExp(re) === re, false); +assertEq(RegExp(re).toString(), re.toString()); + +// If pattern comes from different global, RegExp shouldn't return it. +re = g.eval(`var re = /foo/; re;`); +assertEq(RegExp(re) === re, false); +assertEq(RegExp(re).toString(), re.toString()); +g.eval(`re.constructor = 10;`); +assertEq(RegExp(re) === re, false); +assertEq(RegExp(re).toString(), re.toString()); + + +re = new Proxy(/a/, { + get(that, name) { + return that[name]; + } +}); +assertEq(RegExp(re), re); +re = new Proxy(/a/, { + get(that, name) { + if (name == "constructor") { + return function() {}; + } + return that[name]; + } +}); +assertEq(RegExp(re) === re, false); +re = new Proxy(/a/, { + get(that, name) { + if (name == Symbol.match) { + return undefined; + } + return that[name]; + } +}); +assertEq(RegExp(re) === re, false); + +re = new Proxy(g.eval(`/a/`), { + get(that, name) { + return that[name]; + } +}); +assertEq(RegExp(re) === re, false); + +re = g.eval(`new Proxy(/a/, { + get(that, name) { + return that[name]; + } +});`); +assertEq(RegExp(re) === re, false); + + +var obj = { [Symbol.match]: true, source: "foo", flags: "gi" }; +assertEq(RegExp(obj) === obj, false); +assertEq(RegExp(obj).toString(), "/foo/gi"); +obj.constructor = RegExp; +assertEq(RegExp(obj), obj); + +obj = g.eval(`var obj = { [Symbol.match]: true, source: "foo", flags: "gi" }; obj;`); +assertEq(RegExp(obj) === obj, false); +assertEq(RegExp(obj).toString(), "/foo/gi"); +g.eval(`obj.constructor = RegExp`); +assertEq(RegExp(obj) === obj, false); +obj.constructor = RegExp; +assertEq(RegExp(obj), obj); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/constructor-ordering-2.js b/js/src/tests/ecma_6/RegExp/constructor-ordering-2.js new file mode 100644 index 000000000..21a6bbeca --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/constructor-ordering-2.js @@ -0,0 +1,21 @@ +// Make sure that we don't ToString the second argument until /after/ doing +// the appropriate subclassing lookups + +var didLookup = false; + +var re = /a/; +var flags = { toString() { assertEq(didLookup, true); return "g"; } }; +var newRe = Reflect.construct(RegExp, [re, flags], + Object.defineProperty(function(){}.bind(null), "prototype", { + get() { + didLookup = true; + return RegExp.prototype; + } +})); + +assertEq(Object.getPrototypeOf(newRe), RegExp.prototype); +assertEq(didLookup, true); + + +if (typeof reportCompare === 'function') + reportCompare(0,0,"OK"); diff --git a/js/src/tests/ecma_6/RegExp/constructor-ordering.js b/js/src/tests/ecma_6/RegExp/constructor-ordering.js new file mode 100644 index 000000000..3e3a9b695 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/constructor-ordering.js @@ -0,0 +1,16 @@ +// Make sure that we don't misorder subclassing accesses with respect to +// accessing regex arg internal slots +// +// Test credit André Bargull. + +var re = /a/; +var newRe = Reflect.construct(RegExp, [re], Object.defineProperty(function(){}.bind(null), "prototype", { + get() { + re.compile("b"); + return RegExp.prototype; + } +})); +assertEq(newRe.source, "a"); + +if (typeof reportCompare === 'function') + reportCompare(0,0,"OK"); diff --git a/js/src/tests/ecma_6/RegExp/constructor-regexp-unicode.js b/js/src/tests/ecma_6/RegExp/constructor-regexp-unicode.js new file mode 100644 index 000000000..b348c34a0 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/constructor-regexp-unicode.js @@ -0,0 +1,9 @@ +var BUGNUMBER = 1274393; +var summary = "RegExp constructor should check the pattern syntax again when adding unicode flag."; + +print(BUGNUMBER + ": " + summary); + +assertThrowsInstanceOf(() => RegExp(/\-/, "u"), SyntaxError); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/constructor-regexp.js b/js/src/tests/ecma_6/RegExp/constructor-regexp.js new file mode 100644 index 000000000..419b02713 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/constructor-regexp.js @@ -0,0 +1,61 @@ +var BUGNUMBER = 1130860; +var summary = "RegExp constructor shouldn't invoke source/flags getters on argument RegExp instance."; + +print(BUGNUMBER + ": " + summary); + +// same-compartment +var a = /foo/; +var flagsCalled = false; +var sourceCalled = false; +Object.defineProperty(a, "source", { get: () => { + sourceCalled = true; + return "bar"; +}}); +Object.defineProperty(a, "flags", { get: () => { + flagsCalled = true; + return "i"; +}}); + +assertEq(a.source, "bar"); +assertEq(a.flags, "i"); +assertEq(sourceCalled, true); +assertEq(flagsCalled, true); + +sourceCalled = false; +flagsCalled = false; +assertEq(new RegExp(a).source, "foo"); +assertEq(sourceCalled, false); +assertEq(flagsCalled, false); + +// cross-compartment +var g = newGlobal(); +var b = g.eval(` +var b = /foo2/; +var flagsCalled = false; +var sourceCalled = false; +Object.defineProperty(b, "source", { get: () => { + sourceCalled = true; + return "bar2"; +}}); +Object.defineProperty(b, "flags", { get: () => { + flagsCalled = true; + return "i"; +}}); +b; +`); + +assertEq(b.source, "bar2"); +assertEq(b.flags, "i"); +assertEq(g.eval("sourceCalled;"), true); +assertEq(g.eval("flagsCalled;"), true); + +g.eval(` +sourceCalled = false; +flagsCalled = false; +`); +assertEq(new RegExp(b).source, "foo2"); +assertEq(g.eval("sourceCalled;"), false); +assertEq(g.eval("flagsCalled;"), false); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/descriptor.js b/js/src/tests/ecma_6/RegExp/descriptor.js new file mode 100644 index 000000000..cc545b3a6 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/descriptor.js @@ -0,0 +1,25 @@ +var BUGNUMBER = 1120169; +var summary = "Implement RegExp.prototype.{global, ignoreCase, multiline, sticky, unicode} - property descriptor"; + +print(BUGNUMBER + ": " + summary); + +var getters = [ + "flags", + "global", + "ignoreCase", + "multiline", + "source", + "sticky", + "unicode", +]; + +for (var name of getters) { + var desc = Object.getOwnPropertyDescriptor(RegExp.prototype, name); + assertEq(desc.configurable, true); + assertEq(desc.enumerable, false); + assertEq("writable" in desc, false); + assertEq("get" in desc, true); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/escape.js b/js/src/tests/ecma_6/RegExp/escape.js new file mode 100644 index 000000000..bb59b797d --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/escape.js @@ -0,0 +1,70 @@ +var BUGNUMBER = 1130860; +var summary = 'Slash and LineTerminator should be escaped correctly.'; + +print(BUGNUMBER + ": " + summary); + +function test(re, source) { + assertEq(re.source, source); + assertEq(eval("/" + re.source + "/").source, source); + assertEq(re.toString(), "/" + source + "/"); +} + +test(/\\n/, "\\\\n"); +test(/\\\n/, "\\\\\\n"); +test(/\\\\n/, "\\\\\\\\n"); +test(RegExp("\\n"), "\\n"); +test(RegExp("\\\n"), "\\n"); +test(RegExp("\\\\n"), "\\\\n"); + +test(/\\r/, "\\\\r"); +test(/\\\r/, "\\\\\\r"); +test(/\\\\r/, "\\\\\\\\r"); +test(RegExp("\\r"), "\\r"); +test(RegExp("\\\r"), "\\r"); +test(RegExp("\\\\r"), "\\\\r"); + +test(/\\u2028/, "\\\\u2028"); +test(/\\\u2028/, "\\\\\\u2028"); +test(/\\\\u2028/, "\\\\\\\\u2028"); +test(RegExp("\\u2028"), "\\u2028"); +test(RegExp("\\\u2028"), "\\u2028"); +test(RegExp("\\\\u2028"), "\\\\u2028"); + +test(/\\u2029/, "\\\\u2029"); +test(/\\\u2029/, "\\\\\\u2029"); +test(/\\\\u2029/, "\\\\\\\\u2029"); +test(RegExp("\\u2029"), "\\u2029"); +test(RegExp("\\\u2029"), "\\u2029"); +test(RegExp("\\\\u2029"), "\\\\u2029"); + +test(/\//, "\\/"); +test(/\\\//, "\\\\\\/"); +test(RegExp("/"), "\\/"); +test(RegExp("\/"), "\\/"); +test(RegExp("\\/"), "\\/"); +test(RegExp("\\\/"), "\\/"); +test(RegExp("\\\\/"), "\\\\\\/"); + +test(/[/]/, "[/]"); +test(/[\/]/, "[\\/]"); +test(/[\\/]/, "[\\\\/]"); +test(/[\\\/]/, "[\\\\\\/]"); +test(RegExp("[/]"), "[/]"); +test(RegExp("[\/]"), "[/]"); +test(RegExp("[\\/]"), "[\\/]"); +test(RegExp("[\\\/]"), "[\\/]"); +test(RegExp("[\\\\/]"), "[\\\\/]"); + +test(RegExp("\[/\]"), "[/]"); +test(RegExp("\[\\/\]"), "[\\/]"); + +test(/\[\/\]/, "\\[\\/\\]"); +test(/\[\\\/\]/, "\\[\\\\\\/\\]"); +test(RegExp("\\[/\\]"), "\\[\\/\\]"); +test(RegExp("\\[\/\\]"), "\\[\\/\\]"); +test(RegExp("\\[\\/\\]"), "\\[\\/\\]"); +test(RegExp("\\[\\\/\\]"), "\\[\\/\\]"); +test(RegExp("\\[\\\\/\\]"), "\\[\\\\\\/\\]"); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/exec-lastIndex-negative.js b/js/src/tests/ecma_6/RegExp/exec-lastIndex-negative.js new file mode 100644 index 000000000..18eb2ab9d --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/exec-lastIndex-negative.js @@ -0,0 +1,27 @@ +var BUGNUMBER = 1207922; +var summary = "negative lastIndex should be treated as 0."; + +print(BUGNUMBER + ": " + summary); + +var pattern = /abc/gi; +var string = 'AbcaBcabC'; + +var indices = [ + -1, + -Math.pow(2,32), + -(Math.pow(2,32) + 1), + -Math.pow(2,32) * 2, + -Math.pow(2,40), + -Number.MAX_VALUE, +]; +for (var index of indices) { + pattern.lastIndex = index; + var result = pattern.exec(string); + assertEq(result.index, 0); + assertEq(result.length, 1); + assertEq(result[0], "Abc"); + assertEq(pattern.lastIndex, 3); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/flag-accessors.js b/js/src/tests/ecma_6/RegExp/flag-accessors.js new file mode 100644 index 000000000..848b916c5 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/flag-accessors.js @@ -0,0 +1,49 @@ +var BUGNUMBER = 1120169; +var summary = "Implement RegExp.prototype.{global, ignoreCase, multiline, sticky, unicode}"; + +print(BUGNUMBER + ": " + summary); + +var props = [ + "global", + "ignoreCase", + "multiline", + "sticky", + "unicode", +]; + +testThrows(RegExp.prototype); +test(/foo/iymg, [true, true, true, true, false]); +test(RegExp(""), [false, false, false, false, false]); +test(RegExp("", "mygi"), [true, true, true, true, false]); +test(RegExp("", "mygiu"), [true, true, true, true, true]); + +testThrowsGeneric(); +testThrowsGeneric(1); +testThrowsGeneric(""); +testThrowsGeneric({}); +testThrowsGeneric(new Proxy({}, {get(){ return true; }})); + +function test(obj, expects) { + for (var i = 0; i < props.length; i++) { + assertEq(obj[props[i]], expects[i]); + } +} + +function testThrows(obj) { + for (var prop of props) { + assertThrowsInstanceOf(obj[prop], TypeError); + } +} + +function testThrowsGeneric(obj) { + for (var prop of props) { + assertThrowsInstanceOf(() => genericGet(obj, prop), TypeError); + } +} + +function genericGet(obj, prop) { + return Object.getOwnPropertyDescriptor(RegExp.prototype, prop).get.call(obj); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/flags-param-handling.js b/js/src/tests/ecma_6/RegExp/flags-param-handling.js new file mode 100644 index 000000000..e47799601 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/flags-param-handling.js @@ -0,0 +1,18 @@ +assertEq(RegExp(/foo/my).flags, "my"); +assertEq(RegExp(/foo/, "gi").flags, "gi"); +assertEq(RegExp(/foo/my, "gi").flags, "gi"); +assertEq(RegExp(/foo/my, "").flags, ""); +assertEq(RegExp(/foo/my, undefined).flags, "my"); +assertThrowsInstanceOf(() => RegExp(/foo/my, null), SyntaxError); +assertThrowsInstanceOf(() => RegExp(/foo/my, "foo"), SyntaxError); + +assertEq(/a/.compile("b", "gi").flags, "gi"); +assertEq(/a/.compile(/b/my).flags, "my"); +assertEq(/a/.compile(/b/my, undefined).flags, "my"); +assertThrowsInstanceOf(() => /a/.compile(/b/my, "gi"), TypeError); +assertThrowsInstanceOf(() => /a/.compile(/b/my, ""), TypeError); +assertThrowsInstanceOf(() => /a/.compile(/b/my, null), TypeError); +assertThrowsInstanceOf(() => /a/.compile(/b/my, "foo"), TypeError); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/flags.js b/js/src/tests/ecma_6/RegExp/flags.js new file mode 100644 index 000000000..292fa4f3f --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/flags.js @@ -0,0 +1,26 @@ +var BUGNUMBER = 1108467; +var summary = "Implement RegExp.prototype.flags"; + +print(BUGNUMBER + ": " + summary); + +assertEq(RegExp.prototype.flags, ""); +assertEq(/foo/iymg.flags, "gimy"); +assertEq(RegExp("").flags, ""); +assertEq(RegExp("", "mygi").flags, "gimy"); +assertEq(RegExp("", "mygui").flags, "gimuy"); +assertEq(genericFlags({}), ""); +assertEq(genericFlags({ignoreCase: true}), "i"); +assertEq(genericFlags({sticky:1, unicode:1, global: 0}), "uy"); +assertEq(genericFlags({__proto__: {multiline: true}}), "m"); +assertEq(genericFlags(new Proxy({}, {get(){return true}})), "gimuy"); + +assertThrowsInstanceOf(() => genericFlags(), TypeError); +assertThrowsInstanceOf(() => genericFlags(1), TypeError); +assertThrowsInstanceOf(() => genericFlags(""), TypeError); + +function genericFlags(obj) { + return Object.getOwnPropertyDescriptor(RegExp.prototype,"flags").get.call(obj); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/getter-name.js b/js/src/tests/ecma_6/RegExp/getter-name.js new file mode 100644 index 000000000..d0a413dbc --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/getter-name.js @@ -0,0 +1,16 @@ +var BUGNUMBER = 1180290; +var summary = 'RegExp getters should have get prefix'; + +print(BUGNUMBER + ": " + summary); + +assertEq(Object.getOwnPropertyDescriptor(RegExp, Symbol.species).get.name, "get [Symbol.species]"); +assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, "flags").get.name, "get flags"); +assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, "global").get.name, "get global"); +assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, "ignoreCase").get.name, "get ignoreCase"); +assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, "multiline").get.name, "get multiline"); +assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, "source").get.name, "get source"); +assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, "sticky").get.name, "get sticky"); +assertEq(Object.getOwnPropertyDescriptor(RegExp.prototype, "unicode").get.name, "get unicode"); + +if (typeof reportCompare === 'function') + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/ignoreCase-multiple.js b/js/src/tests/ecma_6/RegExp/ignoreCase-multiple.js new file mode 100644 index 000000000..e52cf499b --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/ignoreCase-multiple.js @@ -0,0 +1,71 @@ +var BUGNUMBER = 1280046; +var summary = "ignoreCase match should perform Canonicalize both on input and pattern."; + +print(BUGNUMBER + ": " + summary); + +// Each element [code1, upper, code2] satisfies the following condition: +// ToUpperCase(code1) == upper +// ToUpperCase(code2) == upper +var pairs = + [ + // U+00B5: MICRO SIGN + // U+039C: GREEK CAPITAL LETTER MU + // U+03BC: GREEK SMALL LETTER MU + ["\u00B5", "\u039C", "\u03BC"], + // U+0345: COMBINING GREEK YPOGEGRAMMENI + // U+0399: GREEK CAPITAL LETTER IOTA + // U+03B9: GREEK SMALL LETTER IOTA + ["\u0345", "\u0399", "\u03B9"], + // U+03C2: GREEK SMALL LETTER FINAL SIGMA + // U+03A3: GREEK CAPITAL LETTER SIGMA + // U+03C3: GREEK SMALL LETTER SIGMA + ["\u03C2", "\u03A3", "\u03C3"], + // U+03D0: GREEK BETA SYMBOL + // U+0392: GREEK CAPITAL LETTER BETA + // U+03B2: GREEK SMALL LETTER BETA + ["\u03D0", "\u0392", "\u03B2"], + // U+03D1: GREEK THETA SYMBOL + // U+0398: GREEK CAPITAL LETTER THETA + // U+03B8: GREEK SMALL LETTER THETA + ["\u03D1", "\u0398", "\u03B8"], + // U+03D5: GREEK PHI SYMBOL + // U+03A6: GREEK CAPITAL LETTER PHI + // U+03C6: GREEK SMALL LETTER PHI + ["\u03D5", "\u03A6", "\u03C6"], + // U+03D6: GREEK PI SYMBOL + // U+03A0: GREEK CAPITAL LETTER PI + // U+03C0: GREEK SMALL LETTER PI + ["\u03D6", "\u03A0", "\u03C0"], + // U+03F0: GREEK KAPPA SYMBOL + // U+039A: GREEK CAPITAL LETTER KAPPA + // U+03BA: GREEK SMALL LETTER KAPPA + ["\u03F0", "\u039A", "\u03BA"], + // U+03F1: GREEK RHO SYMBOL + // U+03A1: GREEK CAPITAL LETTER RHO + // U+03C1: GREEK SMALL LETTER RHO + ["\u03F1", "\u03A1", "\u03C1"], + // U+03F5: GREEK LUNATE EPSILON SYMBOL + // U+0395: GREEK CAPITAL LETTER EPSILON + // U+03B5: GREEK SMALL LETTER EPSILON + ["\u03F5", "\u0395", "\u03B5"], + // U+1E9B: LATIN SMALL LETTER LONG S WITH DOT ABOVE + // U+1E60: LATIN CAPITAL LETTER S WITH DOT ABOVE + // U+1E61: LATIN SMALL LETTER S WITH DOT ABOVE + ["\u1E9B", "\u1E60", "\u1E61"], + // U+1FBE: GREEK PROSGEGRAMMENI + // U+0399: GREEK CAPITAL LETTER IOTA + // U+03B9: GREEK SMALL LETTER IOTA + ["\u1FBE", "\u0399", "\u03B9"], + ]; + +for (var [code1, upper, code2] of pairs) { + assertEq(new RegExp(code1, "i").test(code2), true); + assertEq(new RegExp(code1, "i").test(upper), true); + assertEq(new RegExp(upper, "i").test(code1), true); + assertEq(new RegExp(upper, "i").test(code2), true); + assertEq(new RegExp(code2, "i").test(code1), true); + assertEq(new RegExp(code2, "i").test(upper), true); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/lastIndex-nonwritable.js b/js/src/tests/ecma_6/RegExp/lastIndex-nonwritable.js new file mode 100644 index 000000000..3c867f953 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/lastIndex-nonwritable.js @@ -0,0 +1,27 @@ +var BUGNUMBER = 1168416; +var summary = "Regexp.prototype.test/exec shouldn't change lastIndex if not writable."; + +print(BUGNUMBER + ": " + summary); + +var regex = /0/g; +Object.freeze(regex); +var str = "abc000"; + +var desc = Object.getOwnPropertyDescriptor(regex, "lastIndex"); +assertEq(desc.writable, false); +assertEq(desc.value, 0); + +assertThrowsInstanceOf(() => regex.test(str), TypeError); + +desc = Object.getOwnPropertyDescriptor(regex, "lastIndex"); +assertEq(desc.writable, false); +assertEq(desc.value, 0); + +assertThrowsInstanceOf(() => regex.exec(str), TypeError); + +desc = Object.getOwnPropertyDescriptor(regex, "lastIndex"); +assertEq(desc.writable, false); +assertEq(desc.value, 0); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/match-this.js b/js/src/tests/ecma_6/RegExp/match-this.js new file mode 100644 index 000000000..ee05462f2 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/match-this.js @@ -0,0 +1,12 @@ +var BUGNUMBER = 887016; +var summary = "RegExp.prototype[@@match] should check this value."; + +print(BUGNUMBER + ": " + summary); + +for (var v of [null, 1, true, undefined, "", Symbol.iterator]) { + assertThrowsInstanceOf(() => RegExp.prototype[Symbol.match].call(v), + TypeError); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/match-trace.js b/js/src/tests/ecma_6/RegExp/match-trace.js new file mode 100644 index 000000000..3216db641 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/match-trace.js @@ -0,0 +1,147 @@ +var BUGNUMBER = 887016; +var summary = "Trace RegExp.prototype[@@match] behavior."; + +print(BUGNUMBER + ": " + summary); + +var n; +var log; +var target; +var global; +var unicode; +var logProxy; + +var execResult; +var lastIndexResult; +var lastIndexExpected; + +function P(A) { + return new Proxy(A, { + get(that, name) { + if (logProxy) + log += "get:result[" + name + "],"; + return that[name]; + } + }); +} + +var myRegExp = { + get global() { + log += "get:global,"; + return global; + }, + get lastIndex() { + log += "get:lastIndex,"; + return lastIndexResult[n]; + }, + set lastIndex(v) { + log += "set:lastIndex,"; + assertEq(v, lastIndexExpected[n]); + }, + get unicode() { + log += "get:unicode,"; + return unicode; + }, + get exec() { + log += "get:exec,"; + return function(S) { + log += "call:exec,"; + assertEq(S, target); + return execResult[n++]; + }; + }, +}; + +function reset() { + n = 0; + log = ""; + target = "abcAbcABC"; + global = true; + unicode = false; + logProxy = true; +} + +// Trace global with non-empty match. +reset(); +execResult = [ P(["abc"]), P(["ABC"]), null ]; +lastIndexResult = [ , , , ]; +lastIndexExpected = [ 0, , , ]; +var ret = RegExp.prototype[Symbol.match].call(myRegExp, target); +assertEq(JSON.stringify(ret), `["abc","ABC"]`); +assertEq(log, + "get:global," + + "get:unicode," + + "set:lastIndex," + + "get:exec,call:exec,get:result[0]," + + "get:exec,call:exec,get:result[0]," + + "get:exec,call:exec,"); + +// Trace global with empty match. +reset(); +execResult = [ P([""]), P([""]), null ]; +lastIndexResult = [ , 4, 20, ]; +lastIndexExpected = [ 0, 5, 21, ]; +ret = RegExp.prototype[Symbol.match].call(myRegExp, target); +assertEq(JSON.stringify(ret), `["",""]`); +assertEq(log, + "get:global," + + "get:unicode," + + "set:lastIndex," + + "get:exec,call:exec,get:result[0],get:lastIndex,set:lastIndex," + + "get:exec,call:exec,get:result[0],get:lastIndex,set:lastIndex," + + "get:exec,call:exec,"); + +// Trace global and unicode with empty match. +// 1. not surrogate pair +// 2. lead surrogate pair +// 3. trail surrogate pair +// 4. lead surrogate pair without trail surrogate pair +// 5. index overflow +reset(); +unicode = true; +// 0123 4 5678 +target = "___\uD83D\uDC38___\uD83D"; +execResult = [ P([""]), P([""]), P([""]), P([""]), P([""]), null ]; +lastIndexResult = [ , 2, 3, 4, 8, 9, ]; +lastIndexExpected = [ 0, 3, 5, 5, 9, 10, ]; +ret = RegExp.prototype[Symbol.match].call(myRegExp, target); +assertEq(JSON.stringify(ret), `["","","","",""]`); +assertEq(log, + "get:global," + + "get:unicode," + + "set:lastIndex," + + "get:exec,call:exec,get:result[0],get:lastIndex,set:lastIndex," + + "get:exec,call:exec,get:result[0],get:lastIndex,set:lastIndex," + + "get:exec,call:exec,get:result[0],get:lastIndex,set:lastIndex," + + "get:exec,call:exec,get:result[0],get:lastIndex,set:lastIndex," + + "get:exec,call:exec,get:result[0],get:lastIndex,set:lastIndex," + + "get:exec,call:exec,"); + +// Trace global with no match. +reset(); +execResult = [ null ]; +lastIndexResult = [ , ]; +lastIndexExpected = [ 0, ]; +ret = RegExp.prototype[Symbol.match].call(myRegExp, target); +assertEq(ret, null); +assertEq(log, + "get:global," + + "get:unicode," + + "set:lastIndex," + + "get:exec,call:exec,"); + +// Trace non-global. +reset(); +global = false; +execResult = [ P(["abc"]) ]; +lastIndexResult = []; +lastIndexExpected = []; +ret = RegExp.prototype[Symbol.match].call(myRegExp, target); +// ret is the Proxy on non-global case, disable logging. +logProxy = false; +assertEq(JSON.stringify(ret), `["abc"]`); +assertEq(log, + "get:global," + + "get:exec,call:exec,"); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/match.js b/js/src/tests/ecma_6/RegExp/match.js new file mode 100644 index 000000000..06308b2d6 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/match.js @@ -0,0 +1,36 @@ +var BUGNUMBER = 887016; +var summary = "Implement RegExp.prototype[@@match]."; + +print(BUGNUMBER + ": " + summary); + +assertEq(RegExp.prototype[Symbol.match].name, "[Symbol.match]"); +assertEq(RegExp.prototype[Symbol.match].length, 1); +var desc = Object.getOwnPropertyDescriptor(RegExp.prototype, Symbol.match); +assertEq(desc.configurable, true); +assertEq(desc.enumerable, false); +assertEq(desc.writable, true); + +var re = /a/; +var v = re[Symbol.match]("abcAbcABC"); +assertEq(Array.isArray(v), true); +assertEq(v.length, 1); +assertEq(v[0], "a"); + +re = /d/; +v = re[Symbol.match]("abcAbcABC"); +assertEq(v, null); + +re = /a/ig; +v = re[Symbol.match]("abcAbcABC"); +assertEq(Array.isArray(v), true); +assertEq(v.length, 3); +assertEq(v[0], "a"); +assertEq(v[1], "A"); +assertEq(v[2], "A"); + +re = /d/g; +v = re[Symbol.match]("abcAbcABC"); +assertEq(v, null); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/replace-compile.js b/js/src/tests/ecma_6/RegExp/replace-compile.js new file mode 100644 index 000000000..45359037a --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/replace-compile.js @@ -0,0 +1,21 @@ +var BUGNUMBER = 1287524; +var summary = 'RegExp.prototype[@@replace] should call replacer function after collecting all matches.'; + +print(BUGNUMBER + ": " + summary); + +var rx = RegExp("a", "g"); +var r = rx[Symbol.replace]("abba", function() { + rx.compile("b", "g"); + return "?"; +}); +assertEq(r, "?bb?"); + +rx = RegExp("a", "g"); +r = "abba".replace(rx, function() { + rx.compile("b", "g"); + return "?"; +}); +assertEq(r, "?bb?"); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/replace-global-unicode.js b/js/src/tests/ecma_6/RegExp/replace-global-unicode.js new file mode 100644 index 000000000..80b3ea199 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/replace-global-unicode.js @@ -0,0 +1,18 @@ +var BUGNUMBER = 1287524; +var summary = 'RegExp.prototype[@@replace] should not use optimized path if RegExp.prototype.unicode is modified.'; + +print(BUGNUMBER + ": " + summary); + +Object.defineProperty(RegExp.prototype, "unicode", { + get() { + RegExp.prototype.exec = () => null; + } +}); + +var rx = RegExp("a", "g"); +var s = "abba"; +var r = rx[Symbol.replace](s, "c"); +assertEq(r, "abba"); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/replace-sticky-lastIndex.js b/js/src/tests/ecma_6/RegExp/replace-sticky-lastIndex.js new file mode 100644 index 000000000..2500b2c42 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/replace-sticky-lastIndex.js @@ -0,0 +1,23 @@ +var BUGNUMBER = 887016; +var summary = "String.prototype.replace should do nothing if lastIndex is invalid for sticky RegExp"; + +print(BUGNUMBER + ": " + summary); + +var re = /a/y; +re.lastIndex = -1; +assertEq("a".replace(re, "b"), "b"); +re.lastIndex = 0; +assertEq("a".replace(re, "b"), "b"); +re.lastIndex = 1; +assertEq("a".replace(re, "b"), "a"); +re.lastIndex = 2; +assertEq("a".replace(re, "b"), "a"); +re.lastIndex = "foo"; +assertEq("a".replace(re, "b"), "b"); +re.lastIndex = "1"; +assertEq("a".replace(re, "b"), "a"); +re.lastIndex = {}; +assertEq("a".replace(re, "b"), "b"); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/replace-sticky.js b/js/src/tests/ecma_6/RegExp/replace-sticky.js new file mode 100644 index 000000000..32a6e2aee --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/replace-sticky.js @@ -0,0 +1,21 @@ +var BUGNUMBER = 887016; +var summary = "String.prototype.replace should use and update lastIndex if sticky flag is set"; + +print(BUGNUMBER + ": " + summary); + +var input = "abcdeabcdeabcdefghij"; +var re = new RegExp("abcde", "y"); +re.test(input); +assertEq(re.lastIndex, 5); +var ret = input.replace(re, "ABCDE"); +assertEq(ret, "abcdeABCDEabcdefghij"); +assertEq(re.lastIndex, 10); +ret = input.replace(re, "ABCDE"); +assertEq(ret, "abcdeabcdeABCDEfghij"); +assertEq(re.lastIndex, 15); +ret = input.replace(re, "ABCDE"); +assertEq(ret, "abcdeabcdeabcdefghij"); +assertEq(re.lastIndex, 0); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/replace-this.js b/js/src/tests/ecma_6/RegExp/replace-this.js new file mode 100644 index 000000000..499304f9c --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/replace-this.js @@ -0,0 +1,12 @@ +var BUGNUMBER = 887016; +var summary = "RegExp.prototype[@@replace] should check |this| value."; + +print(BUGNUMBER + ": " + summary); + +for (var v of [null, 1, true, undefined, "", Symbol.iterator]) { + assertThrowsInstanceOf(() => RegExp.prototype[Symbol.replace].call(v), + TypeError); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/replace-trace.js b/js/src/tests/ecma_6/RegExp/replace-trace.js new file mode 100644 index 000000000..73e623563 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/replace-trace.js @@ -0,0 +1,309 @@ +var BUGNUMBER = 887016; +var summary = "Trace RegExp.prototype[@@replace] behavior."; + +print(BUGNUMBER + ": " + summary); + +var n; +var log; +var target; +var global; +var unicode; + +var execResult; +var lastIndexResult; +var lastIndexExpected; + +var arraySetterObserved = false; +function startObserve() { + for (var i = 0; i < 10; i++) { + Object.defineProperty(Array.prototype, i, { + set: function(v) { + arraySetterObserved = true; + }, + configurable: true, + }); + } +} +function stopObserve() { + for (var i = 0; i < 10; i++) + delete Array.prototype[i] +} + +startObserve(); + +function P(A, index, matched2) { + var i = 0; + A.index = index; + return new Proxy(A, { + get(that, name) { + log += "get:result[" + name + "],"; + + // Return a different value for 2nd access to result[0]. + if (matched2 !== undefined && name == 0) { + if (i == 1) { + return matched2; + } + i++; + } + + return that[name]; + } + }); +} + +var myRegExp = { + get global() { + log += "get:global,"; + return global; + }, + get lastIndex() { + log += "get:lastIndex,"; + return lastIndexResult[n]; + }, + set lastIndex(v) { + log += "set:lastIndex,"; + assertEq(v, lastIndexExpected[n]); + }, + get unicode() { + log += "get:unicode,"; + return unicode; + }, + get exec() { + log += "get:exec,"; + return function(S) { + log += "call:exec,"; + assertEq(S, target); + return execResult[n++]; + }; + }, +}; + +function reset() { + n = 0; + log = ""; + target = "abcAbcABC"; + global = true; + unicode = false; + arraySetterObserved = false; +} + +// Trace global with non-empty match. +reset(); +execResult = [ P(["bc"], 1), null ]; +lastIndexResult = [ , , ]; +lastIndexExpected = [ 0, , ]; +var ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "_XYZ_"); +assertEq(arraySetterObserved, false); +assertEq(ret, "a_XYZ_AbcABC"); +assertEq(log, + "get:global," + + "get:unicode," + + "set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:exec,call:exec," + + "get:result[length],get:result[0],get:result[index],"); + +// Trace global with empty match. +reset(); +execResult = [ P([""], 1), null ]; +lastIndexResult = [ , 5, ]; +lastIndexExpected = [ 0, 6, ]; +ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "_XYZ_"); +assertEq(arraySetterObserved, false); +assertEq(ret, "a_XYZ_bcAbcABC"); +assertEq(log, + "get:global," + + "get:unicode," + + "set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:lastIndex,set:lastIndex," + + "get:exec,call:exec," + + "get:result[length],get:result[0],get:result[index],"); + +// Trace global and unicode with empty match. +// 1. not surrogate pair +// 2. lead surrogate pair +// 3. trail surrogate pair +// 4. lead surrogate pair without trail surrogate pair +// 5. index overflow +reset(); +unicode = true; +// 0123 4 5678 +target = "---\uD83D\uDC38---\uD83D"; +execResult = [ P([""], 1), P([""], 2), P([""], 3), P([""], 4), P([""], 5), null ]; +lastIndexResult = [ , 2, 3, 4, 8, 9, ]; +lastIndexExpected = [ 0, 3, 5, 5, 9, 10, ]; +ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "_XYZ_"); +assertEq(arraySetterObserved, false); +assertEq(ret, "-_XYZ_-_XYZ_-_XYZ_\uD83D_XYZ_\uDC38_XYZ_---\uD83D"); +assertEq(log, + "get:global," + + "get:unicode," + + "set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:lastIndex,set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:lastIndex,set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:lastIndex,set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:lastIndex,set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:lastIndex,set:lastIndex," + + "get:exec,call:exec," + + "get:result[length],get:result[0],get:result[index]," + + "get:result[length],get:result[0],get:result[index]," + + "get:result[length],get:result[0],get:result[index]," + + "get:result[length],get:result[0],get:result[index]," + + "get:result[length],get:result[0],get:result[index],"); + +// Trace global with captures and substitutions. +reset(); +execResult = [ P(["bc", "b", "c"], 1), null ]; +lastIndexResult = [ , , ]; +lastIndexExpected = [ 0, , ]; +ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "[$&,$`,$',$1,$2,$3,$]"); +assertEq(arraySetterObserved, false); +assertEq(ret, "a[bc,a,AbcABC,b,c,$3,$]AbcABC"); +assertEq(log, + "get:global," + + "get:unicode," + + "set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:exec,call:exec," + + "get:result[length],get:result[0],get:result[index]," + + "get:result[1],get:result[2],"); + +// Trace global with empty match and captures and substitutions, +// with different matched. +reset(); +execResult = [ P(["", "b", "c"], 1, "BC"), null ]; +lastIndexResult = [ , 5, ]; +lastIndexExpected = [ 0, 6, ]; +ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "[$&,$`,$',$1,$2,$3,$]"); +assertEq(arraySetterObserved, false); +assertEq(ret, "a[BC,a,AbcABC,b,c,$3,$]AbcABC"); +assertEq(log, + "get:global," + + "get:unicode," + + "set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:lastIndex,set:lastIndex," + + "get:exec,call:exec," + + "get:result[length],get:result[0],get:result[index]," + + "get:result[1],get:result[2],"); + +// Trace global with empty match and captures and function, +// with different matched. +reset(); +execResult = [ P(["", "b", "c"], 1, "BC"), null ]; +lastIndexResult = [ , 5, ]; +lastIndexExpected = [ 0, 6, ]; +function replaceFunc(...args) { + log += "call:replaceFunc,"; + assertEq(args.length, 5); + assertEq(args[0], "BC"); + assertEq(args[1], "b"); + assertEq(args[2], "c"); + assertEq(args[3], 1); + assertEq(args[4], target); + return "_ret_"; +} +// This also tests RegExpStatics save/restore with no match. +ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, replaceFunc); +assertEq(arraySetterObserved, false); +assertEq(ret, "a_ret_AbcABC"); +assertEq(log, + "get:global," + + "get:unicode," + + "set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:lastIndex,set:lastIndex," + + "get:exec,call:exec," + + "get:result[length],get:result[0],get:result[index]," + + "get:result[1],get:result[2]," + + "call:replaceFunc,"); + +// Trace global with non-empty match, move backwards. +// 2nd match shouldn't be replaced. +reset(); +execResult = [ P(["X"], 5), P(["YZ"], 1), null ]; +lastIndexResult = [ , , , ]; +lastIndexExpected = [ 0, , , ]; +ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "_XYZ_"); +assertEq(arraySetterObserved, false); +assertEq(ret, "abcAb_XYZ_ABC"); +assertEq(log, + "get:global," + + "get:unicode," + + "set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:exec,call:exec," + + "get:result[0]," + + "get:exec,call:exec," + + "get:result[length],get:result[0],get:result[index]," + + "get:result[length],get:result[0],get:result[index],"); + +// Trace global with non-empty match, position + matchLength overflows. +reset(); +execResult = [ P(["fooooooo"], 7), null ]; +lastIndexResult = [ , , ]; +lastIndexExpected = [ 0, , ]; +ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "_XYZ_"); +assertEq(arraySetterObserved, false); +assertEq(ret, "abcAbcA_XYZ_"); +assertEq(log, + "get:global," + + "get:unicode," + + "set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:exec,call:exec," + + "get:result[length],get:result[0],get:result[index],"); + +// Trace global with non-empty match, position overflows. +reset(); +execResult = [ P(["fooooooo"], 12), null ]; +lastIndexResult = [ , , ]; +lastIndexExpected = [ 0, , ]; +ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "_XYZ_"); +assertEq(arraySetterObserved, false); +assertEq(ret, "abcAbcABC_XYZ_"); +assertEq(log, + "get:global," + + "get:unicode," + + "set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:exec,call:exec," + + "get:result[length],get:result[0],get:result[index],"); + +// Trace non-global. +reset(); +global = false; +execResult = [ P(["bc"], 1) ]; +lastIndexResult = [ , , ]; +lastIndexExpected = [ 0, , ]; +ret = RegExp.prototype[Symbol.replace].call(myRegExp, target, "_XYZ_"); +assertEq(arraySetterObserved, false); +assertEq(ret, "a_XYZ_AbcABC"); +assertEq(log, + "get:global," + + "get:exec,call:exec," + + "get:result[length],get:result[0],get:result[index],"); + +stopObserve(); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/replace-twoBytes.js b/js/src/tests/ecma_6/RegExp/replace-twoBytes.js new file mode 100644 index 000000000..660677c9f --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/replace-twoBytes.js @@ -0,0 +1,44 @@ +var BUGNUMBER = 1269719; +var summary = "RegExp.prototype[@@replace] should check latin1/twoBytes for all strings used in relate operation."; + +print(BUGNUMBER + ": " + summary); + +var ans = [ + "[AB$2$3$]", + "[AB$2$3$]\u3048", + "[AB$2$3$]", + "[AB$2$3$]\u3048", + "[A\u3044$2$3$]", + "[A\u3044$2$3$]\u3048", + "[A\u3044$2$3$]", + "[A\u3044$2$3$]\u3048", + "[\u3042B$2$3$]", + "[\u3042B$2$3$]\u3048", + "[\u3042B$2$3$]", + "[\u3042B$2$3$]\u3048", + "[\u3042\u3044$2$3$]", + "[\u3042\u3044$2$3$]\u3048", + "[\u3042\u3044$2$3$]", + "[\u3042\u3044$2$3$]\u3048", +]; +var i = 0; +for (var matched of ["A", "\u3042"]) { + for (var group1 of ["B", "\u3044"]) { + for (var string of ["C", "\u3046"]) { + for (var replacement of ["[$&$`$'$1$2$3$]", "[$&$`$'$1$2$3$]\u3048"]) { + var myRegExp = { + get exec() { + return function() { + return [matched, group1]; + }; + } + }; + assertEq(RegExp.prototype[Symbol.replace].call(myRegExp, string, replacement), ans[i]); + i++; + } + } + } +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/replace.js b/js/src/tests/ecma_6/RegExp/replace.js new file mode 100644 index 000000000..43522ab55 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/replace.js @@ -0,0 +1,34 @@ +var BUGNUMBER = 887016; +var summary = "Implement RegExp.prototype[@@replace]."; + +print(BUGNUMBER + ": " + summary); + +assertEq(RegExp.prototype[Symbol.replace].name, "[Symbol.replace]"); +assertEq(RegExp.prototype[Symbol.replace].length, 2); +var desc = Object.getOwnPropertyDescriptor(RegExp.prototype, Symbol.replace); +assertEq(desc.configurable, true); +assertEq(desc.enumerable, false); +assertEq(desc.writable, true); + +var re = /a/; +var v = re[Symbol.replace]("abcAbcABC", "X"); +assertEq(v, "XbcAbcABC"); + +re = /d/; +v = re[Symbol.replace]("abcAbcABC", "X"); +assertEq(v, "abcAbcABC"); + +re = /a/ig; +v = re[Symbol.replace]("abcAbcABC", "X"); +assertEq(v, "XbcXbcXBC"); + +re = /(a)(b)(cd)/; +v = re[Symbol.replace]("012abcd345", "_$$_$&_$`_$'_$0_$1_$2_$3_$4_$+_$"); +assertEq(v, "012_$_abcd_012_345_$0_a_b_cd_$4_cd_$345"); + +re = /(a)(b)(cd)/; +v = re[Symbol.replace]("012abcd345", "_\u3042_$$_$&_$`_$'_$0_$1_$2_$3_$4_$+_$"); +assertEq(v, "012_\u3042_$_abcd_012_345_$0_a_b_cd_$4_cd_$345"); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/search-this.js b/js/src/tests/ecma_6/RegExp/search-this.js new file mode 100644 index 000000000..731f5480f --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/search-this.js @@ -0,0 +1,12 @@ +var BUGNUMBER = 887016; +var summary = "RegExp.prototype[@@search] should check this value."; + +print(BUGNUMBER + ": " + summary); + +for (var v of [null, 1, true, undefined, "", Symbol.iterator]) { + assertThrowsInstanceOf(() => RegExp.prototype[Symbol.search].call(v), + TypeError); +} + +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 new file mode 100644 index 000000000..ef14514c6 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/search-trace.js @@ -0,0 +1,76 @@ +var BUGNUMBER = 887016; +var summary = "Trace RegExp.prototype[@@search] behavior."; + +print(BUGNUMBER + ": " + summary); + +var n; +var log; +var target; + +var execResult; +var lastIndexResult; +var lastIndexExpected; + +function P(index) { + return new Proxy({ index }, { + get(that, name) { + log += "get:result[" + name + "],"; + return that[name]; + } + }); +} + +var myRegExp = { + get lastIndex() { + log += "get:lastIndex,"; + return lastIndexResult[n]; + }, + set lastIndex(v) { + log += "set:lastIndex,"; + assertEq(v, lastIndexExpected[n]); + }, + get exec() { + log += "get:exec,"; + return function(S) { + log += "call:exec,"; + assertEq(S, target); + return execResult[n++]; + }; + }, +}; + +function reset() { + n = 0; + log = ""; + target = "abcAbcABC"; +} + +// Trace hit. +reset(); +execResult = [ P(16) ]; +lastIndexResult = [ 10, , ]; +lastIndexExpected = [ 0, 10 ]; +var ret = RegExp.prototype[Symbol.search].call(myRegExp, target); +assertEq(ret, 16); +assertEq(log, + "get:lastIndex," + + "set:lastIndex," + + "get:exec,call:exec," + + "set:lastIndex," + + "get:result[index],"); + +// Trace not hit. +reset(); +execResult = [ null ]; +lastIndexResult = [ 10, , ]; +lastIndexExpected = [ 0, 10 ]; +ret = RegExp.prototype[Symbol.search].call(myRegExp, target); +assertEq(ret, -1); +assertEq(log, + "get:lastIndex," + + "set:lastIndex," + + "get:exec,call:exec," + + "set:lastIndex,"); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/search.js b/js/src/tests/ecma_6/RegExp/search.js new file mode 100644 index 000000000..0875ee47e --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/search.js @@ -0,0 +1,26 @@ +var BUGNUMBER = 887016; +var summary = "Implement RegExp.prototype[@@search]."; + +print(BUGNUMBER + ": " + summary); + +assertEq(RegExp.prototype[Symbol.search].name, "[Symbol.search]"); +assertEq(RegExp.prototype[Symbol.search].length, 1); +var desc = Object.getOwnPropertyDescriptor(RegExp.prototype, Symbol.search); +assertEq(desc.configurable, true); +assertEq(desc.enumerable, false); +assertEq(desc.writable, true); + +var re = /B/; +var v = re[Symbol.search]("abcAbcABC"); +assertEq(v, 7); + +re = /B/i; +v = re[Symbol.search]("abcAbcABCD"); +assertEq(v, 1); + +re = /d/; +v = re[Symbol.search]("abcAbcABCD"); +assertEq(v, -1); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/shell.js b/js/src/tests/ecma_6/RegExp/shell.js new file mode 100644 index 000000000..e69de29bb diff --git a/js/src/tests/ecma_6/RegExp/source.js b/js/src/tests/ecma_6/RegExp/source.js new file mode 100644 index 000000000..354a9d19d --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/source.js @@ -0,0 +1,29 @@ +var BUGNUMBER = 1120169; +var summary = "Implement RegExp.prototype.source"; + +print(BUGNUMBER + ": " + summary); + +assertEq(RegExp.prototype.source, "(?:)"); +assertEq(/foo/.source, "foo"); +assertEq(/foo/iymg.source, "foo"); +assertEq(/\//.source, "\\/"); +assertEq(/\n\r/.source, "\\n\\r"); +assertEq(/\u2028\u2029/.source, "\\u2028\\u2029"); +assertEq(RegExp("").source, "(?:)"); +assertEq(RegExp("", "mygi").source, "(?:)"); +assertEq(RegExp("/").source, "\\/"); +assertEq(RegExp("\n\r").source, "\\n\\r"); +assertEq(RegExp("\u2028\u2029").source, "\\u2028\\u2029"); + +assertThrowsInstanceOf(() => genericSource(), TypeError); +assertThrowsInstanceOf(() => genericSource(1), TypeError); +assertThrowsInstanceOf(() => genericSource(""), TypeError); +assertThrowsInstanceOf(() => genericSource({}), TypeError); +assertThrowsInstanceOf(() => genericSource(new Proxy(/foo/, {get(){ return true; }})), TypeError); + +function genericSource(obj) { + return Object.getOwnPropertyDescriptor(RegExp.prototype, "source").get.call(obj); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/split-deleted-flags.js b/js/src/tests/ecma_6/RegExp/split-deleted-flags.js new file mode 100644 index 000000000..d2ccc852d --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/split-deleted-flags.js @@ -0,0 +1,11 @@ +var BUGNUMBER = 1322319; +var summary = "RegExp.prototype.split should throw if RegRxp.prototype.flags is deleted." + +print(BUGNUMBER + ": " + summary); + +delete RegExp.prototype.flags; + +assertThrowsInstanceOf(() => "aaaaa".split(/a/), SyntaxError); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/split-flags-on-obj.js b/js/src/tests/ecma_6/RegExp/split-flags-on-obj.js new file mode 100644 index 000000000..8c68efed5 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/split-flags-on-obj.js @@ -0,0 +1,21 @@ +var BUGNUMBER = 0; +var summary = "RegExp.prototype.split should reflect the change to Object.prototype.flags."; + +print(BUGNUMBER + ": " + summary); + +Object.defineProperty(Object.prototype, "flags", Object.getOwnPropertyDescriptor(RegExp.prototype, "flags")); +delete RegExp.prototype.flags; + +let re = /a/i; +let a = re[Symbol.split]("1a2A3a4A5"); +assertDeepEq(a, ["1", "2", "3", "4", "5"]); + +delete Object.prototype.flags; + +Object.prototype.flags = ""; + +a = re[Symbol.split]("1a2A3a4A5"); +assertDeepEq(a, ["1", "2A3", "4A5"]); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/split-invalid-lastIndex.js b/js/src/tests/ecma_6/RegExp/split-invalid-lastIndex.js new file mode 100644 index 000000000..3def559ad --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/split-invalid-lastIndex.js @@ -0,0 +1,31 @@ +var BUGNUMBER = 1263851; +var summary = "RegExp.prototype[@@split] should handle if lastIndex is out of bound."; + +print(BUGNUMBER + ": " + summary); + +var myRegExp = { + get constructor() { + return { + get [Symbol.species]() { + return function() { + return { + get lastIndex() { + return 9; + }, + set lastIndex(v) {}, + exec() { + return []; + } + }; + }; + } + }; + } +}; +var result = RegExp.prototype[Symbol.split].call(myRegExp, "abcde");; +assertEq(result.length, 2); +assertEq(result[0], ""); +assertEq(result[1], ""); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/split-limit.js b/js/src/tests/ecma_6/RegExp/split-limit.js new file mode 100644 index 000000000..5fa194b90 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/split-limit.js @@ -0,0 +1,14 @@ +var BUGNUMBER = 1287525; +var summary = "RegExp.prototype[@@split] shouldn't use optimized path if limit is not number."; + +print(BUGNUMBER + ": " + summary); + +var rx = /a/; +var r = rx[Symbol.split]("abba", {valueOf() { + RegExp.prototype.exec = () => null; + return 100; +}}); +assertEq(r.length, 1); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/split-obj.js b/js/src/tests/ecma_6/RegExp/split-obj.js new file mode 100644 index 000000000..75c09f38d --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/split-obj.js @@ -0,0 +1,12 @@ +var BUGNUMBER = 887016; +var summary = "RegExp.prototype[@@split] should check if this value is RegExp."; + +print(BUGNUMBER + ": " + summary); + +var obj = { flags: "", toString: () => "-" }; +assertDeepEq(RegExp.prototype[Symbol.split].call(obj, "a-b-c"), + ["a", "b", "c"]); + +if (typeof reportCompare === "function") + reportCompare(true, true); + diff --git a/js/src/tests/ecma_6/RegExp/split-prop-access.js b/js/src/tests/ecma_6/RegExp/split-prop-access.js new file mode 100644 index 000000000..73c5bebb3 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/split-prop-access.js @@ -0,0 +1,19 @@ +var BUGNUMBER = 1287525; +var summary = 'String.prototype.split should call ToUint32(limit) before ToString(separator).'; + +print(BUGNUMBER + ": " + summary); + +var accessed = false; + +var rx = /a/; +Object.defineProperty(rx, Symbol.match, { + get() { + accessed = true; + } +}); +rx[Symbol.split]("abba"); + +assertEq(accessed, true); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/split-this.js b/js/src/tests/ecma_6/RegExp/split-this.js new file mode 100644 index 000000000..ece29fe8a --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/split-this.js @@ -0,0 +1,12 @@ +var BUGNUMBER = 887016; +var summary = "RegExp.prototype[@@split] should check this value."; + +print(BUGNUMBER + ": " + summary); + +for (var v of [null, 1, true, undefined, "", Symbol.iterator]) { + assertThrowsInstanceOf(() => RegExp.prototype[Symbol.split].call(v), + TypeError); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/split-trace.js b/js/src/tests/ecma_6/RegExp/split-trace.js new file mode 100644 index 000000000..ce6e410d9 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/split-trace.js @@ -0,0 +1,229 @@ +var BUGNUMBER = 887016; +var summary = "Trace RegExp.prototype[@@split] behavior."; + +print(BUGNUMBER + ": " + summary); + +var n; +var log; +var target; +var flags; +var expectedFlags; + +var execResult; +var lastIndexResult; +var lastIndexExpected; + +var arraySetterObserved = false; +function startObserve() { + for (var i = 0; i < 10; i++) { + Object.defineProperty(Array.prototype, i, { + set: function(v) { + arraySetterObserved = true; + }, + configurable: true, + }); + } +} +function stopObserve() { + for (var i = 0; i < 10; i++) + delete Array.prototype[i] +} + +startObserve(); + +function P(A) { + return new Proxy(A, { + get(that, name) { + log += "get:result[" + name + "],"; + return that[name]; + } + }); +} + +var myRegExp = { + get constructor() { + log += "get:constructor,"; + return { + get [Symbol.species]() { + log += "get:species,"; + return function(pattern, flags) { + assertEq(pattern, myRegExp); + assertEq(flags, expectedFlags); + log += "call:constructor,"; + return { + get lastIndex() { + log += "get:lastIndex,"; + return lastIndexResult[n]; + }, + set lastIndex(v) { + log += "set:lastIndex,"; + assertEq(v, lastIndexExpected[n]); + }, + get flags() { + log += "get:flags,"; + return flags; + }, + get exec() { + log += "get:exec,"; + return function(S) { + log += "call:exec,"; + assertEq(S, target); + return execResult[n++]; + }; + }, + }; + }; + } + }; + }, + get flags() { + log += "get:flags,"; + return flags; + }, +}; + +function reset() { + n = 0; + log = ""; + target = "abcde"; + flags = ""; + expectedFlags = "y"; + arraySetterObserved = false; +} + +// Trace match and no match. +reset(); +execResult = [ null, P(["b"]), null, P(["d"]), null ]; +lastIndexResult = [ , , 2, , 4, , ]; +lastIndexExpected = [ 0, 1, 2, 3, 4, ]; +var ret = RegExp.prototype[Symbol.split].call(myRegExp, target); +assertEq(arraySetterObserved, false); +assertEq(JSON.stringify(ret), `["a","c","e"]`); +assertEq(log, + "get:constructor," + + "get:species," + + "get:flags," + + "call:constructor," + + "set:lastIndex,get:exec,call:exec," + + "set:lastIndex,get:exec,call:exec,get:lastIndex," + + "get:result[length]," + + "set:lastIndex,get:exec,call:exec," + + "set:lastIndex,get:exec,call:exec,get:lastIndex," + + "get:result[length]," + + "set:lastIndex,get:exec,call:exec,"); + +// Trace non-empty flags, empty target, no match. +reset(); +flags = "iy"; +expectedFlags = "iy"; +target = ""; +execResult = [ null ]; +lastIndexResult = []; +lastIndexExpected = []; +ret = RegExp.prototype[Symbol.split].call(myRegExp, target); +assertEq(arraySetterObserved, false); +assertEq(JSON.stringify(ret), `[""]`); +assertEq(log, + "get:constructor," + + "get:species," + + "get:flags," + + "call:constructor," + + "get:exec,call:exec,"); + +// Trace empty target, match. +reset(); +target = ""; +execResult = [ P([""]) ]; +lastIndexResult = []; +lastIndexExpected = []; +ret = RegExp.prototype[Symbol.split].call(myRegExp, target); +assertEq(arraySetterObserved, false); +assertEq(JSON.stringify(ret), `[]`); +assertEq(log, + "get:constructor," + + "get:species," + + "get:flags," + + "call:constructor," + + "get:exec,call:exec,"); + +// Trace captures. +reset(); +target = "abc"; +execResult = [ null, P(["b", "X", "YZ"]), null ]; +lastIndexResult = [ , , 2, , ]; +lastIndexExpected = [ 0, 1, 2, ]; +ret = RegExp.prototype[Symbol.split].call(myRegExp, target); +assertEq(arraySetterObserved, false); +assertEq(JSON.stringify(ret), `["a","X","YZ","c"]`); +assertEq(log, + "get:constructor," + + "get:species," + + "get:flags," + + "call:constructor," + + "set:lastIndex,get:exec,call:exec," + + "set:lastIndex,get:exec,call:exec,get:lastIndex," + + "get:result[length]," + + "get:result[1],get:result[2]," + + "set:lastIndex,get:exec,call:exec,"); + +// Trace unicode. +// 1. not surrogate pair +// 2. lead surrogate pair +// 3. trail surrogate pair +// 4. lead surrogate pair without trail surrogate pair +// 5. index overflow +reset(); +flags = "u"; +expectedFlags = "uy"; +target = "-\uD83D\uDC38\uDC38\uD83D"; +execResult = [ null, null, null, null ]; +lastIndexResult = [ , , , , , ]; +lastIndexExpected = [ 0, 1, 3, 4, ]; +ret = RegExp.prototype[Symbol.split].call(myRegExp, target); +assertEq(arraySetterObserved, false); +assertEq(JSON.stringify(ret), `["-\uD83D\uDC38\uDC38\uD83D"]`); +assertEq(log, + "get:constructor," + + "get:species," + + "get:flags," + + "call:constructor," + + "set:lastIndex,get:exec,call:exec," + + "set:lastIndex,get:exec,call:exec," + + "set:lastIndex,get:exec,call:exec," + + "set:lastIndex,get:exec,call:exec,"); + +// Trace unicode, match, same position and different position. +reset(); +flags = "u"; +expectedFlags = "uy"; +target = "-\uD83D\uDC38\uDC38\uD83D"; +var E = P(["", "X"]); +execResult = [ E, E, E, E, E, E, E ]; +lastIndexResult = [ , 0, 1, 1, 3, 3, 4, 4 ]; +lastIndexExpected = [ 0, 1, 1, 3, 3, 4, 4, ]; +ret = RegExp.prototype[Symbol.split].call(myRegExp, target); +assertEq(arraySetterObserved, false); +assertEq(JSON.stringify(ret), `["-","X","\uD83D\uDC38","X","\uDC38","X","\uD83D"]`); +assertEq(log, + "get:constructor," + + "get:species," + + "get:flags," + + "call:constructor," + + "set:lastIndex,get:exec,call:exec,get:lastIndex," + + "set:lastIndex,get:exec,call:exec,get:lastIndex," + + "get:result[length]," + + "get:result[1]," + + "set:lastIndex,get:exec,call:exec,get:lastIndex," + + "set:lastIndex,get:exec,call:exec,get:lastIndex," + + "get:result[length]," + + "get:result[1]," + + "set:lastIndex,get:exec,call:exec,get:lastIndex," + + "set:lastIndex,get:exec,call:exec,get:lastIndex," + + "get:result[length]," + + "get:result[1]," + + "set:lastIndex,get:exec,call:exec,get:lastIndex,"); + +stopObserve(); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/split.js b/js/src/tests/ecma_6/RegExp/split.js new file mode 100644 index 000000000..d7e28d791 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/split.js @@ -0,0 +1,30 @@ +var BUGNUMBER = 887016; +var summary = "Implement RegExp.prototype[@@split]."; + +print(BUGNUMBER + ": " + summary); + +assertEq(RegExp.prototype[Symbol.split].name, "[Symbol.split]"); +assertEq(RegExp.prototype[Symbol.split].length, 2); +var desc = Object.getOwnPropertyDescriptor(RegExp.prototype, Symbol.split); +assertEq(desc.configurable, true); +assertEq(desc.enumerable, false); +assertEq(desc.writable, true); + +var re = /b/; +var v = re[Symbol.split]("abcAbcABC"); +assertEq(JSON.stringify(v), `["a","cA","cABC"]`); + +re = /d/; +v = re[Symbol.split]("abcAbcABC"); +assertEq(JSON.stringify(v), `["abcAbcABC"]`); + +re = /b/ig; +v = re[Symbol.split]("abcAbcABC"); +assertEq(JSON.stringify(v), `["a","cA","cA","C"]`); + +re = /b/ig; +v = re[Symbol.split]("abcAbcABC", 2); +assertEq(JSON.stringify(v), `["a","cA"]`); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/sticky.js b/js/src/tests/ecma_6/RegExp/sticky.js new file mode 100644 index 000000000..13a6debe9 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/sticky.js @@ -0,0 +1,126 @@ +var BUGNUMBER = 773687; +var summary = 'sticky flag should not break assertion behavior.'; + +print(BUGNUMBER + ": " + summary); + +function test(re, text, expectations) { + // Sanity check for test data itself. + assertEq(expectations.length, text.length + 1); + + for (var i = 0; i < expectations.length; i++) { + var result = expectations[i]; + + re.lastIndex = i; + var match = re.exec(text); + if (result === null) { + assertEq(re.lastIndex, 0); + assertEq(match, null); + } else { + assertEq(re.lastIndex, result.lastIndex); + assertEq(match !== null, true); + assertEq(match.length, result.matches.length); + for (var j = 0; j < result.matches.length; j++) + assertEq(match[j], result.matches[j]); + assertEq(match.index, result.index); + } + } +} + +// simple text +test(/bc/y, "abcabd", [ + null, + { lastIndex: 3, matches: ["bc"], index: 1 }, + null, + null, + null, + null, + null, +]); + +// complex pattern +test(/bc|c|d/y, "abcabd", [ + null, + { lastIndex: 3, matches: ["bc"], index: 1 }, + { lastIndex: 3, matches: ["c"], index: 2 }, + null, + null, + { lastIndex: 6, matches: ["d"], index: 5 }, + null, +]); + +test(/.*(bc|c|d)/y, "abcabd", [ + { lastIndex: 6, matches: ["abcabd", "d"], index: 0 }, + { lastIndex: 6, matches: ["bcabd", "d"], index: 1 }, + { lastIndex: 6, matches: ["cabd", "d"], index: 2 }, + { lastIndex: 6, matches: ["abd", "d"], index: 3 }, + { lastIndex: 6, matches: ["bd", "d"], index: 4 }, + { lastIndex: 6, matches: ["d", "d"], index: 5 }, + null, +]); + +test(/.*?(bc|c|d)/y, "abcabd", [ + { lastIndex: 3, matches: ["abc", "bc"], index: 0 }, + { lastIndex: 3, matches: ["bc", "bc"], index: 1 }, + { lastIndex: 3, matches: ["c", "c"], index: 2 }, + { lastIndex: 6, matches: ["abd", "d"], index: 3 }, + { lastIndex: 6, matches: ["bd", "d"], index: 4 }, + { lastIndex: 6, matches: ["d", "d"], index: 5 }, + null, +]); + +test(/(bc|.*c|d)/y, "abcabd", [ + { lastIndex: 3, matches: ["abc", "abc"], index: 0 }, + { lastIndex: 3, matches: ["bc", "bc"], index: 1 }, + { lastIndex: 3, matches: ["c", "c"], index: 2 }, + null, + null, + { lastIndex: 6, matches: ["d", "d"], index: 5 }, + null, +]); + +// ^ assertions +test(/^/y, "abcabc", [ + { lastIndex: 0, matches: [""], index: 0 }, + null, + null, + null, + null, + null, + null, +]); + +test(/^a/my, "abc\nabc", [ + { lastIndex: 1, matches: ["a"], index: 0 }, + null, + null, + null, + { lastIndex: 5, matches: ["a"], index: 4 }, + null, + null, + null, +]); + +// \b assertions +test(/\b/y, "abc bc", [ + { lastIndex: 0, matches: [""], index: 0 }, + null, + null, + { lastIndex: 3, matches: [""], index: 3 }, + { lastIndex: 4, matches: [""], index: 4 }, + null, + { lastIndex: 6, matches: [""], index: 6 }, +]); + +// \B assertions +test(/\B/y, "abc bc", [ + null, + { lastIndex: 1, matches: [""], index: 1 }, + { lastIndex: 2, matches: [""], index: 2 }, + null, + null, + { lastIndex: 5, matches: [""], index: 5 }, + null, +]); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/test-trailing.js b/js/src/tests/ecma_6/RegExp/test-trailing.js new file mode 100644 index 000000000..7cb910ee6 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/test-trailing.js @@ -0,0 +1,31 @@ +var BUGNUMBER = 1304737; +var summary = "Trailing .* should not be ignored on matchOnly match."; + +print(BUGNUMBER + ": " + summary); + +function test(r, lastIndexIsZero) { + r.lastIndex = 0; + r.test("foo"); + assertEq(r.lastIndex, lastIndexIsZero ? 0 : 3); + + r.lastIndex = 0; + r.test("foo\nbar"); + assertEq(r.lastIndex, lastIndexIsZero ? 0 : 3); + + var input = "foo" + ".bar".repeat(20000); + r.lastIndex = 0; + r.test(input); + assertEq(r.lastIndex, lastIndexIsZero ? 0 : input.length); + + r.lastIndex = 0; + r.test(input + "\nbaz"); + assertEq(r.lastIndex, lastIndexIsZero ? 0 : input.length); +} + +test(/f.*/, true); +test(/f.*/g, false); +test(/f.*/y, false); +test(/f.*/gy, false); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/toString.js b/js/src/tests/ecma_6/RegExp/toString.js new file mode 100644 index 000000000..5ffbeed33 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/toString.js @@ -0,0 +1,42 @@ +var BUGNUMBER = 1079919; +var summary = "Make RegExp.prototype.toString to be a generic function."; + +print(BUGNUMBER + ": " + summary); + +assertEq(RegExp.prototype.toString(), "/(?:)/"); +assertEq(/foo/.toString(), "/foo/"); +assertEq(/foo/i.toString(), "/foo/i"); +assertEq(/foo/gimy.toString(), "/foo/gimy"); +assertEq(/foo/igym.toString(), "/foo/gimy"); +assertEq(/\n\r/.toString(), "/\\n\\r/"); +assertEq(/\u2028\u2029/.toString(), "/\\u2028\\u2029/"); +assertEq(/\//.toString(), "/\\//"); +assertEq(RegExp().toString(), "/(?:)/"); +assertEq(RegExp("", "gimy").toString(), "/(?:)/gimy"); +assertEq(RegExp("\n\r").toString(), "/\\n\\r/"); +assertEq(RegExp("\u2028\u2029").toString(), "/\\u2028\\u2029/"); +assertEq(RegExp("/").toString(), "/\\//"); + +assertThrowsInstanceOf(() => RegExp.prototype.toString.call(), TypeError); +assertThrowsInstanceOf(() => RegExp.prototype.toString.call(1), TypeError); +assertThrowsInstanceOf(() => RegExp.prototype.toString.call(""), TypeError); +assertEq(RegExp.prototype.toString.call({}), "/undefined/undefined"); +assertEq(RegExp.prototype.toString.call({ source:"foo", flags:"bar" }), "/foo/bar"); + +var a = []; +var p = new Proxy({}, { + get(that, name) { + a.push(name); + return { + toString() { + a.push(name + "-tostring"); + return name; + } + }; + } +}); +assertEq(RegExp.prototype.toString.call(p), "/source/flags"); +assertEq(a.join(","), "source,source-tostring,flags,flags-tostring"); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-back-reference.js b/js/src/tests/ecma_6/RegExp/unicode-back-reference.js new file mode 100644 index 000000000..2a65432a1 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-back-reference.js @@ -0,0 +1,39 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- back reference should not match lead surrogate that has corresponding trail surrogate."; + +print(BUGNUMBER + ": " + summary); + +// The last character of back reference is not a surrogate. +assertEqArray(/foo(.+)bar\1/u.exec("fooAbarA\uDC00"), + ["fooAbarA", "A"]); +assertEqArray(/foo(.+)bar\1/u.exec("fooAbarA\uD834"), + ["fooAbarA", "A"]); +assertEqArray(/foo(.+)bar\1/u.exec("fooAbarAA"), + ["fooAbarA", "A"]); +assertEqArray(/foo(.+)bar\1/u.exec("fooAbarA"), + ["fooAbarA", "A"]); + +// The last character of back reference is a lead surrogate. +assertEq(/foo(.+)bar\1/u.exec("foo\uD834bar\uD834\uDC00"), null); +assertEqArray(/foo(.+)bar\1/u.exec("foo\uD834bar\uD834\uD834"), + ["foo\uD834bar\uD834", "\uD834"]); +assertEqArray(/foo(.+)bar\1/u.exec("foo\uD834bar\uD834A"), + ["foo\uD834bar\uD834", "\uD834"]); +assertEqArray(/foo(.+)bar\1/u.exec("foo\uD834bar\uD834"), + ["foo\uD834bar\uD834", "\uD834"]); + +// The last character of back reference is a trail surrogate. +assertEqArray(/foo(.+)bar\1/u.exec("foo\uDC00bar\uDC00\uDC00"), + ["foo\uDC00bar\uDC00", "\uDC00"]); +assertEqArray(/foo(.+)bar\1/u.exec("foo\uDC00bar\uDC00\uD834"), + ["foo\uDC00bar\uDC00", "\uDC00"]); +assertEqArray(/foo(.+)bar\1/u.exec("foo\uDC00bar\uDC00A"), + ["foo\uDC00bar\uDC00", "\uDC00"]); +assertEqArray(/foo(.+)bar\1/u.exec("foo\uDC00bar\uDC00"), + ["foo\uDC00bar\uDC00", "\uDC00"]); + +// Pattern should not match to surrogate pair partially. +assertEq(/^(.+)\1$/u.exec("\uDC00foobar\uD834\uDC00foobar\uD834"), null); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-braced.js b/js/src/tests/ecma_6/RegExp/unicode-braced.js new file mode 100644 index 000000000..97df7acab --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-braced.js @@ -0,0 +1,166 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- braced pattern in RegExpUnicodeEscapeSequence."; + +print(BUGNUMBER + ": " + summary); + +// ==== standalone ==== + +assertEqArray(/\u{41}/u.exec("ABC"), + ["A"]); +assertEqArray(/\u{41}/.exec("ABC" + "u".repeat(41)), + ["u".repeat(41)]); + +assertEqArray(/\u{4A}/u.exec("JKL"), + ["J"]); +assertEqArray(/\u{4A}/.exec("JKLu{4A}"), + ["u{4A}"]); + +assertEqArray(/\u{1F438}/u.exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(/\u{1F438}/.exec("u{1F438}"), + ["u{1F438}"]); + +assertEqArray(/\u{0}/u.exec("\u{0}"), + ["\u{0}"]); +assertEqArray(/\u{10FFFF}/u.exec("\u{10FFFF}"), + ["\u{10FFFF}"]); +assertEqArray(/\u{10ffff}/u.exec("\u{10FFFF}"), + ["\u{10FFFF}"]); + +// leading 0 +assertEqArray(/\u{0000000000000000000000}/u.exec("\u{0}"), + ["\u{0}"]); +assertEqArray(/\u{000000000000000010FFFF}/u.exec("\u{10FFFF}"), + ["\u{10FFFF}"]); + +// RegExp constructor +assertEqArray(new RegExp("\\u{0}", "u").exec("\u{0}"), + ["\u{0}"]); +assertEqArray(new RegExp("\\u{41}", "u").exec("ABC"), + ["A"]); +assertEqArray(new RegExp("\\u{1F438}", "u").exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(new RegExp("\\u{10FFFF}", "u").exec("\u{10FFFF}"), + ["\u{10FFFF}"]); + +assertEqArray(new RegExp("\\u{0000000000000000}", "u").exec("\u{0}"), + ["\u{0}"]); + +assertEqArray(eval(`/\\u{${"0".repeat(Math.pow(2, 24)) + "1234"}}/u`).exec("\u{1234}"), + ["\u{1234}"]); +assertEqArray(new RegExp(`\\u{${"0".repeat(Math.pow(2, 24)) + "1234"}}`, "u").exec("\u{1234}"), + ["\u{1234}"]); + +// ==== ? ==== + +assertEqArray(/\u{1F438}?/u.exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(/\u{1F438}?/u.exec(""), + [""]); + +// lead-only target +assertEqArray(/\u{1F438}?/u.exec("\uD83D"), + [""]); + +// RegExp constructor +assertEqArray(new RegExp("\\u{1F438}?", "u").exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(new RegExp("\\u{1F438}?", "u").exec(""), + [""]); +assertEqArray(new RegExp("\\u{1F438}?", "u").exec("\uD83D"), + [""]); + +// ==== + ==== + +assertEqArray(/\u{1F438}+/u.exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(/\u{1F438}+/u.exec("\u{1F438}\u{1F438}"), + ["\u{1F438}\u{1F438}"]); +assertEq(/\u{1F438}+/u.exec(""), + null); + +// lead-only target +assertEq(/\u{1F438}+/u.exec("\uD83D"), + null); +assertEqArray(/\u{1F438}+/u.exec("\uD83D\uDC38\uDC38"), + ["\uD83D\uDC38"]); + +// ==== * ==== + +assertEqArray(/\u{1F438}*/u.exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(/\u{1F438}*/u.exec("\u{1F438}\u{1F438}"), + ["\u{1F438}\u{1F438}"]); +assertEqArray(/\u{1F438}*/u.exec(""), + [""]); + +// lead-only target +assertEqArray(/\u{1F438}*/u.exec("\uD83D"), + [""]); +assertEqArray(/\u{1F438}*/u.exec("\uD83D\uDC38\uDC38"), + ["\uD83D\uDC38"]); + +// ==== lead-only ==== + +// match only non-surrogate pair +assertEqArray(/\u{D83D}/u.exec("\uD83D\uDBFF"), + ["\uD83D"]); +assertEq(/\u{D83D}/u.exec("\uD83D\uDC00"), + null); +assertEq(/\u{D83D}/u.exec("\uD83D\uDFFF"), + null); +assertEqArray(/\u{D83D}/u.exec("\uD83D\uE000"), + ["\uD83D"]); + +// match before non-tail char +assertEqArray(/\u{D83D}/u.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/\u{D83D}/u.exec("\uD83DA"), + ["\uD83D"]); + +// ==== trail-only ==== + +// match only non-surrogate pair +assertEqArray(/\u{DC38}/u.exec("\uD7FF\uDC38"), + ["\uDC38"]); +assertEq(/\u{DC38}/u.exec("\uD800\uDC38"), + null); +assertEq(/\u{DC38}/u.exec("\uDBFF\uDC38"), + null); +assertEqArray(/\u{DC38}/u.exec("\uDC00\uDC38"), + ["\uDC38"]); + +// match after non-lead char +assertEqArray(/\u{DC38}/u.exec("\uDC38"), + ["\uDC38"]); +assertEqArray(/\u{DC38}/u.exec("A\uDC38"), + ["\uDC38"]); + +// ==== wrong patterns ==== + +assertThrowsInstanceOf(() => eval(`/\\u{-1}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u{0.0}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u{G}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u{}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u{{/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u{/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u{110000}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u{00110000}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u{100000000000000000000000000000}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u{FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u{ FFFF}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u{FFFF }/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u{FF FF}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u{F F F F}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u{100000001}/u`), SyntaxError); + +// surrogate pair with braced +assertEq(/\u{D83D}\u{DC38}+/u.exec("\uD83D\uDC38\uDC38"), + null); +assertEq(/\uD83D\u{DC38}+/u.exec("\uD83D\uDC38\uDC38"), + null); +assertEq(/\u{D83D}\uDC38+/u.exec("\uD83D\uDC38\uDC38"), + null); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-character-class-escape.js b/js/src/tests/ecma_6/RegExp/unicode-character-class-escape.js new file mode 100644 index 000000000..175207d5a --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-character-class-escape.js @@ -0,0 +1,75 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- CharacterClassEscape."; + +print(BUGNUMBER + ": " + summary); + +// BMP + +assertEqArray(/\d+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"), + ["0123456789"]); +assertEqArray(/\D+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"), + ["abcxyzABCXYZ"]); + +assertEqArray(/\s+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"), + ["\t\r\n\v\x0c\xa0\uFEFF"]); +assertEqArray(/\S+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"), + ["abcxyzABCXYZ0123456789_"]); + +assertEqArray(/\w+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"), + ["abcxyzABCXYZ0123456789_"]); +assertEqArray(/\W+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"), + ["\t\r\n\v\x0c\xa0\uFEFF*"]); + +assertEqArray(/\n+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"), + ["\n"]); + +assertEqArray(/[\d]+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"), + ["0123456789"]); +assertEqArray(/[\D]+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"), + ["abcxyzABCXYZ"]); + +assertEqArray(/[\s]+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"), + ["\t\r\n\v\x0c\xa0\uFEFF"]); +assertEqArray(/[\S]+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"), + ["abcxyzABCXYZ0123456789_"]); + +assertEqArray(/[\w]+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"), + ["abcxyzABCXYZ0123456789_"]); +assertEqArray(/[\W]+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"), + ["\t\r\n\v\x0c\xa0\uFEFF*"]); + +assertEqArray(/[\n]+/u.exec("abcxyzABCXYZ0123456789_\t\r\n\v\x0c\xa0\uFEFF*"), + ["\n"]); + +// non-BMP + +function testNonBMP(re) { + assertEqArray(re.exec("\uD83D\uDBFF"), + ["\uD83D"]); + assertEqArray(re.exec("\uD83D\uDC00"), + ["\uD83D\uDC00"]); + assertEqArray(re.exec("\uD83D\uDFFF"), + ["\uD83D\uDFFF"]); + assertEqArray(re.exec("\uD83D\uE000"), + ["\uD83D"]); + + assertEqArray(re.exec("\uD7FF\uDC38"), + ["\uD7FF"]); + assertEqArray(re.exec("\uD800\uDC38"), + ["\uD800\uDC38"]); + assertEqArray(re.exec("\uDBFF\uDC38"), + ["\uDBFF\uDC38"]); + assertEqArray(re.exec("\uDC00\uDC38"), + ["\uDC00"]); +} + +testNonBMP(/\D/u); +testNonBMP(/\S/u); +testNonBMP(/\W/u); + +testNonBMP(/[\D]/u); +testNonBMP(/[\S]/u); +testNonBMP(/[\W]/u); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-class-braced.js b/js/src/tests/ecma_6/RegExp/unicode-class-braced.js new file mode 100644 index 000000000..4b5954012 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-class-braced.js @@ -0,0 +1,236 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- braced pattern in RegExpUnicodeEscapeSequence in CharacterClass."; + +print(BUGNUMBER + ": " + summary); + +// ==== standalone ==== + +assertEqArray(/[\u{41}]/u.exec("ABC"), + ["A"]); + +assertEqArray(/[\u{1F438}]/u.exec("\u{1F438}"), + ["\u{1F438}"]); +assertEq(/[\u{1F438}]/u.exec("\uD83D"), + null); +assertEq(/[\u{1F438}]/u.exec("\uDC38"), + null); + +assertEqArray(/[\u{0}]/u.exec("\u{0}"), + ["\u{0}"]); +assertEqArray(/[\u{10FFFF}]/u.exec("\u{10FFFF}"), + ["\u{10FFFF}"]); +assertEqArray(/[\u{10ffff}]/u.exec("\u{10FFFF}"), + ["\u{10FFFF}"]); + +// leading 0 +assertEqArray(/[\u{0000000000000000000000}]/u.exec("\u{0}"), + ["\u{0}"]); +assertEqArray(/[\u{000000000000000010FFFF}]/u.exec("\u{10FFFF}"), + ["\u{10FFFF}"]); + +// RegExp constructor +assertEqArray(new RegExp("[\\u{0}]", "u").exec("\u{0}"), + ["\u{0}"]); +assertEqArray(new RegExp("[\\u{41}]", "u").exec("ABC"), + ["A"]); +assertEqArray(new RegExp("[\\u{1F438}]", "u").exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(new RegExp("[\\u{10FFFF}]", "u").exec("\u{10FFFF}"), + ["\u{10FFFF}"]); + +assertEqArray(new RegExp("[\\u{0000000000000000}]", "u").exec("\u{0}"), + ["\u{0}"]); + +assertEqArray(eval(`/[\\u{${"0".repeat(Math.pow(2, 24)) + "1234"}}]/u`).exec("\u{1234}"), + ["\u{1234}"]); +assertEqArray(new RegExp(`[\\u{${"0".repeat(Math.pow(2, 24)) + "1234"}}]`, "u").exec("\u{1234}"), + ["\u{1234}"]); + +// ==== BMP + non-BMP ==== + +assertEqArray(/[A\u{1F438}]/u.exec("A\u{1F438}"), + ["A"]); +assertEqArray(/[A\u{1F438}]/u.exec("\u{1F438}A"), + ["\u{1F438}"]); + +// lead-only target +assertEqArray(/[A\u{1F438}]/u.exec("\uD83DA"), + ["A"]); +assertEq(/[A\u{1F438}]/u.exec("\uD83D"), + null); + +// + +assertEqArray(/[A\u{1F438}]+/u.exec("\u{1F438}A\u{1F438}A"), + ["\u{1F438}A\u{1F438}A"]); + +// trail surrogate + lead surrogate +assertEqArray(/[A\u{1F438}]+/u.exec("\uD83D\uDC38A\uDC38\uD83DA"), + ["\uD83D\uDC38A"]); + +// ==== non-BMP + non-BMP ==== + +assertEqArray(/[\u{1F418}\u{1F438}]/u.exec("\u{1F418}\u{1F438}"), + ["\u{1F418}"]); + +assertEqArray(/[\u{1F418}\u{1F438}]+/u.exec("\u{1F418}\u{1F438}"), + ["\u{1F418}\u{1F438}"]); +assertEqArray(/[\u{1F418}\u{1F438}]+/u.exec("\u{1F418}\uDC38\uD83D"), + ["\u{1F418}"]); +assertEqArray(/[\u{1F418}\u{1F438}]+/u.exec("\uDC18\uD83D\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(/[\u{1F418}\u{1F438}]+/u.exec("\uDC18\u{1F438}\uD83D"), + ["\u{1F438}"]); + +// trail surrogate + lead surrogate +assertEq(/[\u{1F418}\u{1F438}]+/u.exec("\uDC18\uDC38\uD83D\uD83D"), + null); + +// ==== non-BMP + non-BMP range (from_lead == to_lead) ==== + +assertEqArray(/[\u{1F418}-\u{1F438}]/u.exec("\u{1F418}"), + ["\u{1F418}"]); +assertEqArray(/[\u{1F418}-\u{1F438}]/u.exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(/[\u{1F418}-\u{1F438}]/u.exec("\u{1F427}"), + ["\u{1F427}"]); + +assertEq(/[\u{1F418}-\u{1F438}]/u.exec("\u{1F417}"), + null); +assertEq(/[\u{1F418}-\u{1F438}]/u.exec("\u{1F439}"), + null); + +// ==== non-BMP + non-BMP range (from_lead + 1 == to_lead) ==== + +assertEqArray(/[\u{1F17C}-\u{1F438}]/u.exec("\uD83C\uDD7C"), + ["\uD83C\uDD7C"]); +assertEqArray(/[\u{1F17C}-\u{1F438}]/u.exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(/[\u{1F17C}-\u{1F438}]/u.exec("\uD83C\uDF99"), + ["\uD83C\uDF99"]); +assertEqArray(/[\u{1F17C}-\u{1F438}]/u.exec("\uD83D\uDC00"), + ["\uD83D\uDC00"]); + +assertEq(/[\u{1F17C}-\u{1F438}]/u.exec("\uD83C\uDD7B"), + null); +assertEq(/[\u{1F17C}-\u{1F438}]/u.exec("\uD83C\uE000"), + null); +assertEq(/[\u{1F17C}-\u{1F438}]/u.exec("\uD83D\uDB99"), + null); +assertEq(/[\u{1F17C}-\u{1F438}]/u.exec("\uD83D\uDC39"), + null); + +// ==== non-BMP + non-BMP range (from_lead + 2 == to_lead) ==== + +assertEqArray(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83C\uDD7C"), + ["\uD83C\uDD7C"]); +assertEqArray(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83E\uDC29"), + ["\uD83E\uDC29"]); + +assertEqArray(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83C\uDF99"), + ["\uD83C\uDF99"]); +assertEqArray(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83D\uDC00"), + ["\uD83D\uDC00"]); +assertEqArray(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83D\uDF99"), + ["\uD83D\uDF99"]); +assertEqArray(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83E\uDC00"), + ["\uD83E\uDC00"]); + +assertEq(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83C\uDD7B"), + null); +assertEq(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83C\uE000"), + null); +assertEq(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83D\uDB99"), + null); +assertEq(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83D\uE000"), + null); +assertEq(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83E\uDB99"), + null); +assertEq(/[\u{1F17C}-\u{1F829}]/u.exec("\uD83E\uDC30"), + null); + +// ==== non-BMP + non-BMP range (other) ==== + +assertEqArray(/[\u{1D164}-\u{1F438}]/u.exec("\uD834\uDD64"), + ["\uD834\uDD64"]); +assertEqArray(/[\u{1D164}-\u{1F438}]/u.exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(/[\u{1D164}-\u{1F438}]/u.exec("\uD836\uDF99"), + ["\uD836\uDF99"]); +assertEqArray(/[\u{1D164}-\u{1F438}]/u.exec("\uD838\uDC00"), + ["\uD838\uDC00"]); + +assertEq(/[\u{1D164}-\u{1F438}]/u.exec("\uD834\uDD63"), + null); +assertEq(/[\u{1D164}-\u{1F438}]/u.exec("\uD83D\uDC39"), + null); + +assertEq(/[\u{1D164}-\u{1F438}]/u.exec("\uD834\uE000"), + null); +assertEq(/[\u{1D164}-\u{1F438}]/u.exec("\uD835\uDB99"), + null); +assertEq(/[\u{1D164}-\u{1F438}]/u.exec("\uD83C\uE000"), + null); +assertEq(/[\u{1D164}-\u{1F438}]/u.exec("\uD83D\uDB99"), + null); + +// ==== BMP + non-BMP range ==== + +assertEqArray(/[\u{42}-\u{1F438}]/u.exec("B"), + ["B"]); +assertEqArray(/[\u{42}-\u{1F438}]/u.exec("C"), + ["C"]); +assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uFFFF"), + ["\uFFFF"]); +assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uD800\uDC00"), + ["\uD800\uDC00"]); + +assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uD800"), + ["\uD800"]); +assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uDBFF"), + ["\uDBFF"]); +assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uDC00"), + ["\uDC00"]); +assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uDFFF"), + ["\uDFFF"]); + +assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uDC38"), + ["\uDC38"]); + +assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uD83D\uDBFF"), + ["\uD83D"]); +assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uD83D\uDC00"), + ["\uD83D\uDC00"]); +assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uD83D\uDC38"), + ["\uD83D\uDC38"]); +assertEq(/[\u{42}-\u{1F438}]/u.exec("\uD83D\uDC39"), + null); +assertEq(/[\u{42}-\u{1F438}]/u.exec("\uD83D\uDFFF"), + null); +assertEqArray(/[\u{42}-\u{1F438}]/u.exec("\uD83D\uE000"), + ["\uD83D"]); + +assertEq(/[\u{42}-\u{1F438}]/u.exec("A"), + null); + +// ==== wrong patterns ==== + +assertThrowsInstanceOf(() => eval(`/[\\u{-1}]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u{0.0}]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u{G}]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u{}]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u{{]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u{]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u{110000}]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u{00110000}]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u{100000000000000000000000000000}]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u{FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF}]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u{ FFFF}]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u{FFFF }]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u{FF FF}]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u{F F F F}]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u{100000001}]/u`), SyntaxError); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-class-empty.js b/js/src/tests/ecma_6/RegExp/unicode-class-empty.js new file mode 100644 index 000000000..4d187551f --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-class-empty.js @@ -0,0 +1,25 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- empty class should not match anything."; + +print(BUGNUMBER + ": " + summary); + +assertEq(/[]/u.exec("A"), + null); +assertEq(/[]/u.exec("\uD83D"), + null); +assertEq(/[]/u.exec("\uDC38"), + null); +assertEq(/[]/u.exec("\uD83D\uDC38"), + null); + +assertEqArray(/[^]/u.exec("A"), + ["A"]); +assertEqArray(/[^]/u.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/[^]/u.exec("\uDC38"), + ["\uDC38"]); +assertEqArray(/[^]/u.exec("\uD83D\uDC38"), + ["\uD83D\uDC38"]); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-class-ignoreCase.js b/js/src/tests/ecma_6/RegExp/unicode-class-ignoreCase.js new file mode 100644 index 000000000..afa7705c7 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-class-ignoreCase.js @@ -0,0 +1,28 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- ignoreCase flag for CharacterClass."; + +print(BUGNUMBER + ": " + summary); + +assertEqArray(/[ABC]+/iu.exec("DCBAabcd"), + ["CBAabc"]); + +assertEqArray(/[A\u{10401}]+/iu.exec("A\u{10401}a\u{10429}"), + ["A\u{10401}a\u{10429}"]); + +assertEqArray(/[\u{10401}-\u{10404}\u{10408}-\u{1040B}]+/iu.exec("\u{10400}\u{10401}\u{10402}\u{10403}\u{10404}\u{10408}\u{10409}\u{1040A}\u{1040B}\u{1040C}"), + ["\u{10401}\u{10402}\u{10403}\u{10404}\u{10408}\u{10409}\u{1040A}\u{1040B}"]); +assertEqArray(/[\u{10401}-\u{10404}\u{10408}-\u{1040B}]+/iu.exec("\u{10428}\u{10429}\u{1042A}\u{1042B}\u{1042C}\u{10430}\u{10431}\u{10432}\u{10433}\u{10434}"), + ["\u{10429}\u{1042A}\u{1042B}\u{1042C}\u{10430}\u{10431}\u{10432}\u{10433}"]); + +assertEqArray(/[\u{10429}-\u{1042C}\u{10430}-\u{10433}]+/iu.exec("\u{10400}\u{10401}\u{10402}\u{10403}\u{10404}\u{10408}\u{10409}\u{1040A}\u{1040B}\u{1040C}"), + ["\u{10401}\u{10402}\u{10403}\u{10404}\u{10408}\u{10409}\u{1040A}\u{1040B}"]); +assertEqArray(/[\u{10429}-\u{1042C}\u{10430}-\u{10433}]+/iu.exec("\u{10428}\u{10429}\u{1042A}\u{1042B}\u{1042C}\u{10430}\u{10431}\u{10432}\u{10433}\u{10434}"), + ["\u{10429}\u{1042A}\u{1042B}\u{1042C}\u{10430}\u{10431}\u{10432}\u{10433}"]); + +assertEqArray(/[\u{10401}-\u{10404}\u{10430}-\u{10433}]+/iu.exec("\u{10400}\u{10401}\u{10402}\u{10403}\u{10404}\u{10408}\u{10409}\u{1040A}\u{1040B}\u{1040C}"), + ["\u{10401}\u{10402}\u{10403}\u{10404}\u{10408}\u{10409}\u{1040A}\u{1040B}"]); +assertEqArray(/[\u{10401}-\u{10404}\u{10430}-\u{10433}]+/iu.exec("\u{10428}\u{10429}\u{1042A}\u{1042B}\u{1042C}\u{10430}\u{10431}\u{10432}\u{10433}\u{10434}"), + ["\u{10429}\u{1042A}\u{1042B}\u{1042C}\u{10430}\u{10431}\u{10432}\u{10433}"]); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-class-lead-trail.js b/js/src/tests/ecma_6/RegExp/unicode-class-lead-trail.js new file mode 100644 index 000000000..c83bf937d --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-class-lead-trail.js @@ -0,0 +1,142 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- lead and trail pattern in RegExpUnicodeEscapeSequence in CharacterClass."; + +print(BUGNUMBER + ": " + summary); + +// ==== standalone ==== + +assertEqArray(/[\uD83D\uDC38]/u.exec("\uD83D\uDC38"), + ["\uD83D\uDC38"]); +assertEq(/[\uD83D\uDC38]/u.exec("\uD83D"), + null); +assertEq(/[\uD83D\uDC38]/u.exec("\uDC38"), + null); + +// no unicode flag +assertEqArray(/[\uD83D\uDC38]/.exec("\uD83D\uDC38"), + ["\uD83D"]); +assertEqArray(/[\uD83D\uDC38]/.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/[\uD83D\uDC38]/.exec("\uDC38"), + ["\uDC38"]); + +// RegExp constructor +assertEqArray(new RegExp("[\uD83D\uDC38]", "u").exec("\uD83D\uDC38"), + ["\uD83D\uDC38"]); +assertEq(new RegExp("[\uD83D\uDC38]", "u").exec("\uD83D"), + null); +assertEq(new RegExp("[\uD83D\uDC38]", "u").exec("\uDC38"), + null); + +// RegExp constructor, no unicode flag +assertEqArray(new RegExp("[\uD83D\uDC38]", "").exec("\uD83D\uDC38"), + ["\uD83D"]); +assertEqArray(new RegExp("[\uD83D\uDC38]", "").exec("\uD83D"), + ["\uD83D"]); +assertEqArray(new RegExp("[\uD83D\uDC38]", "").exec("\uDC38"), + ["\uDC38"]); + +// ==== lead-only ==== + +// match only non-surrogate pair +assertEqArray(/[\uD83D]/u.exec("\uD83D\uDBFF"), + ["\uD83D"]); +assertEq(/[\uD83D]/u.exec("\uD83D\uDC00"), + null); +assertEq(/[\uD83D]/u.exec("\uD83D\uDFFF"), + null); +assertEqArray(/[\uD83D]/u.exec("\uD83D\uE000"), + ["\uD83D"]); + +// match before non-tail char +assertEqArray(/[\uD83D]/u.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/[\uD83D]/u.exec("\uD83DA"), + ["\uD83D"]); + +// no unicode flag +assertEqArray(/[\uD83D]/.exec("\uD83D\uDBFF"), + ["\uD83D"]); +assertEqArray(/[\uD83D]/.exec("\uD83D\uDC00"), + ["\uD83D"]); +assertEqArray(/[\uD83D]/.exec("\uD83D\uDFFF"), + ["\uD83D"]); +assertEqArray(/[\uD83D]/.exec("\uD83D\uE000"), + ["\uD83D"]); +assertEqArray(/[\uD83D]/.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/[\uD83D]/.exec("\uD83DA"), + ["\uD83D"]); + +// ==== trail-only ==== + +// match only non-surrogate pair +assertEqArray(/[\uDC38]/u.exec("\uD7FF\uDC38"), + ["\uDC38"]); +assertEq(/[\uDC38]/u.exec("\uD800\uDC38"), + null); +assertEq(/[\uDC38]/u.exec("\uDBFF\uDC38"), + null); +assertEqArray(/[\uDC38]/u.exec("\uDC00\uDC38"), + ["\uDC38"]); + +// match after non-lead char +assertEqArray(/[\uDC38]/u.exec("\uDC38"), + ["\uDC38"]); +assertEqArray(/[\uDC38]/u.exec("A\uDC38"), + ["\uDC38"]); + +// no unicode flag +assertEqArray(/[\uDC38]/.exec("\uD7FF\uDC38"), + ["\uDC38"]); +assertEqArray(/[\uDC38]/.exec("\uD800\uDC38"), + ["\uDC38"]); +assertEqArray(/[\uDC38]/.exec("\uDBFF\uDC38"), + ["\uDC38"]); +assertEqArray(/[\uDC38]/.exec("\uDC00\uDC38"), + ["\uDC38"]); +assertEqArray(/[\uDC38]/.exec("\uDC38"), + ["\uDC38"]); +assertEqArray(/[\uDC38]/.exec("A\uDC38"), + ["\uDC38"]); + +// ==== invalid trail ==== + +assertEqArray(/[\uD83D\u3042]*/u.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/[\uD83D\u3042]*/u.exec("\uD83D\u3042"), + ["\uD83D\u3042"]); +assertEqArray(/[\uD83D\u3042]*/u.exec("\uD83D\u3042\u3042\uD83D"), + ["\uD83D\u3042\u3042\uD83D"]); + +assertEqArray(/[\uD83D\u{3042}]*/u.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/[\uD83D\u{3042}]*/u.exec("\uD83D\u3042"), + ["\uD83D\u3042"]); +assertEqArray(/[\uD83D\u{3042}]*/u.exec("\uD83D\u3042\u3042\uD83D"), + ["\uD83D\u3042\u3042\uD83D"]); + +assertEqArray(/[\uD83DA]*/u.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/[\uD83DA]*/u.exec("\uD83DA"), + ["\uD83DA"]); +assertEqArray(/[\uD83DA]*/u.exec("\uD83DAA\uD83D"), + ["\uD83DAA\uD83D"]); + +// ==== wrong patterns ==== + +assertThrowsInstanceOf(() => eval(`/[\\u]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u0]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u00]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u000]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u000G]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\u0.00]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\uD83D\\u]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\uD83D\\u0]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\uD83D\\u00]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\uD83D\\u000]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\uD83D\\u000G]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\uD83D\\u0.00]/u`), SyntaxError); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-class-negated.js b/js/src/tests/ecma_6/RegExp/unicode-class-negated.js new file mode 100644 index 000000000..0b573f6dc --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-class-negated.js @@ -0,0 +1,64 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- negated CharacterClass."; + +print(BUGNUMBER + ": " + summary); + +// ==== BMP ==== + +assertEqArray(/[^A]/u.exec("ABC"), + ["B"]); +assertEqArray(/[^A]/u.exec("A\u{1F438}C"), + ["\u{1F438}"]); +assertEqArray(/[^A]/u.exec("A\uD83DC"), + ["\uD83D"]); +assertEqArray(/[^A]/u.exec("A\uDC38C"), + ["\uDC38"]); + +assertEqArray(/[^\uE000]/u.exec("\uE000\uE001"), + ["\uE001"]); +assertEqArray(/[^\uE000]/u.exec("\uE000\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(/[^\uE000]/u.exec("\uE000\uD83D"), + ["\uD83D"]); +assertEqArray(/[^\uE000]/u.exec("\uE000\uDC38"), + ["\uDC38"]); + +// ==== non-BMP ==== + +assertEqArray(/[^\u{1F438}]/u.exec("\u{1F438}A"), + ["A"]); +assertEqArray(/[^\u{1F438}]/u.exec("\u{1F438}\u{1F439}"), + ["\u{1F439}"]); +assertEqArray(/[^\u{1F438}]/u.exec("\u{1F438}\uD83D"), + ["\uD83D"]); +assertEqArray(/[^\u{1F438}]/u.exec("\u{1F438}\uDC38"), + ["\uDC38"]); + +// ==== lead-only ==== + +assertEqArray(/[^\uD83D]/u.exec("\u{1F438}A"), + ["\u{1F438}"]); +assertEqArray(/[^\uD83D]/u.exec("\uD83D\uDBFF"), + ["\uDBFF"]); +assertEqArray(/[^\uD83D]/u.exec("\uD83D\uDC00"), + ["\uD83D\uDC00"]); +assertEqArray(/[^\uD83D]/u.exec("\uD83D\uDFFF"), + ["\uD83D\uDFFF"]); +assertEqArray(/[^\uD83D]/u.exec("\uD83D\uE000"), + ["\uE000"]); + +// ==== trail-only ==== + +assertEqArray(/[^\uDC38]/u.exec("\u{1F438}A"), + ["\u{1F438}"]); +assertEqArray(/[^\uDC38]/u.exec("\uD7FF\uDC38"), + ["\uD7FF"]); +assertEqArray(/[^\uDC38]/u.exec("\uD800\uDC38"), + ["\uD800\uDC38"]); +assertEqArray(/[^\uDC38]/u.exec("\uDBFF\uDC38"), + ["\uDBFF\uDC38"]); +assertEqArray(/[^\uDC38]/u.exec("\uDC00\uDC38"), + ["\uDC00"]); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-class-range.js b/js/src/tests/ecma_6/RegExp/unicode-class-range.js new file mode 100644 index 000000000..5bb757560 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-class-range.js @@ -0,0 +1,28 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- disallow range with CharacterClassEscape."; + +print(BUGNUMBER + ": " + summary); + +assertThrowsInstanceOf(() => eval(`/[\\w-\\uFFFF]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\W-\\uFFFF]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\d-\\uFFFF]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\D-\\uFFFF]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\s-\\uFFFF]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\S-\\uFFFF]/u`), SyntaxError); + +assertThrowsInstanceOf(() => eval(`/[\\uFFFF-\\w]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\uFFFF-\\W]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\uFFFF-\\d]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\uFFFF-\\D]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\uFFFF-\\s]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\uFFFF-\\S]/u`), SyntaxError); + +assertThrowsInstanceOf(() => eval(`/[\\w-\\w]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\W-\\W]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\d-\\d]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\D-\\D]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\s-\\s]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\S-\\S]/u`), SyntaxError); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-class-raw.js b/js/src/tests/ecma_6/RegExp/unicode-class-raw.js new file mode 100644 index 000000000..742fec2b4 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-class-raw.js @@ -0,0 +1,65 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- raw unicode."; + +print(BUGNUMBER + ": " + summary); + +// ==== standalone ==== + +assertEqArray(eval(`/[\uD83D\uDC38]/u`).exec("\u{1F438}"), + ["\u{1F438}"]); + +// no unicode flag +assertEqArray(eval(`/[\uD83D\uDC38]/`).exec("\u{1F438}"), + ["\uD83D"]); + +// escaped (lead) +assertEq(eval(`/[\\uD83D\uDC38]/u`).exec("\u{1F438}"), + null); +assertEq(eval(`/[\\u{D83D}\uDC38]/u`).exec("\u{1F438}"), + null); + +// escaped (trail) +assertEq(eval(`/[\uD83D\\uDC38]/u`).exec("\u{1F438}"), + null); +assertEq(eval(`/[\uD83D\\u{DC38}]/u`).exec("\u{1F438}"), + null); + +// escaped (lead), no unicode flag +assertEqArray(eval(`/[\\uD83D\uDC38]/`).exec("\u{1F438}"), + ["\uD83D"]); + +// escaped (trail), no unicode flag +assertEqArray(eval(`/[\uD83D\\uDC38]/`).exec("\u{1F438}"), + ["\uD83D"]); + +// ==== RegExp constructor ==== + +assertEqArray(new RegExp("[\uD83D\uDC38]", "u").exec("\u{1F438}"), + ["\u{1F438}"]); + +// no unicode flag +assertEqArray(new RegExp("[\uD83D\uDC38]", "").exec("\u{1F438}"), + ["\uD83D"]); + +// escaped(lead) +assertEq(new RegExp("[\\uD83D\uDC38]", "u").exec("\u{1F438}"), + null); +assertEq(new RegExp("[\\u{D83D}\uDC38]", "u").exec("\u{1F438}"), + null); + +// escaped(trail) +assertEq(new RegExp("[\uD83D\\uDC38]", "u").exec("\u{1F438}"), + null); +assertEq(new RegExp("[\uD83D\\u{DC38}]", "u").exec("\u{1F438}"), + null); + +// escaped(lead), no unicode flag +assertEqArray(new RegExp("[\\uD83D\uDC38]", "").exec("\u{1F438}"), + ["\uD83D"]); + +// escaped(trail), no unicode flag +assertEqArray(new RegExp("[\uD83D\\uDC38]", "").exec("\u{1F438}"), + ["\uD83D"]); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-disallow-extended.js b/js/src/tests/ecma_6/RegExp/unicode-disallow-extended.js new file mode 100644 index 000000000..d1f775fac --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-disallow-extended.js @@ -0,0 +1,117 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- disallow extended patterns."; + +print(BUGNUMBER + ": " + summary); + +// IdentityEscape + +assertEqArray(/\^\$\\\.\*\+\?\(\)\[\]\{\}\|/u.exec("^$\\.*+?()[]{}|"), + ["^$\\.*+?()[]{}|"]); +assertThrowsInstanceOf(() => eval(`/\\A/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\-/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\U{10}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\U0000/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\uD83D\\U0000/u`), SyntaxError); + +assertEqArray(/[\^\$\\\.\*\+\?\(\)\[\]\{\}\|]+/u.exec("^$\\.*+?()[]{}|"), + ["^$\\.*+?()[]{}|"]); +assertThrowsInstanceOf(() => eval(`/[\\A]/u`), SyntaxError); +assertEqArray(/[A\-Z]+/u.exec("a-zABC"), + ["-"]); +assertThrowsInstanceOf(() => eval(`/[\\U{10}]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\U0000]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\uD83D\\U0000]/u`), SyntaxError); + +// PatternCharacter +assertThrowsInstanceOf(() => eval(`/{}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/{/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/{0}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/{1,}/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/{1,2}/u`), SyntaxError); + +// QuantifiableAssertion +assertEqArray(/.B(?=A)/u.exec("cBaCBA"), + ["CB"]); +assertEqArray(/.B(?!A)/u.exec("CBAcBa"), + ["cB"]); +assertEqArray(/.B(?:A)/u.exec("cBaCBA"), + ["CBA"]); +assertEqArray(/.B(A)/u.exec("cBaCBA"), + ["CBA", "A"]); + +assertThrowsInstanceOf(() => eval(`/.B(?=A)+/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/.B(?!A)+/u`), SyntaxError); +assertEqArray(/.B(?:A)+/u.exec("cBaCBA"), + ["CBA"]); +assertEqArray(/.B(A)+/u.exec("cBaCBA"), + ["CBA", "A"]); + +// ControlLetter +assertEqArray(/\cA/u.exec("\u0001"), + ["\u0001"]); +assertEqArray(/\cZ/u.exec("\u001a"), + ["\u001a"]); +assertEqArray(/\ca/u.exec("\u0001"), + ["\u0001"]); +assertEqArray(/\cz/u.exec("\u001a"), + ["\u001a"]); + +assertEqArray(/[\cA]/u.exec("\u0001"), + ["\u0001"]); +assertEqArray(/[\cZ]/u.exec("\u001a"), + ["\u001a"]); +assertEqArray(/[\ca]/u.exec("\u0001"), + ["\u0001"]); +assertEqArray(/[\cz]/u.exec("\u001a"), + ["\u001a"]); + +assertThrowsInstanceOf(() => eval(`/\\c/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\c1/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\c_/u`), SyntaxError); + +assertThrowsInstanceOf(() => eval(`/[\\c]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\c1]/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/[\\c_]/u`), SyntaxError); + +// HexEscapeSequence +assertThrowsInstanceOf(() => eval(`/\\x/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\x0/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\x1/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\x1G/u`), SyntaxError); + +// LegacyOctalEscapeSequence +assertThrowsInstanceOf(() => eval(`/\\52/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\052/u`), SyntaxError); + +// DecimalEscape +assertEqArray(/\0/u.exec("\0"), + ["\0"]); +assertEqArray(/[\0]/u.exec("\0"), + ["\0"]); +assertEqArray(/\0A/u.exec("\0A"), + ["\0A"]); +assertEqArray(/\0G/u.exec("\0G"), + ["\0G"]); +assertEqArray(/(A.)\1/u.exec("ABACABAB"), + ["ABAB", "AB"]); +assertEqArray(/(A.)(B.)(C.)(D.)(E.)(F.)(G.)(H.)(I.)(J.)(K.)\10/u.exec("A1B2C3D4E5F6G7H8I9JaKbJa"), + ["A1B2C3D4E5F6G7H8I9JaKbJa", "A1", "B2", "C3", "D4", "E5", "F6", "G7", "H8", "I9", "Ja", "Kb"]); + +assertThrowsInstanceOf(() => eval(`/\\00/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\01/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\09/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\1/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\2/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\3/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\4/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\5/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\6/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\7/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\8/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\9/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\10/u`), SyntaxError); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-everything.js b/js/src/tests/ecma_6/RegExp/unicode-everything.js new file mode 100644 index 000000000..a18ac2867 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-everything.js @@ -0,0 +1,59 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- everything Atom."; + +print(BUGNUMBER + ": " + summary); + +// ==== standalone ==== + +assertEqArray(/./u.exec("ABC"), + ["A"]); +assertEqArray(/./u.exec("\u{1F438}BC"), + ["\u{1F438}"]); + +assertEqArray(/./u.exec("\uD83D\uDBFF"), + ["\uD83D"]); +assertEqArray(/./u.exec("\uD83D\uDC00"), + ["\uD83D\uDC00"]); +assertEqArray(/./u.exec("\uD83D\uDFFF"), + ["\uD83D\uDFFF"]); +assertEqArray(/./u.exec("\uD83D\uE000"), + ["\uD83D"]); +assertEqArray(/./u.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/./u.exec("\uD83DA"), + ["\uD83D"]); + +assertEqArray(/./u.exec("\uD7FF\uDC38"), + ["\uD7FF"]); +assertEqArray(/./u.exec("\uD800\uDC38"), + ["\uD800\uDC38"]); +assertEqArray(/./u.exec("\uDBFF\uDC38"), + ["\uDBFF\uDC38"]); +assertEqArray(/./u.exec("\uDC00\uDC38"), + ["\uDC00"]); +assertEqArray(/./u.exec("\uDC38"), + ["\uDC38"]); +assertEqArray(/./u.exec("A\uDC38"), + ["A"]); + +assertEqArray(/.A/u.exec("\uD7FF\uDC38A"), + ["\uDC38A"]); +assertEqArray(/.A/u.exec("\uD800\uDC38A"), + ["\uD800\uDC38A"]); +assertEqArray(/.A/u.exec("\uDBFF\uDC38A"), + ["\uDBFF\uDC38A"]); +assertEqArray(/.A/u.exec("\uDC00\uDC38A"), + ["\uDC38A"]); + +// ==== leading multiple ==== + +assertEqArray(/.*A/u.exec("\u{1F438}\u{1F438}\u{1F438}A"), + ["\u{1F438}\u{1F438}\u{1F438}A"]); + +// ==== trailing multiple ==== + +assertEqArray(/A.*/u.exec("A\u{1F438}\u{1F438}\u{1F438}"), + ["A\u{1F438}\u{1F438}\u{1F438}"]); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-ascii.js b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-ascii.js new file mode 100644 index 000000000..6d453290e --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-ascii.js @@ -0,0 +1,45 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- ignoreCase flag with non-ascii to ascii map."; + +print(BUGNUMBER + ": " + summary); + +// LATIN CAPITAL LETTER Y WITH DIAERESIS +assertEqArray(/\u0178/iu.exec("\u00FF"), + ["\u00FF"]); +assertEqArray(/\u00FF/iu.exec("\u0178"), + ["\u0178"]); + +// LATIN SMALL LETTER LONG S +assertEqArray(/\u017F/iu.exec("S"), + ["S"]); +assertEqArray(/\u017F/iu.exec("s"), + ["s"]); +assertEqArray(/S/iu.exec("\u017F"), + ["\u017F"]); +assertEqArray(/s/iu.exec("\u017F"), + ["\u017F"]); + +// LATIN CAPITAL LETTER SHARP S +assertEqArray(/\u1E9E/iu.exec("\u00DF"), + ["\u00DF"]); +assertEqArray(/\u00DF/iu.exec("\u1E9E"), + ["\u1E9E"]); + +// KELVIN SIGN +assertEqArray(/\u212A/iu.exec("K"), + ["K"]); +assertEqArray(/\u212A/iu.exec("k"), + ["k"]); +assertEqArray(/K/iu.exec("\u212A"), + ["\u212A"]); +assertEqArray(/k/iu.exec("\u212A"), + ["\u212A"]); + +// ANGSTROM SIGN +assertEqArray(/\u212B/iu.exec("\u00E5"), + ["\u00E5"]); +assertEqArray(/\u00E5/iu.exec("\u212B"), + ["\u212B"]); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-escape.js b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-escape.js new file mode 100644 index 000000000..d731fb6bb --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-escape.js @@ -0,0 +1,71 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- ignoreCase flag with character class escape."; + +// \W doesn't match S or K from the change in +// https://github.com/tc39/ecma262/pull/525 +// (bug 1281739) + +print(BUGNUMBER + ": " + summary); + +// LATIN SMALL LETTER LONG S + +assertEqArray(/\w/iu.exec("S"), + ["S"]); +assertEqArray(/\w/iu.exec("s"), + ["s"]); +assertEqArray(/\w/iu.exec("\u017F"), + ["\u017F"]); + +assertEqArray(/[^\W]/iu.exec("S"), + ["S"]); +assertEqArray(/[^\W]/iu.exec("s"), + ["s"]); +assertEqArray(/[^\W]/iu.exec("\u017F"), + ["\u017F"]); + +assertEq(/\W/iu.exec("S"), + null); +assertEq(/\W/iu.exec("s"), + null); +assertEq(/\W/iu.exec("\u017F"), + null); + +assertEq(/[^\w]/iu.exec("S"), + null); +assertEq(/[^\w]/iu.exec("s"), + null); +assertEq(/[^\w]/iu.exec("\u017F"), + null); + +// KELVIN SIGN + +assertEqArray(/\w/iu.exec("k"), + ["k"]); +assertEqArray(/\w/iu.exec("k"), + ["k"]); +assertEqArray(/\w/iu.exec("\u212A"), + ["\u212A"]); + +assertEqArray(/[^\W]/iu.exec("k"), + ["k"]); +assertEqArray(/[^\W]/iu.exec("k"), + ["k"]); +assertEqArray(/[^\W]/iu.exec("\u212A"), + ["\u212A"]); + +assertEq(/\W/iu.exec("k"), + null); +assertEq(/\W/iu.exec("k"), + null); +assertEq(/\W/iu.exec("\u212A"), + null); + +assertEq(/[^\w]/iu.exec("k"), + null); +assertEq(/[^\w]/iu.exec("k"), + null); +assertEq(/[^\w]/iu.exec("\u212A"), + null); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-negated.js b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-negated.js new file mode 100644 index 000000000..30909a515 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase-negated.js @@ -0,0 +1,19 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- ignoreCase flag with negated character class."; + +print(BUGNUMBER + ": " + summary); + +assertEq(/[^A]/iu.exec("A"), + null); +assertEq(/[^a]/iu.exec("A"), + null); +assertEq(/[^A]/iu.exec("a"), + null); +assertEq(/[^a]/iu.exec("a"), + null); + +assertEqArray(/[^A]/iu.exec("b"), + ["b"]); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-ignoreCase.js b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase.js new file mode 100644 index 000000000..28b2e77dc --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-ignoreCase.js @@ -0,0 +1,2643 @@ +/* Generated by make_unicode.py DO NOT MODIFY */ +/* Unicode version: 9.0.0 */ + +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- ignoreCase flag."; + +print(BUGNUMBER + ": " + summary); + +function test(code, ...equivs) { + var codeRe = new RegExp(String.fromCodePoint(code) + "+", "iu"); + var ans = String.fromCodePoint(code) + equivs.map(c => String.fromCodePoint(c)).join(""); + assertEqArray(codeRe.exec("<" + ans + ">"), [ans]); + codeRe = new RegExp("[" + String.fromCodePoint(code) + "]+", "iu"); + assertEqArray(codeRe.exec("<" + ans + ">"), [ans]); +} +test(0x41,0x61); +test(0x42,0x62); +test(0x43,0x63); +test(0x44,0x64); +test(0x45,0x65); +test(0x46,0x66); +test(0x47,0x67); +test(0x48,0x68); +test(0x49,0x69); +test(0x4a,0x6a); +test(0x4b,0x6b,0x212a); +test(0x4c,0x6c); +test(0x4d,0x6d); +test(0x4e,0x6e); +test(0x4f,0x6f); +test(0x50,0x70); +test(0x51,0x71); +test(0x52,0x72); +test(0x53,0x73,0x17f); +test(0x54,0x74); +test(0x55,0x75); +test(0x56,0x76); +test(0x57,0x77); +test(0x58,0x78); +test(0x59,0x79); +test(0x5a,0x7a); +test(0x61,0x41); +test(0x62,0x42); +test(0x63,0x43); +test(0x64,0x44); +test(0x65,0x45); +test(0x66,0x46); +test(0x67,0x47); +test(0x68,0x48); +test(0x69,0x49); +test(0x6a,0x4a); +test(0x6b,0x4b,0x212a); +test(0x6c,0x4c); +test(0x6d,0x4d); +test(0x6e,0x4e); +test(0x6f,0x4f); +test(0x70,0x50); +test(0x71,0x51); +test(0x72,0x52); +test(0x73,0x53,0x17f); +test(0x74,0x54); +test(0x75,0x55); +test(0x76,0x56); +test(0x77,0x57); +test(0x78,0x58); +test(0x79,0x59); +test(0x7a,0x5a); +test(0xb5,0x3bc,0x39c); +test(0xc0,0xe0); +test(0xc1,0xe1); +test(0xc2,0xe2); +test(0xc3,0xe3); +test(0xc4,0xe4); +test(0xc5,0xe5,0x212b); +test(0xc6,0xe6); +test(0xc7,0xe7); +test(0xc8,0xe8); +test(0xc9,0xe9); +test(0xca,0xea); +test(0xcb,0xeb); +test(0xcc,0xec); +test(0xcd,0xed); +test(0xce,0xee); +test(0xcf,0xef); +test(0xd0,0xf0); +test(0xd1,0xf1); +test(0xd2,0xf2); +test(0xd3,0xf3); +test(0xd4,0xf4); +test(0xd5,0xf5); +test(0xd6,0xf6); +test(0xd8,0xf8); +test(0xd9,0xf9); +test(0xda,0xfa); +test(0xdb,0xfb); +test(0xdc,0xfc); +test(0xdd,0xfd); +test(0xde,0xfe); +test(0xdf,0x1e9e); +test(0xe0,0xc0); +test(0xe1,0xc1); +test(0xe2,0xc2); +test(0xe3,0xc3); +test(0xe4,0xc4); +test(0xe5,0xc5,0x212b); +test(0xe6,0xc6); +test(0xe7,0xc7); +test(0xe8,0xc8); +test(0xe9,0xc9); +test(0xea,0xca); +test(0xeb,0xcb); +test(0xec,0xcc); +test(0xed,0xcd); +test(0xee,0xce); +test(0xef,0xcf); +test(0xf0,0xd0); +test(0xf1,0xd1); +test(0xf2,0xd2); +test(0xf3,0xd3); +test(0xf4,0xd4); +test(0xf5,0xd5); +test(0xf6,0xd6); +test(0xf8,0xd8); +test(0xf9,0xd9); +test(0xfa,0xda); +test(0xfb,0xdb); +test(0xfc,0xdc); +test(0xfd,0xdd); +test(0xfe,0xde); +test(0xff,0x178); +test(0x100,0x101); +test(0x101,0x100); +test(0x102,0x103); +test(0x103,0x102); +test(0x104,0x105); +test(0x105,0x104); +test(0x106,0x107); +test(0x107,0x106); +test(0x108,0x109); +test(0x109,0x108); +test(0x10a,0x10b); +test(0x10b,0x10a); +test(0x10c,0x10d); +test(0x10d,0x10c); +test(0x10e,0x10f); +test(0x10f,0x10e); +test(0x110,0x111); +test(0x111,0x110); +test(0x112,0x113); +test(0x113,0x112); +test(0x114,0x115); +test(0x115,0x114); +test(0x116,0x117); +test(0x117,0x116); +test(0x118,0x119); +test(0x119,0x118); +test(0x11a,0x11b); +test(0x11b,0x11a); +test(0x11c,0x11d); +test(0x11d,0x11c); +test(0x11e,0x11f); +test(0x11f,0x11e); +test(0x120,0x121); +test(0x121,0x120); +test(0x122,0x123); +test(0x123,0x122); +test(0x124,0x125); +test(0x125,0x124); +test(0x126,0x127); +test(0x127,0x126); +test(0x128,0x129); +test(0x129,0x128); +test(0x12a,0x12b); +test(0x12b,0x12a); +test(0x12c,0x12d); +test(0x12d,0x12c); +test(0x12e,0x12f); +test(0x12f,0x12e); +test(0x132,0x133); +test(0x133,0x132); +test(0x134,0x135); +test(0x135,0x134); +test(0x136,0x137); +test(0x137,0x136); +test(0x139,0x13a); +test(0x13a,0x139); +test(0x13b,0x13c); +test(0x13c,0x13b); +test(0x13d,0x13e); +test(0x13e,0x13d); +test(0x13f,0x140); +test(0x140,0x13f); +test(0x141,0x142); +test(0x142,0x141); +test(0x143,0x144); +test(0x144,0x143); +test(0x145,0x146); +test(0x146,0x145); +test(0x147,0x148); +test(0x148,0x147); +test(0x14a,0x14b); +test(0x14b,0x14a); +test(0x14c,0x14d); +test(0x14d,0x14c); +test(0x14e,0x14f); +test(0x14f,0x14e); +test(0x150,0x151); +test(0x151,0x150); +test(0x152,0x153); +test(0x153,0x152); +test(0x154,0x155); +test(0x155,0x154); +test(0x156,0x157); +test(0x157,0x156); +test(0x158,0x159); +test(0x159,0x158); +test(0x15a,0x15b); +test(0x15b,0x15a); +test(0x15c,0x15d); +test(0x15d,0x15c); +test(0x15e,0x15f); +test(0x15f,0x15e); +test(0x160,0x161); +test(0x161,0x160); +test(0x162,0x163); +test(0x163,0x162); +test(0x164,0x165); +test(0x165,0x164); +test(0x166,0x167); +test(0x167,0x166); +test(0x168,0x169); +test(0x169,0x168); +test(0x16a,0x16b); +test(0x16b,0x16a); +test(0x16c,0x16d); +test(0x16d,0x16c); +test(0x16e,0x16f); +test(0x16f,0x16e); +test(0x170,0x171); +test(0x171,0x170); +test(0x172,0x173); +test(0x173,0x172); +test(0x174,0x175); +test(0x175,0x174); +test(0x176,0x177); +test(0x177,0x176); +test(0x178,0xff); +test(0x179,0x17a); +test(0x17a,0x179); +test(0x17b,0x17c); +test(0x17c,0x17b); +test(0x17d,0x17e); +test(0x17e,0x17d); +test(0x17f,0x73,0x53); +test(0x180,0x243); +test(0x181,0x253); +test(0x182,0x183); +test(0x183,0x182); +test(0x184,0x185); +test(0x185,0x184); +test(0x186,0x254); +test(0x187,0x188); +test(0x188,0x187); +test(0x189,0x256); +test(0x18a,0x257); +test(0x18b,0x18c); +test(0x18c,0x18b); +test(0x18e,0x1dd); +test(0x18f,0x259); +test(0x190,0x25b); +test(0x191,0x192); +test(0x192,0x191); +test(0x193,0x260); +test(0x194,0x263); +test(0x195,0x1f6); +test(0x196,0x269); +test(0x197,0x268); +test(0x198,0x199); +test(0x199,0x198); +test(0x19a,0x23d); +test(0x19c,0x26f); +test(0x19d,0x272); +test(0x19e,0x220); +test(0x19f,0x275); +test(0x1a0,0x1a1); +test(0x1a1,0x1a0); +test(0x1a2,0x1a3); +test(0x1a3,0x1a2); +test(0x1a4,0x1a5); +test(0x1a5,0x1a4); +test(0x1a6,0x280); +test(0x1a7,0x1a8); +test(0x1a8,0x1a7); +test(0x1a9,0x283); +test(0x1ac,0x1ad); +test(0x1ad,0x1ac); +test(0x1ae,0x288); +test(0x1af,0x1b0); +test(0x1b0,0x1af); +test(0x1b1,0x28a); +test(0x1b2,0x28b); +test(0x1b3,0x1b4); +test(0x1b4,0x1b3); +test(0x1b5,0x1b6); +test(0x1b6,0x1b5); +test(0x1b7,0x292); +test(0x1b8,0x1b9); +test(0x1b9,0x1b8); +test(0x1bc,0x1bd); +test(0x1bd,0x1bc); +test(0x1bf,0x1f7); +test(0x1c4,0x1c6,0x1c5); +test(0x1c5,0x1c6,0x1c4); +test(0x1c6,0x1c4,0x1c5); +test(0x1c7,0x1c9,0x1c8); +test(0x1c8,0x1c9,0x1c7); +test(0x1c9,0x1c7,0x1c8); +test(0x1ca,0x1cc,0x1cb); +test(0x1cb,0x1cc,0x1ca); +test(0x1cc,0x1ca,0x1cb); +test(0x1cd,0x1ce); +test(0x1ce,0x1cd); +test(0x1cf,0x1d0); +test(0x1d0,0x1cf); +test(0x1d1,0x1d2); +test(0x1d2,0x1d1); +test(0x1d3,0x1d4); +test(0x1d4,0x1d3); +test(0x1d5,0x1d6); +test(0x1d6,0x1d5); +test(0x1d7,0x1d8); +test(0x1d8,0x1d7); +test(0x1d9,0x1da); +test(0x1da,0x1d9); +test(0x1db,0x1dc); +test(0x1dc,0x1db); +test(0x1dd,0x18e); +test(0x1de,0x1df); +test(0x1df,0x1de); +test(0x1e0,0x1e1); +test(0x1e1,0x1e0); +test(0x1e2,0x1e3); +test(0x1e3,0x1e2); +test(0x1e4,0x1e5); +test(0x1e5,0x1e4); +test(0x1e6,0x1e7); +test(0x1e7,0x1e6); +test(0x1e8,0x1e9); +test(0x1e9,0x1e8); +test(0x1ea,0x1eb); +test(0x1eb,0x1ea); +test(0x1ec,0x1ed); +test(0x1ed,0x1ec); +test(0x1ee,0x1ef); +test(0x1ef,0x1ee); +test(0x1f1,0x1f3,0x1f2); +test(0x1f2,0x1f3,0x1f1); +test(0x1f3,0x1f1,0x1f2); +test(0x1f4,0x1f5); +test(0x1f5,0x1f4); +test(0x1f6,0x195); +test(0x1f7,0x1bf); +test(0x1f8,0x1f9); +test(0x1f9,0x1f8); +test(0x1fa,0x1fb); +test(0x1fb,0x1fa); +test(0x1fc,0x1fd); +test(0x1fd,0x1fc); +test(0x1fe,0x1ff); +test(0x1ff,0x1fe); +test(0x200,0x201); +test(0x201,0x200); +test(0x202,0x203); +test(0x203,0x202); +test(0x204,0x205); +test(0x205,0x204); +test(0x206,0x207); +test(0x207,0x206); +test(0x208,0x209); +test(0x209,0x208); +test(0x20a,0x20b); +test(0x20b,0x20a); +test(0x20c,0x20d); +test(0x20d,0x20c); +test(0x20e,0x20f); +test(0x20f,0x20e); +test(0x210,0x211); +test(0x211,0x210); +test(0x212,0x213); +test(0x213,0x212); +test(0x214,0x215); +test(0x215,0x214); +test(0x216,0x217); +test(0x217,0x216); +test(0x218,0x219); +test(0x219,0x218); +test(0x21a,0x21b); +test(0x21b,0x21a); +test(0x21c,0x21d); +test(0x21d,0x21c); +test(0x21e,0x21f); +test(0x21f,0x21e); +test(0x220,0x19e); +test(0x222,0x223); +test(0x223,0x222); +test(0x224,0x225); +test(0x225,0x224); +test(0x226,0x227); +test(0x227,0x226); +test(0x228,0x229); +test(0x229,0x228); +test(0x22a,0x22b); +test(0x22b,0x22a); +test(0x22c,0x22d); +test(0x22d,0x22c); +test(0x22e,0x22f); +test(0x22f,0x22e); +test(0x230,0x231); +test(0x231,0x230); +test(0x232,0x233); +test(0x233,0x232); +test(0x23a,0x2c65); +test(0x23b,0x23c); +test(0x23c,0x23b); +test(0x23d,0x19a); +test(0x23e,0x2c66); +test(0x23f,0x2c7e); +test(0x240,0x2c7f); +test(0x241,0x242); +test(0x242,0x241); +test(0x243,0x180); +test(0x244,0x289); +test(0x245,0x28c); +test(0x246,0x247); +test(0x247,0x246); +test(0x248,0x249); +test(0x249,0x248); +test(0x24a,0x24b); +test(0x24b,0x24a); +test(0x24c,0x24d); +test(0x24d,0x24c); +test(0x24e,0x24f); +test(0x24f,0x24e); +test(0x250,0x2c6f); +test(0x251,0x2c6d); +test(0x252,0x2c70); +test(0x253,0x181); +test(0x254,0x186); +test(0x256,0x189); +test(0x257,0x18a); +test(0x259,0x18f); +test(0x25b,0x190); +test(0x25c,0xa7ab); +test(0x260,0x193); +test(0x261,0xa7ac); +test(0x263,0x194); +test(0x265,0xa78d); +test(0x266,0xa7aa); +test(0x268,0x197); +test(0x269,0x196); +test(0x26a,0xa7ae); +test(0x26b,0x2c62); +test(0x26c,0xa7ad); +test(0x26f,0x19c); +test(0x271,0x2c6e); +test(0x272,0x19d); +test(0x275,0x19f); +test(0x27d,0x2c64); +test(0x280,0x1a6); +test(0x283,0x1a9); +test(0x287,0xa7b1); +test(0x288,0x1ae); +test(0x289,0x244); +test(0x28a,0x1b1); +test(0x28b,0x1b2); +test(0x28c,0x245); +test(0x292,0x1b7); +test(0x29d,0xa7b2); +test(0x29e,0xa7b0); +test(0x345,0x3b9,0x399,0x1fbe); +test(0x370,0x371); +test(0x371,0x370); +test(0x372,0x373); +test(0x373,0x372); +test(0x376,0x377); +test(0x377,0x376); +test(0x37b,0x3fd); +test(0x37c,0x3fe); +test(0x37d,0x3ff); +test(0x37f,0x3f3); +test(0x386,0x3ac); +test(0x388,0x3ad); +test(0x389,0x3ae); +test(0x38a,0x3af); +test(0x38c,0x3cc); +test(0x38e,0x3cd); +test(0x38f,0x3ce); +test(0x391,0x3b1); +test(0x392,0x3b2,0x3d0); +test(0x393,0x3b3); +test(0x394,0x3b4); +test(0x395,0x3b5,0x3f5); +test(0x396,0x3b6); +test(0x397,0x3b7); +test(0x398,0x3b8,0x3d1,0x3f4); +test(0x399,0x3b9,0x345,0x1fbe); +test(0x39a,0x3ba,0x3f0); +test(0x39b,0x3bb); +test(0x39c,0x3bc,0xb5); +test(0x39d,0x3bd); +test(0x39e,0x3be); +test(0x39f,0x3bf); +test(0x3a0,0x3c0,0x3d6); +test(0x3a1,0x3c1,0x3f1); +test(0x3a3,0x3c3,0x3c2); +test(0x3a4,0x3c4); +test(0x3a5,0x3c5); +test(0x3a6,0x3c6,0x3d5); +test(0x3a7,0x3c7); +test(0x3a8,0x3c8); +test(0x3a9,0x3c9,0x2126); +test(0x3aa,0x3ca); +test(0x3ab,0x3cb); +test(0x3ac,0x386); +test(0x3ad,0x388); +test(0x3ae,0x389); +test(0x3af,0x38a); +test(0x3b1,0x391); +test(0x3b2,0x392,0x3d0); +test(0x3b3,0x393); +test(0x3b4,0x394); +test(0x3b5,0x395,0x3f5); +test(0x3b6,0x396); +test(0x3b7,0x397); +test(0x3b8,0x398,0x3d1,0x3f4); +test(0x3b9,0x345,0x399,0x1fbe); +test(0x3ba,0x39a,0x3f0); +test(0x3bb,0x39b); +test(0x3bc,0xb5,0x39c); +test(0x3bd,0x39d); +test(0x3be,0x39e); +test(0x3bf,0x39f); +test(0x3c0,0x3a0,0x3d6); +test(0x3c1,0x3a1,0x3f1); +test(0x3c2,0x3c3,0x3a3); +test(0x3c3,0x3a3,0x3c2); +test(0x3c4,0x3a4); +test(0x3c5,0x3a5); +test(0x3c6,0x3a6,0x3d5); +test(0x3c7,0x3a7); +test(0x3c8,0x3a8); +test(0x3c9,0x3a9,0x2126); +test(0x3ca,0x3aa); +test(0x3cb,0x3ab); +test(0x3cc,0x38c); +test(0x3cd,0x38e); +test(0x3ce,0x38f); +test(0x3cf,0x3d7); +test(0x3d0,0x3b2,0x392); +test(0x3d1,0x3b8,0x398,0x3f4); +test(0x3d5,0x3c6,0x3a6); +test(0x3d6,0x3c0,0x3a0); +test(0x3d7,0x3cf); +test(0x3d8,0x3d9); +test(0x3d9,0x3d8); +test(0x3da,0x3db); +test(0x3db,0x3da); +test(0x3dc,0x3dd); +test(0x3dd,0x3dc); +test(0x3de,0x3df); +test(0x3df,0x3de); +test(0x3e0,0x3e1); +test(0x3e1,0x3e0); +test(0x3e2,0x3e3); +test(0x3e3,0x3e2); +test(0x3e4,0x3e5); +test(0x3e5,0x3e4); +test(0x3e6,0x3e7); +test(0x3e7,0x3e6); +test(0x3e8,0x3e9); +test(0x3e9,0x3e8); +test(0x3ea,0x3eb); +test(0x3eb,0x3ea); +test(0x3ec,0x3ed); +test(0x3ed,0x3ec); +test(0x3ee,0x3ef); +test(0x3ef,0x3ee); +test(0x3f0,0x3ba,0x39a); +test(0x3f1,0x3c1,0x3a1); +test(0x3f2,0x3f9); +test(0x3f3,0x37f); +test(0x3f4,0x3b8,0x398,0x3d1); +test(0x3f5,0x3b5,0x395); +test(0x3f7,0x3f8); +test(0x3f8,0x3f7); +test(0x3f9,0x3f2); +test(0x3fa,0x3fb); +test(0x3fb,0x3fa); +test(0x3fd,0x37b); +test(0x3fe,0x37c); +test(0x3ff,0x37d); +test(0x400,0x450); +test(0x401,0x451); +test(0x402,0x452); +test(0x403,0x453); +test(0x404,0x454); +test(0x405,0x455); +test(0x406,0x456); +test(0x407,0x457); +test(0x408,0x458); +test(0x409,0x459); +test(0x40a,0x45a); +test(0x40b,0x45b); +test(0x40c,0x45c); +test(0x40d,0x45d); +test(0x40e,0x45e); +test(0x40f,0x45f); +test(0x410,0x430); +test(0x411,0x431); +test(0x412,0x432,0x1c80); +test(0x413,0x433); +test(0x414,0x434,0x1c81); +test(0x415,0x435); +test(0x416,0x436); +test(0x417,0x437); +test(0x418,0x438); +test(0x419,0x439); +test(0x41a,0x43a); +test(0x41b,0x43b); +test(0x41c,0x43c); +test(0x41d,0x43d); +test(0x41e,0x43e,0x1c82); +test(0x41f,0x43f); +test(0x420,0x440); +test(0x421,0x441,0x1c83); +test(0x422,0x442,0x1c84,0x1c85); +test(0x423,0x443); +test(0x424,0x444); +test(0x425,0x445); +test(0x426,0x446); +test(0x427,0x447); +test(0x428,0x448); +test(0x429,0x449); +test(0x42a,0x44a,0x1c86); +test(0x42b,0x44b); +test(0x42c,0x44c); +test(0x42d,0x44d); +test(0x42e,0x44e); +test(0x42f,0x44f); +test(0x430,0x410); +test(0x431,0x411); +test(0x432,0x412,0x1c80); +test(0x433,0x413); +test(0x434,0x414,0x1c81); +test(0x435,0x415); +test(0x436,0x416); +test(0x437,0x417); +test(0x438,0x418); +test(0x439,0x419); +test(0x43a,0x41a); +test(0x43b,0x41b); +test(0x43c,0x41c); +test(0x43d,0x41d); +test(0x43e,0x41e,0x1c82); +test(0x43f,0x41f); +test(0x440,0x420); +test(0x441,0x421,0x1c83); +test(0x442,0x422,0x1c84,0x1c85); +test(0x443,0x423); +test(0x444,0x424); +test(0x445,0x425); +test(0x446,0x426); +test(0x447,0x427); +test(0x448,0x428); +test(0x449,0x429); +test(0x44a,0x42a,0x1c86); +test(0x44b,0x42b); +test(0x44c,0x42c); +test(0x44d,0x42d); +test(0x44e,0x42e); +test(0x44f,0x42f); +test(0x450,0x400); +test(0x451,0x401); +test(0x452,0x402); +test(0x453,0x403); +test(0x454,0x404); +test(0x455,0x405); +test(0x456,0x406); +test(0x457,0x407); +test(0x458,0x408); +test(0x459,0x409); +test(0x45a,0x40a); +test(0x45b,0x40b); +test(0x45c,0x40c); +test(0x45d,0x40d); +test(0x45e,0x40e); +test(0x45f,0x40f); +test(0x460,0x461); +test(0x461,0x460); +test(0x462,0x463,0x1c87); +test(0x463,0x462,0x1c87); +test(0x464,0x465); +test(0x465,0x464); +test(0x466,0x467); +test(0x467,0x466); +test(0x468,0x469); +test(0x469,0x468); +test(0x46a,0x46b); +test(0x46b,0x46a); +test(0x46c,0x46d); +test(0x46d,0x46c); +test(0x46e,0x46f); +test(0x46f,0x46e); +test(0x470,0x471); +test(0x471,0x470); +test(0x472,0x473); +test(0x473,0x472); +test(0x474,0x475); +test(0x475,0x474); +test(0x476,0x477); +test(0x477,0x476); +test(0x478,0x479); +test(0x479,0x478); +test(0x47a,0x47b); +test(0x47b,0x47a); +test(0x47c,0x47d); +test(0x47d,0x47c); +test(0x47e,0x47f); +test(0x47f,0x47e); +test(0x480,0x481); +test(0x481,0x480); +test(0x48a,0x48b); +test(0x48b,0x48a); +test(0x48c,0x48d); +test(0x48d,0x48c); +test(0x48e,0x48f); +test(0x48f,0x48e); +test(0x490,0x491); +test(0x491,0x490); +test(0x492,0x493); +test(0x493,0x492); +test(0x494,0x495); +test(0x495,0x494); +test(0x496,0x497); +test(0x497,0x496); +test(0x498,0x499); +test(0x499,0x498); +test(0x49a,0x49b); +test(0x49b,0x49a); +test(0x49c,0x49d); +test(0x49d,0x49c); +test(0x49e,0x49f); +test(0x49f,0x49e); +test(0x4a0,0x4a1); +test(0x4a1,0x4a0); +test(0x4a2,0x4a3); +test(0x4a3,0x4a2); +test(0x4a4,0x4a5); +test(0x4a5,0x4a4); +test(0x4a6,0x4a7); +test(0x4a7,0x4a6); +test(0x4a8,0x4a9); +test(0x4a9,0x4a8); +test(0x4aa,0x4ab); +test(0x4ab,0x4aa); +test(0x4ac,0x4ad); +test(0x4ad,0x4ac); +test(0x4ae,0x4af); +test(0x4af,0x4ae); +test(0x4b0,0x4b1); +test(0x4b1,0x4b0); +test(0x4b2,0x4b3); +test(0x4b3,0x4b2); +test(0x4b4,0x4b5); +test(0x4b5,0x4b4); +test(0x4b6,0x4b7); +test(0x4b7,0x4b6); +test(0x4b8,0x4b9); +test(0x4b9,0x4b8); +test(0x4ba,0x4bb); +test(0x4bb,0x4ba); +test(0x4bc,0x4bd); +test(0x4bd,0x4bc); +test(0x4be,0x4bf); +test(0x4bf,0x4be); +test(0x4c0,0x4cf); +test(0x4c1,0x4c2); +test(0x4c2,0x4c1); +test(0x4c3,0x4c4); +test(0x4c4,0x4c3); +test(0x4c5,0x4c6); +test(0x4c6,0x4c5); +test(0x4c7,0x4c8); +test(0x4c8,0x4c7); +test(0x4c9,0x4ca); +test(0x4ca,0x4c9); +test(0x4cb,0x4cc); +test(0x4cc,0x4cb); +test(0x4cd,0x4ce); +test(0x4ce,0x4cd); +test(0x4cf,0x4c0); +test(0x4d0,0x4d1); +test(0x4d1,0x4d0); +test(0x4d2,0x4d3); +test(0x4d3,0x4d2); +test(0x4d4,0x4d5); +test(0x4d5,0x4d4); +test(0x4d6,0x4d7); +test(0x4d7,0x4d6); +test(0x4d8,0x4d9); +test(0x4d9,0x4d8); +test(0x4da,0x4db); +test(0x4db,0x4da); +test(0x4dc,0x4dd); +test(0x4dd,0x4dc); +test(0x4de,0x4df); +test(0x4df,0x4de); +test(0x4e0,0x4e1); +test(0x4e1,0x4e0); +test(0x4e2,0x4e3); +test(0x4e3,0x4e2); +test(0x4e4,0x4e5); +test(0x4e5,0x4e4); +test(0x4e6,0x4e7); +test(0x4e7,0x4e6); +test(0x4e8,0x4e9); +test(0x4e9,0x4e8); +test(0x4ea,0x4eb); +test(0x4eb,0x4ea); +test(0x4ec,0x4ed); +test(0x4ed,0x4ec); +test(0x4ee,0x4ef); +test(0x4ef,0x4ee); +test(0x4f0,0x4f1); +test(0x4f1,0x4f0); +test(0x4f2,0x4f3); +test(0x4f3,0x4f2); +test(0x4f4,0x4f5); +test(0x4f5,0x4f4); +test(0x4f6,0x4f7); +test(0x4f7,0x4f6); +test(0x4f8,0x4f9); +test(0x4f9,0x4f8); +test(0x4fa,0x4fb); +test(0x4fb,0x4fa); +test(0x4fc,0x4fd); +test(0x4fd,0x4fc); +test(0x4fe,0x4ff); +test(0x4ff,0x4fe); +test(0x500,0x501); +test(0x501,0x500); +test(0x502,0x503); +test(0x503,0x502); +test(0x504,0x505); +test(0x505,0x504); +test(0x506,0x507); +test(0x507,0x506); +test(0x508,0x509); +test(0x509,0x508); +test(0x50a,0x50b); +test(0x50b,0x50a); +test(0x50c,0x50d); +test(0x50d,0x50c); +test(0x50e,0x50f); +test(0x50f,0x50e); +test(0x510,0x511); +test(0x511,0x510); +test(0x512,0x513); +test(0x513,0x512); +test(0x514,0x515); +test(0x515,0x514); +test(0x516,0x517); +test(0x517,0x516); +test(0x518,0x519); +test(0x519,0x518); +test(0x51a,0x51b); +test(0x51b,0x51a); +test(0x51c,0x51d); +test(0x51d,0x51c); +test(0x51e,0x51f); +test(0x51f,0x51e); +test(0x520,0x521); +test(0x521,0x520); +test(0x522,0x523); +test(0x523,0x522); +test(0x524,0x525); +test(0x525,0x524); +test(0x526,0x527); +test(0x527,0x526); +test(0x528,0x529); +test(0x529,0x528); +test(0x52a,0x52b); +test(0x52b,0x52a); +test(0x52c,0x52d); +test(0x52d,0x52c); +test(0x52e,0x52f); +test(0x52f,0x52e); +test(0x531,0x561); +test(0x532,0x562); +test(0x533,0x563); +test(0x534,0x564); +test(0x535,0x565); +test(0x536,0x566); +test(0x537,0x567); +test(0x538,0x568); +test(0x539,0x569); +test(0x53a,0x56a); +test(0x53b,0x56b); +test(0x53c,0x56c); +test(0x53d,0x56d); +test(0x53e,0x56e); +test(0x53f,0x56f); +test(0x540,0x570); +test(0x541,0x571); +test(0x542,0x572); +test(0x543,0x573); +test(0x544,0x574); +test(0x545,0x575); +test(0x546,0x576); +test(0x547,0x577); +test(0x548,0x578); +test(0x549,0x579); +test(0x54a,0x57a); +test(0x54b,0x57b); +test(0x54c,0x57c); +test(0x54d,0x57d); +test(0x54e,0x57e); +test(0x54f,0x57f); +test(0x550,0x580); +test(0x551,0x581); +test(0x552,0x582); +test(0x553,0x583); +test(0x554,0x584); +test(0x555,0x585); +test(0x556,0x586); +test(0x561,0x531); +test(0x562,0x532); +test(0x563,0x533); +test(0x564,0x534); +test(0x565,0x535); +test(0x566,0x536); +test(0x567,0x537); +test(0x568,0x538); +test(0x569,0x539); +test(0x56a,0x53a); +test(0x56b,0x53b); +test(0x56c,0x53c); +test(0x56d,0x53d); +test(0x56e,0x53e); +test(0x56f,0x53f); +test(0x570,0x540); +test(0x571,0x541); +test(0x572,0x542); +test(0x573,0x543); +test(0x574,0x544); +test(0x575,0x545); +test(0x576,0x546); +test(0x577,0x547); +test(0x578,0x548); +test(0x579,0x549); +test(0x57a,0x54a); +test(0x57b,0x54b); +test(0x57c,0x54c); +test(0x57d,0x54d); +test(0x57e,0x54e); +test(0x57f,0x54f); +test(0x580,0x550); +test(0x581,0x551); +test(0x582,0x552); +test(0x583,0x553); +test(0x584,0x554); +test(0x585,0x555); +test(0x586,0x556); +test(0x10a0,0x2d00); +test(0x10a1,0x2d01); +test(0x10a2,0x2d02); +test(0x10a3,0x2d03); +test(0x10a4,0x2d04); +test(0x10a5,0x2d05); +test(0x10a6,0x2d06); +test(0x10a7,0x2d07); +test(0x10a8,0x2d08); +test(0x10a9,0x2d09); +test(0x10aa,0x2d0a); +test(0x10ab,0x2d0b); +test(0x10ac,0x2d0c); +test(0x10ad,0x2d0d); +test(0x10ae,0x2d0e); +test(0x10af,0x2d0f); +test(0x10b0,0x2d10); +test(0x10b1,0x2d11); +test(0x10b2,0x2d12); +test(0x10b3,0x2d13); +test(0x10b4,0x2d14); +test(0x10b5,0x2d15); +test(0x10b6,0x2d16); +test(0x10b7,0x2d17); +test(0x10b8,0x2d18); +test(0x10b9,0x2d19); +test(0x10ba,0x2d1a); +test(0x10bb,0x2d1b); +test(0x10bc,0x2d1c); +test(0x10bd,0x2d1d); +test(0x10be,0x2d1e); +test(0x10bf,0x2d1f); +test(0x10c0,0x2d20); +test(0x10c1,0x2d21); +test(0x10c2,0x2d22); +test(0x10c3,0x2d23); +test(0x10c4,0x2d24); +test(0x10c5,0x2d25); +test(0x10c7,0x2d27); +test(0x10cd,0x2d2d); +test(0x13a0,0xab70); +test(0x13a1,0xab71); +test(0x13a2,0xab72); +test(0x13a3,0xab73); +test(0x13a4,0xab74); +test(0x13a5,0xab75); +test(0x13a6,0xab76); +test(0x13a7,0xab77); +test(0x13a8,0xab78); +test(0x13a9,0xab79); +test(0x13aa,0xab7a); +test(0x13ab,0xab7b); +test(0x13ac,0xab7c); +test(0x13ad,0xab7d); +test(0x13ae,0xab7e); +test(0x13af,0xab7f); +test(0x13b0,0xab80); +test(0x13b1,0xab81); +test(0x13b2,0xab82); +test(0x13b3,0xab83); +test(0x13b4,0xab84); +test(0x13b5,0xab85); +test(0x13b6,0xab86); +test(0x13b7,0xab87); +test(0x13b8,0xab88); +test(0x13b9,0xab89); +test(0x13ba,0xab8a); +test(0x13bb,0xab8b); +test(0x13bc,0xab8c); +test(0x13bd,0xab8d); +test(0x13be,0xab8e); +test(0x13bf,0xab8f); +test(0x13c0,0xab90); +test(0x13c1,0xab91); +test(0x13c2,0xab92); +test(0x13c3,0xab93); +test(0x13c4,0xab94); +test(0x13c5,0xab95); +test(0x13c6,0xab96); +test(0x13c7,0xab97); +test(0x13c8,0xab98); +test(0x13c9,0xab99); +test(0x13ca,0xab9a); +test(0x13cb,0xab9b); +test(0x13cc,0xab9c); +test(0x13cd,0xab9d); +test(0x13ce,0xab9e); +test(0x13cf,0xab9f); +test(0x13d0,0xaba0); +test(0x13d1,0xaba1); +test(0x13d2,0xaba2); +test(0x13d3,0xaba3); +test(0x13d4,0xaba4); +test(0x13d5,0xaba5); +test(0x13d6,0xaba6); +test(0x13d7,0xaba7); +test(0x13d8,0xaba8); +test(0x13d9,0xaba9); +test(0x13da,0xabaa); +test(0x13db,0xabab); +test(0x13dc,0xabac); +test(0x13dd,0xabad); +test(0x13de,0xabae); +test(0x13df,0xabaf); +test(0x13e0,0xabb0); +test(0x13e1,0xabb1); +test(0x13e2,0xabb2); +test(0x13e3,0xabb3); +test(0x13e4,0xabb4); +test(0x13e5,0xabb5); +test(0x13e6,0xabb6); +test(0x13e7,0xabb7); +test(0x13e8,0xabb8); +test(0x13e9,0xabb9); +test(0x13ea,0xabba); +test(0x13eb,0xabbb); +test(0x13ec,0xabbc); +test(0x13ed,0xabbd); +test(0x13ee,0xabbe); +test(0x13ef,0xabbf); +test(0x13f0,0x13f8); +test(0x13f1,0x13f9); +test(0x13f2,0x13fa); +test(0x13f3,0x13fb); +test(0x13f4,0x13fc); +test(0x13f5,0x13fd); +test(0x13f8,0x13f0); +test(0x13f9,0x13f1); +test(0x13fa,0x13f2); +test(0x13fb,0x13f3); +test(0x13fc,0x13f4); +test(0x13fd,0x13f5); +test(0x1c80,0x432,0x412); +test(0x1c81,0x434,0x414); +test(0x1c82,0x43e,0x41e); +test(0x1c83,0x441,0x421); +test(0x1c84,0x442,0x422,0x1c85); +test(0x1c85,0x442,0x422,0x1c84); +test(0x1c86,0x44a,0x42a); +test(0x1c87,0x463,0x462); +test(0x1c88,0xa64b,0xa64a); +test(0x1d79,0xa77d); +test(0x1d7d,0x2c63); +test(0x1e00,0x1e01); +test(0x1e01,0x1e00); +test(0x1e02,0x1e03); +test(0x1e03,0x1e02); +test(0x1e04,0x1e05); +test(0x1e05,0x1e04); +test(0x1e06,0x1e07); +test(0x1e07,0x1e06); +test(0x1e08,0x1e09); +test(0x1e09,0x1e08); +test(0x1e0a,0x1e0b); +test(0x1e0b,0x1e0a); +test(0x1e0c,0x1e0d); +test(0x1e0d,0x1e0c); +test(0x1e0e,0x1e0f); +test(0x1e0f,0x1e0e); +test(0x1e10,0x1e11); +test(0x1e11,0x1e10); +test(0x1e12,0x1e13); +test(0x1e13,0x1e12); +test(0x1e14,0x1e15); +test(0x1e15,0x1e14); +test(0x1e16,0x1e17); +test(0x1e17,0x1e16); +test(0x1e18,0x1e19); +test(0x1e19,0x1e18); +test(0x1e1a,0x1e1b); +test(0x1e1b,0x1e1a); +test(0x1e1c,0x1e1d); +test(0x1e1d,0x1e1c); +test(0x1e1e,0x1e1f); +test(0x1e1f,0x1e1e); +test(0x1e20,0x1e21); +test(0x1e21,0x1e20); +test(0x1e22,0x1e23); +test(0x1e23,0x1e22); +test(0x1e24,0x1e25); +test(0x1e25,0x1e24); +test(0x1e26,0x1e27); +test(0x1e27,0x1e26); +test(0x1e28,0x1e29); +test(0x1e29,0x1e28); +test(0x1e2a,0x1e2b); +test(0x1e2b,0x1e2a); +test(0x1e2c,0x1e2d); +test(0x1e2d,0x1e2c); +test(0x1e2e,0x1e2f); +test(0x1e2f,0x1e2e); +test(0x1e30,0x1e31); +test(0x1e31,0x1e30); +test(0x1e32,0x1e33); +test(0x1e33,0x1e32); +test(0x1e34,0x1e35); +test(0x1e35,0x1e34); +test(0x1e36,0x1e37); +test(0x1e37,0x1e36); +test(0x1e38,0x1e39); +test(0x1e39,0x1e38); +test(0x1e3a,0x1e3b); +test(0x1e3b,0x1e3a); +test(0x1e3c,0x1e3d); +test(0x1e3d,0x1e3c); +test(0x1e3e,0x1e3f); +test(0x1e3f,0x1e3e); +test(0x1e40,0x1e41); +test(0x1e41,0x1e40); +test(0x1e42,0x1e43); +test(0x1e43,0x1e42); +test(0x1e44,0x1e45); +test(0x1e45,0x1e44); +test(0x1e46,0x1e47); +test(0x1e47,0x1e46); +test(0x1e48,0x1e49); +test(0x1e49,0x1e48); +test(0x1e4a,0x1e4b); +test(0x1e4b,0x1e4a); +test(0x1e4c,0x1e4d); +test(0x1e4d,0x1e4c); +test(0x1e4e,0x1e4f); +test(0x1e4f,0x1e4e); +test(0x1e50,0x1e51); +test(0x1e51,0x1e50); +test(0x1e52,0x1e53); +test(0x1e53,0x1e52); +test(0x1e54,0x1e55); +test(0x1e55,0x1e54); +test(0x1e56,0x1e57); +test(0x1e57,0x1e56); +test(0x1e58,0x1e59); +test(0x1e59,0x1e58); +test(0x1e5a,0x1e5b); +test(0x1e5b,0x1e5a); +test(0x1e5c,0x1e5d); +test(0x1e5d,0x1e5c); +test(0x1e5e,0x1e5f); +test(0x1e5f,0x1e5e); +test(0x1e60,0x1e61,0x1e9b); +test(0x1e61,0x1e60,0x1e9b); +test(0x1e62,0x1e63); +test(0x1e63,0x1e62); +test(0x1e64,0x1e65); +test(0x1e65,0x1e64); +test(0x1e66,0x1e67); +test(0x1e67,0x1e66); +test(0x1e68,0x1e69); +test(0x1e69,0x1e68); +test(0x1e6a,0x1e6b); +test(0x1e6b,0x1e6a); +test(0x1e6c,0x1e6d); +test(0x1e6d,0x1e6c); +test(0x1e6e,0x1e6f); +test(0x1e6f,0x1e6e); +test(0x1e70,0x1e71); +test(0x1e71,0x1e70); +test(0x1e72,0x1e73); +test(0x1e73,0x1e72); +test(0x1e74,0x1e75); +test(0x1e75,0x1e74); +test(0x1e76,0x1e77); +test(0x1e77,0x1e76); +test(0x1e78,0x1e79); +test(0x1e79,0x1e78); +test(0x1e7a,0x1e7b); +test(0x1e7b,0x1e7a); +test(0x1e7c,0x1e7d); +test(0x1e7d,0x1e7c); +test(0x1e7e,0x1e7f); +test(0x1e7f,0x1e7e); +test(0x1e80,0x1e81); +test(0x1e81,0x1e80); +test(0x1e82,0x1e83); +test(0x1e83,0x1e82); +test(0x1e84,0x1e85); +test(0x1e85,0x1e84); +test(0x1e86,0x1e87); +test(0x1e87,0x1e86); +test(0x1e88,0x1e89); +test(0x1e89,0x1e88); +test(0x1e8a,0x1e8b); +test(0x1e8b,0x1e8a); +test(0x1e8c,0x1e8d); +test(0x1e8d,0x1e8c); +test(0x1e8e,0x1e8f); +test(0x1e8f,0x1e8e); +test(0x1e90,0x1e91); +test(0x1e91,0x1e90); +test(0x1e92,0x1e93); +test(0x1e93,0x1e92); +test(0x1e94,0x1e95); +test(0x1e95,0x1e94); +test(0x1e9b,0x1e61,0x1e60); +test(0x1e9e,0xdf); +test(0x1ea0,0x1ea1); +test(0x1ea1,0x1ea0); +test(0x1ea2,0x1ea3); +test(0x1ea3,0x1ea2); +test(0x1ea4,0x1ea5); +test(0x1ea5,0x1ea4); +test(0x1ea6,0x1ea7); +test(0x1ea7,0x1ea6); +test(0x1ea8,0x1ea9); +test(0x1ea9,0x1ea8); +test(0x1eaa,0x1eab); +test(0x1eab,0x1eaa); +test(0x1eac,0x1ead); +test(0x1ead,0x1eac); +test(0x1eae,0x1eaf); +test(0x1eaf,0x1eae); +test(0x1eb0,0x1eb1); +test(0x1eb1,0x1eb0); +test(0x1eb2,0x1eb3); +test(0x1eb3,0x1eb2); +test(0x1eb4,0x1eb5); +test(0x1eb5,0x1eb4); +test(0x1eb6,0x1eb7); +test(0x1eb7,0x1eb6); +test(0x1eb8,0x1eb9); +test(0x1eb9,0x1eb8); +test(0x1eba,0x1ebb); +test(0x1ebb,0x1eba); +test(0x1ebc,0x1ebd); +test(0x1ebd,0x1ebc); +test(0x1ebe,0x1ebf); +test(0x1ebf,0x1ebe); +test(0x1ec0,0x1ec1); +test(0x1ec1,0x1ec0); +test(0x1ec2,0x1ec3); +test(0x1ec3,0x1ec2); +test(0x1ec4,0x1ec5); +test(0x1ec5,0x1ec4); +test(0x1ec6,0x1ec7); +test(0x1ec7,0x1ec6); +test(0x1ec8,0x1ec9); +test(0x1ec9,0x1ec8); +test(0x1eca,0x1ecb); +test(0x1ecb,0x1eca); +test(0x1ecc,0x1ecd); +test(0x1ecd,0x1ecc); +test(0x1ece,0x1ecf); +test(0x1ecf,0x1ece); +test(0x1ed0,0x1ed1); +test(0x1ed1,0x1ed0); +test(0x1ed2,0x1ed3); +test(0x1ed3,0x1ed2); +test(0x1ed4,0x1ed5); +test(0x1ed5,0x1ed4); +test(0x1ed6,0x1ed7); +test(0x1ed7,0x1ed6); +test(0x1ed8,0x1ed9); +test(0x1ed9,0x1ed8); +test(0x1eda,0x1edb); +test(0x1edb,0x1eda); +test(0x1edc,0x1edd); +test(0x1edd,0x1edc); +test(0x1ede,0x1edf); +test(0x1edf,0x1ede); +test(0x1ee0,0x1ee1); +test(0x1ee1,0x1ee0); +test(0x1ee2,0x1ee3); +test(0x1ee3,0x1ee2); +test(0x1ee4,0x1ee5); +test(0x1ee5,0x1ee4); +test(0x1ee6,0x1ee7); +test(0x1ee7,0x1ee6); +test(0x1ee8,0x1ee9); +test(0x1ee9,0x1ee8); +test(0x1eea,0x1eeb); +test(0x1eeb,0x1eea); +test(0x1eec,0x1eed); +test(0x1eed,0x1eec); +test(0x1eee,0x1eef); +test(0x1eef,0x1eee); +test(0x1ef0,0x1ef1); +test(0x1ef1,0x1ef0); +test(0x1ef2,0x1ef3); +test(0x1ef3,0x1ef2); +test(0x1ef4,0x1ef5); +test(0x1ef5,0x1ef4); +test(0x1ef6,0x1ef7); +test(0x1ef7,0x1ef6); +test(0x1ef8,0x1ef9); +test(0x1ef9,0x1ef8); +test(0x1efa,0x1efb); +test(0x1efb,0x1efa); +test(0x1efc,0x1efd); +test(0x1efd,0x1efc); +test(0x1efe,0x1eff); +test(0x1eff,0x1efe); +test(0x1f00,0x1f08); +test(0x1f01,0x1f09); +test(0x1f02,0x1f0a); +test(0x1f03,0x1f0b); +test(0x1f04,0x1f0c); +test(0x1f05,0x1f0d); +test(0x1f06,0x1f0e); +test(0x1f07,0x1f0f); +test(0x1f08,0x1f00); +test(0x1f09,0x1f01); +test(0x1f0a,0x1f02); +test(0x1f0b,0x1f03); +test(0x1f0c,0x1f04); +test(0x1f0d,0x1f05); +test(0x1f0e,0x1f06); +test(0x1f0f,0x1f07); +test(0x1f10,0x1f18); +test(0x1f11,0x1f19); +test(0x1f12,0x1f1a); +test(0x1f13,0x1f1b); +test(0x1f14,0x1f1c); +test(0x1f15,0x1f1d); +test(0x1f18,0x1f10); +test(0x1f19,0x1f11); +test(0x1f1a,0x1f12); +test(0x1f1b,0x1f13); +test(0x1f1c,0x1f14); +test(0x1f1d,0x1f15); +test(0x1f20,0x1f28); +test(0x1f21,0x1f29); +test(0x1f22,0x1f2a); +test(0x1f23,0x1f2b); +test(0x1f24,0x1f2c); +test(0x1f25,0x1f2d); +test(0x1f26,0x1f2e); +test(0x1f27,0x1f2f); +test(0x1f28,0x1f20); +test(0x1f29,0x1f21); +test(0x1f2a,0x1f22); +test(0x1f2b,0x1f23); +test(0x1f2c,0x1f24); +test(0x1f2d,0x1f25); +test(0x1f2e,0x1f26); +test(0x1f2f,0x1f27); +test(0x1f30,0x1f38); +test(0x1f31,0x1f39); +test(0x1f32,0x1f3a); +test(0x1f33,0x1f3b); +test(0x1f34,0x1f3c); +test(0x1f35,0x1f3d); +test(0x1f36,0x1f3e); +test(0x1f37,0x1f3f); +test(0x1f38,0x1f30); +test(0x1f39,0x1f31); +test(0x1f3a,0x1f32); +test(0x1f3b,0x1f33); +test(0x1f3c,0x1f34); +test(0x1f3d,0x1f35); +test(0x1f3e,0x1f36); +test(0x1f3f,0x1f37); +test(0x1f40,0x1f48); +test(0x1f41,0x1f49); +test(0x1f42,0x1f4a); +test(0x1f43,0x1f4b); +test(0x1f44,0x1f4c); +test(0x1f45,0x1f4d); +test(0x1f48,0x1f40); +test(0x1f49,0x1f41); +test(0x1f4a,0x1f42); +test(0x1f4b,0x1f43); +test(0x1f4c,0x1f44); +test(0x1f4d,0x1f45); +test(0x1f51,0x1f59); +test(0x1f53,0x1f5b); +test(0x1f55,0x1f5d); +test(0x1f57,0x1f5f); +test(0x1f59,0x1f51); +test(0x1f5b,0x1f53); +test(0x1f5d,0x1f55); +test(0x1f5f,0x1f57); +test(0x1f60,0x1f68); +test(0x1f61,0x1f69); +test(0x1f62,0x1f6a); +test(0x1f63,0x1f6b); +test(0x1f64,0x1f6c); +test(0x1f65,0x1f6d); +test(0x1f66,0x1f6e); +test(0x1f67,0x1f6f); +test(0x1f68,0x1f60); +test(0x1f69,0x1f61); +test(0x1f6a,0x1f62); +test(0x1f6b,0x1f63); +test(0x1f6c,0x1f64); +test(0x1f6d,0x1f65); +test(0x1f6e,0x1f66); +test(0x1f6f,0x1f67); +test(0x1f70,0x1fba); +test(0x1f71,0x1fbb); +test(0x1f72,0x1fc8); +test(0x1f73,0x1fc9); +test(0x1f74,0x1fca); +test(0x1f75,0x1fcb); +test(0x1f76,0x1fda); +test(0x1f77,0x1fdb); +test(0x1f78,0x1ff8); +test(0x1f79,0x1ff9); +test(0x1f7a,0x1fea); +test(0x1f7b,0x1feb); +test(0x1f7c,0x1ffa); +test(0x1f7d,0x1ffb); +test(0x1f80,0x1f88); +test(0x1f81,0x1f89); +test(0x1f82,0x1f8a); +test(0x1f83,0x1f8b); +test(0x1f84,0x1f8c); +test(0x1f85,0x1f8d); +test(0x1f86,0x1f8e); +test(0x1f87,0x1f8f); +test(0x1f88,0x1f80); +test(0x1f89,0x1f81); +test(0x1f8a,0x1f82); +test(0x1f8b,0x1f83); +test(0x1f8c,0x1f84); +test(0x1f8d,0x1f85); +test(0x1f8e,0x1f86); +test(0x1f8f,0x1f87); +test(0x1f90,0x1f98); +test(0x1f91,0x1f99); +test(0x1f92,0x1f9a); +test(0x1f93,0x1f9b); +test(0x1f94,0x1f9c); +test(0x1f95,0x1f9d); +test(0x1f96,0x1f9e); +test(0x1f97,0x1f9f); +test(0x1f98,0x1f90); +test(0x1f99,0x1f91); +test(0x1f9a,0x1f92); +test(0x1f9b,0x1f93); +test(0x1f9c,0x1f94); +test(0x1f9d,0x1f95); +test(0x1f9e,0x1f96); +test(0x1f9f,0x1f97); +test(0x1fa0,0x1fa8); +test(0x1fa1,0x1fa9); +test(0x1fa2,0x1faa); +test(0x1fa3,0x1fab); +test(0x1fa4,0x1fac); +test(0x1fa5,0x1fad); +test(0x1fa6,0x1fae); +test(0x1fa7,0x1faf); +test(0x1fa8,0x1fa0); +test(0x1fa9,0x1fa1); +test(0x1faa,0x1fa2); +test(0x1fab,0x1fa3); +test(0x1fac,0x1fa4); +test(0x1fad,0x1fa5); +test(0x1fae,0x1fa6); +test(0x1faf,0x1fa7); +test(0x1fb0,0x1fb8); +test(0x1fb1,0x1fb9); +test(0x1fb3,0x1fbc); +test(0x1fb8,0x1fb0); +test(0x1fb9,0x1fb1); +test(0x1fba,0x1f70); +test(0x1fbb,0x1f71); +test(0x1fbc,0x1fb3); +test(0x1fbe,0x3b9,0x345,0x399); +test(0x1fc3,0x1fcc); +test(0x1fc8,0x1f72); +test(0x1fc9,0x1f73); +test(0x1fca,0x1f74); +test(0x1fcb,0x1f75); +test(0x1fcc,0x1fc3); +test(0x1fd0,0x1fd8); +test(0x1fd1,0x1fd9); +test(0x1fd8,0x1fd0); +test(0x1fd9,0x1fd1); +test(0x1fda,0x1f76); +test(0x1fdb,0x1f77); +test(0x1fe0,0x1fe8); +test(0x1fe1,0x1fe9); +test(0x1fe5,0x1fec); +test(0x1fe8,0x1fe0); +test(0x1fe9,0x1fe1); +test(0x1fea,0x1f7a); +test(0x1feb,0x1f7b); +test(0x1fec,0x1fe5); +test(0x1ff3,0x1ffc); +test(0x1ff8,0x1f78); +test(0x1ff9,0x1f79); +test(0x1ffa,0x1f7c); +test(0x1ffb,0x1f7d); +test(0x1ffc,0x1ff3); +test(0x2126,0x3c9,0x3a9); +test(0x212a,0x6b,0x4b); +test(0x212b,0xe5,0xc5); +test(0x2132,0x214e); +test(0x214e,0x2132); +test(0x2160,0x2170); +test(0x2161,0x2171); +test(0x2162,0x2172); +test(0x2163,0x2173); +test(0x2164,0x2174); +test(0x2165,0x2175); +test(0x2166,0x2176); +test(0x2167,0x2177); +test(0x2168,0x2178); +test(0x2169,0x2179); +test(0x216a,0x217a); +test(0x216b,0x217b); +test(0x216c,0x217c); +test(0x216d,0x217d); +test(0x216e,0x217e); +test(0x216f,0x217f); +test(0x2170,0x2160); +test(0x2171,0x2161); +test(0x2172,0x2162); +test(0x2173,0x2163); +test(0x2174,0x2164); +test(0x2175,0x2165); +test(0x2176,0x2166); +test(0x2177,0x2167); +test(0x2178,0x2168); +test(0x2179,0x2169); +test(0x217a,0x216a); +test(0x217b,0x216b); +test(0x217c,0x216c); +test(0x217d,0x216d); +test(0x217e,0x216e); +test(0x217f,0x216f); +test(0x2183,0x2184); +test(0x2184,0x2183); +test(0x24b6,0x24d0); +test(0x24b7,0x24d1); +test(0x24b8,0x24d2); +test(0x24b9,0x24d3); +test(0x24ba,0x24d4); +test(0x24bb,0x24d5); +test(0x24bc,0x24d6); +test(0x24bd,0x24d7); +test(0x24be,0x24d8); +test(0x24bf,0x24d9); +test(0x24c0,0x24da); +test(0x24c1,0x24db); +test(0x24c2,0x24dc); +test(0x24c3,0x24dd); +test(0x24c4,0x24de); +test(0x24c5,0x24df); +test(0x24c6,0x24e0); +test(0x24c7,0x24e1); +test(0x24c8,0x24e2); +test(0x24c9,0x24e3); +test(0x24ca,0x24e4); +test(0x24cb,0x24e5); +test(0x24cc,0x24e6); +test(0x24cd,0x24e7); +test(0x24ce,0x24e8); +test(0x24cf,0x24e9); +test(0x24d0,0x24b6); +test(0x24d1,0x24b7); +test(0x24d2,0x24b8); +test(0x24d3,0x24b9); +test(0x24d4,0x24ba); +test(0x24d5,0x24bb); +test(0x24d6,0x24bc); +test(0x24d7,0x24bd); +test(0x24d8,0x24be); +test(0x24d9,0x24bf); +test(0x24da,0x24c0); +test(0x24db,0x24c1); +test(0x24dc,0x24c2); +test(0x24dd,0x24c3); +test(0x24de,0x24c4); +test(0x24df,0x24c5); +test(0x24e0,0x24c6); +test(0x24e1,0x24c7); +test(0x24e2,0x24c8); +test(0x24e3,0x24c9); +test(0x24e4,0x24ca); +test(0x24e5,0x24cb); +test(0x24e6,0x24cc); +test(0x24e7,0x24cd); +test(0x24e8,0x24ce); +test(0x24e9,0x24cf); +test(0x2c00,0x2c30); +test(0x2c01,0x2c31); +test(0x2c02,0x2c32); +test(0x2c03,0x2c33); +test(0x2c04,0x2c34); +test(0x2c05,0x2c35); +test(0x2c06,0x2c36); +test(0x2c07,0x2c37); +test(0x2c08,0x2c38); +test(0x2c09,0x2c39); +test(0x2c0a,0x2c3a); +test(0x2c0b,0x2c3b); +test(0x2c0c,0x2c3c); +test(0x2c0d,0x2c3d); +test(0x2c0e,0x2c3e); +test(0x2c0f,0x2c3f); +test(0x2c10,0x2c40); +test(0x2c11,0x2c41); +test(0x2c12,0x2c42); +test(0x2c13,0x2c43); +test(0x2c14,0x2c44); +test(0x2c15,0x2c45); +test(0x2c16,0x2c46); +test(0x2c17,0x2c47); +test(0x2c18,0x2c48); +test(0x2c19,0x2c49); +test(0x2c1a,0x2c4a); +test(0x2c1b,0x2c4b); +test(0x2c1c,0x2c4c); +test(0x2c1d,0x2c4d); +test(0x2c1e,0x2c4e); +test(0x2c1f,0x2c4f); +test(0x2c20,0x2c50); +test(0x2c21,0x2c51); +test(0x2c22,0x2c52); +test(0x2c23,0x2c53); +test(0x2c24,0x2c54); +test(0x2c25,0x2c55); +test(0x2c26,0x2c56); +test(0x2c27,0x2c57); +test(0x2c28,0x2c58); +test(0x2c29,0x2c59); +test(0x2c2a,0x2c5a); +test(0x2c2b,0x2c5b); +test(0x2c2c,0x2c5c); +test(0x2c2d,0x2c5d); +test(0x2c2e,0x2c5e); +test(0x2c30,0x2c00); +test(0x2c31,0x2c01); +test(0x2c32,0x2c02); +test(0x2c33,0x2c03); +test(0x2c34,0x2c04); +test(0x2c35,0x2c05); +test(0x2c36,0x2c06); +test(0x2c37,0x2c07); +test(0x2c38,0x2c08); +test(0x2c39,0x2c09); +test(0x2c3a,0x2c0a); +test(0x2c3b,0x2c0b); +test(0x2c3c,0x2c0c); +test(0x2c3d,0x2c0d); +test(0x2c3e,0x2c0e); +test(0x2c3f,0x2c0f); +test(0x2c40,0x2c10); +test(0x2c41,0x2c11); +test(0x2c42,0x2c12); +test(0x2c43,0x2c13); +test(0x2c44,0x2c14); +test(0x2c45,0x2c15); +test(0x2c46,0x2c16); +test(0x2c47,0x2c17); +test(0x2c48,0x2c18); +test(0x2c49,0x2c19); +test(0x2c4a,0x2c1a); +test(0x2c4b,0x2c1b); +test(0x2c4c,0x2c1c); +test(0x2c4d,0x2c1d); +test(0x2c4e,0x2c1e); +test(0x2c4f,0x2c1f); +test(0x2c50,0x2c20); +test(0x2c51,0x2c21); +test(0x2c52,0x2c22); +test(0x2c53,0x2c23); +test(0x2c54,0x2c24); +test(0x2c55,0x2c25); +test(0x2c56,0x2c26); +test(0x2c57,0x2c27); +test(0x2c58,0x2c28); +test(0x2c59,0x2c29); +test(0x2c5a,0x2c2a); +test(0x2c5b,0x2c2b); +test(0x2c5c,0x2c2c); +test(0x2c5d,0x2c2d); +test(0x2c5e,0x2c2e); +test(0x2c60,0x2c61); +test(0x2c61,0x2c60); +test(0x2c62,0x26b); +test(0x2c63,0x1d7d); +test(0x2c64,0x27d); +test(0x2c65,0x23a); +test(0x2c66,0x23e); +test(0x2c67,0x2c68); +test(0x2c68,0x2c67); +test(0x2c69,0x2c6a); +test(0x2c6a,0x2c69); +test(0x2c6b,0x2c6c); +test(0x2c6c,0x2c6b); +test(0x2c6d,0x251); +test(0x2c6e,0x271); +test(0x2c6f,0x250); +test(0x2c70,0x252); +test(0x2c72,0x2c73); +test(0x2c73,0x2c72); +test(0x2c75,0x2c76); +test(0x2c76,0x2c75); +test(0x2c7e,0x23f); +test(0x2c7f,0x240); +test(0x2c80,0x2c81); +test(0x2c81,0x2c80); +test(0x2c82,0x2c83); +test(0x2c83,0x2c82); +test(0x2c84,0x2c85); +test(0x2c85,0x2c84); +test(0x2c86,0x2c87); +test(0x2c87,0x2c86); +test(0x2c88,0x2c89); +test(0x2c89,0x2c88); +test(0x2c8a,0x2c8b); +test(0x2c8b,0x2c8a); +test(0x2c8c,0x2c8d); +test(0x2c8d,0x2c8c); +test(0x2c8e,0x2c8f); +test(0x2c8f,0x2c8e); +test(0x2c90,0x2c91); +test(0x2c91,0x2c90); +test(0x2c92,0x2c93); +test(0x2c93,0x2c92); +test(0x2c94,0x2c95); +test(0x2c95,0x2c94); +test(0x2c96,0x2c97); +test(0x2c97,0x2c96); +test(0x2c98,0x2c99); +test(0x2c99,0x2c98); +test(0x2c9a,0x2c9b); +test(0x2c9b,0x2c9a); +test(0x2c9c,0x2c9d); +test(0x2c9d,0x2c9c); +test(0x2c9e,0x2c9f); +test(0x2c9f,0x2c9e); +test(0x2ca0,0x2ca1); +test(0x2ca1,0x2ca0); +test(0x2ca2,0x2ca3); +test(0x2ca3,0x2ca2); +test(0x2ca4,0x2ca5); +test(0x2ca5,0x2ca4); +test(0x2ca6,0x2ca7); +test(0x2ca7,0x2ca6); +test(0x2ca8,0x2ca9); +test(0x2ca9,0x2ca8); +test(0x2caa,0x2cab); +test(0x2cab,0x2caa); +test(0x2cac,0x2cad); +test(0x2cad,0x2cac); +test(0x2cae,0x2caf); +test(0x2caf,0x2cae); +test(0x2cb0,0x2cb1); +test(0x2cb1,0x2cb0); +test(0x2cb2,0x2cb3); +test(0x2cb3,0x2cb2); +test(0x2cb4,0x2cb5); +test(0x2cb5,0x2cb4); +test(0x2cb6,0x2cb7); +test(0x2cb7,0x2cb6); +test(0x2cb8,0x2cb9); +test(0x2cb9,0x2cb8); +test(0x2cba,0x2cbb); +test(0x2cbb,0x2cba); +test(0x2cbc,0x2cbd); +test(0x2cbd,0x2cbc); +test(0x2cbe,0x2cbf); +test(0x2cbf,0x2cbe); +test(0x2cc0,0x2cc1); +test(0x2cc1,0x2cc0); +test(0x2cc2,0x2cc3); +test(0x2cc3,0x2cc2); +test(0x2cc4,0x2cc5); +test(0x2cc5,0x2cc4); +test(0x2cc6,0x2cc7); +test(0x2cc7,0x2cc6); +test(0x2cc8,0x2cc9); +test(0x2cc9,0x2cc8); +test(0x2cca,0x2ccb); +test(0x2ccb,0x2cca); +test(0x2ccc,0x2ccd); +test(0x2ccd,0x2ccc); +test(0x2cce,0x2ccf); +test(0x2ccf,0x2cce); +test(0x2cd0,0x2cd1); +test(0x2cd1,0x2cd0); +test(0x2cd2,0x2cd3); +test(0x2cd3,0x2cd2); +test(0x2cd4,0x2cd5); +test(0x2cd5,0x2cd4); +test(0x2cd6,0x2cd7); +test(0x2cd7,0x2cd6); +test(0x2cd8,0x2cd9); +test(0x2cd9,0x2cd8); +test(0x2cda,0x2cdb); +test(0x2cdb,0x2cda); +test(0x2cdc,0x2cdd); +test(0x2cdd,0x2cdc); +test(0x2cde,0x2cdf); +test(0x2cdf,0x2cde); +test(0x2ce0,0x2ce1); +test(0x2ce1,0x2ce0); +test(0x2ce2,0x2ce3); +test(0x2ce3,0x2ce2); +test(0x2ceb,0x2cec); +test(0x2cec,0x2ceb); +test(0x2ced,0x2cee); +test(0x2cee,0x2ced); +test(0x2cf2,0x2cf3); +test(0x2cf3,0x2cf2); +test(0x2d00,0x10a0); +test(0x2d01,0x10a1); +test(0x2d02,0x10a2); +test(0x2d03,0x10a3); +test(0x2d04,0x10a4); +test(0x2d05,0x10a5); +test(0x2d06,0x10a6); +test(0x2d07,0x10a7); +test(0x2d08,0x10a8); +test(0x2d09,0x10a9); +test(0x2d0a,0x10aa); +test(0x2d0b,0x10ab); +test(0x2d0c,0x10ac); +test(0x2d0d,0x10ad); +test(0x2d0e,0x10ae); +test(0x2d0f,0x10af); +test(0x2d10,0x10b0); +test(0x2d11,0x10b1); +test(0x2d12,0x10b2); +test(0x2d13,0x10b3); +test(0x2d14,0x10b4); +test(0x2d15,0x10b5); +test(0x2d16,0x10b6); +test(0x2d17,0x10b7); +test(0x2d18,0x10b8); +test(0x2d19,0x10b9); +test(0x2d1a,0x10ba); +test(0x2d1b,0x10bb); +test(0x2d1c,0x10bc); +test(0x2d1d,0x10bd); +test(0x2d1e,0x10be); +test(0x2d1f,0x10bf); +test(0x2d20,0x10c0); +test(0x2d21,0x10c1); +test(0x2d22,0x10c2); +test(0x2d23,0x10c3); +test(0x2d24,0x10c4); +test(0x2d25,0x10c5); +test(0x2d27,0x10c7); +test(0x2d2d,0x10cd); +test(0xa640,0xa641); +test(0xa641,0xa640); +test(0xa642,0xa643); +test(0xa643,0xa642); +test(0xa644,0xa645); +test(0xa645,0xa644); +test(0xa646,0xa647); +test(0xa647,0xa646); +test(0xa648,0xa649); +test(0xa649,0xa648); +test(0xa64a,0xa64b,0x1c88); +test(0xa64b,0x1c88,0xa64a); +test(0xa64c,0xa64d); +test(0xa64d,0xa64c); +test(0xa64e,0xa64f); +test(0xa64f,0xa64e); +test(0xa650,0xa651); +test(0xa651,0xa650); +test(0xa652,0xa653); +test(0xa653,0xa652); +test(0xa654,0xa655); +test(0xa655,0xa654); +test(0xa656,0xa657); +test(0xa657,0xa656); +test(0xa658,0xa659); +test(0xa659,0xa658); +test(0xa65a,0xa65b); +test(0xa65b,0xa65a); +test(0xa65c,0xa65d); +test(0xa65d,0xa65c); +test(0xa65e,0xa65f); +test(0xa65f,0xa65e); +test(0xa660,0xa661); +test(0xa661,0xa660); +test(0xa662,0xa663); +test(0xa663,0xa662); +test(0xa664,0xa665); +test(0xa665,0xa664); +test(0xa666,0xa667); +test(0xa667,0xa666); +test(0xa668,0xa669); +test(0xa669,0xa668); +test(0xa66a,0xa66b); +test(0xa66b,0xa66a); +test(0xa66c,0xa66d); +test(0xa66d,0xa66c); +test(0xa680,0xa681); +test(0xa681,0xa680); +test(0xa682,0xa683); +test(0xa683,0xa682); +test(0xa684,0xa685); +test(0xa685,0xa684); +test(0xa686,0xa687); +test(0xa687,0xa686); +test(0xa688,0xa689); +test(0xa689,0xa688); +test(0xa68a,0xa68b); +test(0xa68b,0xa68a); +test(0xa68c,0xa68d); +test(0xa68d,0xa68c); +test(0xa68e,0xa68f); +test(0xa68f,0xa68e); +test(0xa690,0xa691); +test(0xa691,0xa690); +test(0xa692,0xa693); +test(0xa693,0xa692); +test(0xa694,0xa695); +test(0xa695,0xa694); +test(0xa696,0xa697); +test(0xa697,0xa696); +test(0xa698,0xa699); +test(0xa699,0xa698); +test(0xa69a,0xa69b); +test(0xa69b,0xa69a); +test(0xa722,0xa723); +test(0xa723,0xa722); +test(0xa724,0xa725); +test(0xa725,0xa724); +test(0xa726,0xa727); +test(0xa727,0xa726); +test(0xa728,0xa729); +test(0xa729,0xa728); +test(0xa72a,0xa72b); +test(0xa72b,0xa72a); +test(0xa72c,0xa72d); +test(0xa72d,0xa72c); +test(0xa72e,0xa72f); +test(0xa72f,0xa72e); +test(0xa732,0xa733); +test(0xa733,0xa732); +test(0xa734,0xa735); +test(0xa735,0xa734); +test(0xa736,0xa737); +test(0xa737,0xa736); +test(0xa738,0xa739); +test(0xa739,0xa738); +test(0xa73a,0xa73b); +test(0xa73b,0xa73a); +test(0xa73c,0xa73d); +test(0xa73d,0xa73c); +test(0xa73e,0xa73f); +test(0xa73f,0xa73e); +test(0xa740,0xa741); +test(0xa741,0xa740); +test(0xa742,0xa743); +test(0xa743,0xa742); +test(0xa744,0xa745); +test(0xa745,0xa744); +test(0xa746,0xa747); +test(0xa747,0xa746); +test(0xa748,0xa749); +test(0xa749,0xa748); +test(0xa74a,0xa74b); +test(0xa74b,0xa74a); +test(0xa74c,0xa74d); +test(0xa74d,0xa74c); +test(0xa74e,0xa74f); +test(0xa74f,0xa74e); +test(0xa750,0xa751); +test(0xa751,0xa750); +test(0xa752,0xa753); +test(0xa753,0xa752); +test(0xa754,0xa755); +test(0xa755,0xa754); +test(0xa756,0xa757); +test(0xa757,0xa756); +test(0xa758,0xa759); +test(0xa759,0xa758); +test(0xa75a,0xa75b); +test(0xa75b,0xa75a); +test(0xa75c,0xa75d); +test(0xa75d,0xa75c); +test(0xa75e,0xa75f); +test(0xa75f,0xa75e); +test(0xa760,0xa761); +test(0xa761,0xa760); +test(0xa762,0xa763); +test(0xa763,0xa762); +test(0xa764,0xa765); +test(0xa765,0xa764); +test(0xa766,0xa767); +test(0xa767,0xa766); +test(0xa768,0xa769); +test(0xa769,0xa768); +test(0xa76a,0xa76b); +test(0xa76b,0xa76a); +test(0xa76c,0xa76d); +test(0xa76d,0xa76c); +test(0xa76e,0xa76f); +test(0xa76f,0xa76e); +test(0xa779,0xa77a); +test(0xa77a,0xa779); +test(0xa77b,0xa77c); +test(0xa77c,0xa77b); +test(0xa77d,0x1d79); +test(0xa77e,0xa77f); +test(0xa77f,0xa77e); +test(0xa780,0xa781); +test(0xa781,0xa780); +test(0xa782,0xa783); +test(0xa783,0xa782); +test(0xa784,0xa785); +test(0xa785,0xa784); +test(0xa786,0xa787); +test(0xa787,0xa786); +test(0xa78b,0xa78c); +test(0xa78c,0xa78b); +test(0xa78d,0x265); +test(0xa790,0xa791); +test(0xa791,0xa790); +test(0xa792,0xa793); +test(0xa793,0xa792); +test(0xa796,0xa797); +test(0xa797,0xa796); +test(0xa798,0xa799); +test(0xa799,0xa798); +test(0xa79a,0xa79b); +test(0xa79b,0xa79a); +test(0xa79c,0xa79d); +test(0xa79d,0xa79c); +test(0xa79e,0xa79f); +test(0xa79f,0xa79e); +test(0xa7a0,0xa7a1); +test(0xa7a1,0xa7a0); +test(0xa7a2,0xa7a3); +test(0xa7a3,0xa7a2); +test(0xa7a4,0xa7a5); +test(0xa7a5,0xa7a4); +test(0xa7a6,0xa7a7); +test(0xa7a7,0xa7a6); +test(0xa7a8,0xa7a9); +test(0xa7a9,0xa7a8); +test(0xa7aa,0x266); +test(0xa7ab,0x25c); +test(0xa7ac,0x261); +test(0xa7ad,0x26c); +test(0xa7ae,0x26a); +test(0xa7b0,0x29e); +test(0xa7b1,0x287); +test(0xa7b2,0x29d); +test(0xa7b3,0xab53); +test(0xa7b4,0xa7b5); +test(0xa7b5,0xa7b4); +test(0xa7b6,0xa7b7); +test(0xa7b7,0xa7b6); +test(0xab53,0xa7b3); +test(0xab70,0x13a0); +test(0xab71,0x13a1); +test(0xab72,0x13a2); +test(0xab73,0x13a3); +test(0xab74,0x13a4); +test(0xab75,0x13a5); +test(0xab76,0x13a6); +test(0xab77,0x13a7); +test(0xab78,0x13a8); +test(0xab79,0x13a9); +test(0xab7a,0x13aa); +test(0xab7b,0x13ab); +test(0xab7c,0x13ac); +test(0xab7d,0x13ad); +test(0xab7e,0x13ae); +test(0xab7f,0x13af); +test(0xab80,0x13b0); +test(0xab81,0x13b1); +test(0xab82,0x13b2); +test(0xab83,0x13b3); +test(0xab84,0x13b4); +test(0xab85,0x13b5); +test(0xab86,0x13b6); +test(0xab87,0x13b7); +test(0xab88,0x13b8); +test(0xab89,0x13b9); +test(0xab8a,0x13ba); +test(0xab8b,0x13bb); +test(0xab8c,0x13bc); +test(0xab8d,0x13bd); +test(0xab8e,0x13be); +test(0xab8f,0x13bf); +test(0xab90,0x13c0); +test(0xab91,0x13c1); +test(0xab92,0x13c2); +test(0xab93,0x13c3); +test(0xab94,0x13c4); +test(0xab95,0x13c5); +test(0xab96,0x13c6); +test(0xab97,0x13c7); +test(0xab98,0x13c8); +test(0xab99,0x13c9); +test(0xab9a,0x13ca); +test(0xab9b,0x13cb); +test(0xab9c,0x13cc); +test(0xab9d,0x13cd); +test(0xab9e,0x13ce); +test(0xab9f,0x13cf); +test(0xaba0,0x13d0); +test(0xaba1,0x13d1); +test(0xaba2,0x13d2); +test(0xaba3,0x13d3); +test(0xaba4,0x13d4); +test(0xaba5,0x13d5); +test(0xaba6,0x13d6); +test(0xaba7,0x13d7); +test(0xaba8,0x13d8); +test(0xaba9,0x13d9); +test(0xabaa,0x13da); +test(0xabab,0x13db); +test(0xabac,0x13dc); +test(0xabad,0x13dd); +test(0xabae,0x13de); +test(0xabaf,0x13df); +test(0xabb0,0x13e0); +test(0xabb1,0x13e1); +test(0xabb2,0x13e2); +test(0xabb3,0x13e3); +test(0xabb4,0x13e4); +test(0xabb5,0x13e5); +test(0xabb6,0x13e6); +test(0xabb7,0x13e7); +test(0xabb8,0x13e8); +test(0xabb9,0x13e9); +test(0xabba,0x13ea); +test(0xabbb,0x13eb); +test(0xabbc,0x13ec); +test(0xabbd,0x13ed); +test(0xabbe,0x13ee); +test(0xabbf,0x13ef); +test(0xff21,0xff41); +test(0xff22,0xff42); +test(0xff23,0xff43); +test(0xff24,0xff44); +test(0xff25,0xff45); +test(0xff26,0xff46); +test(0xff27,0xff47); +test(0xff28,0xff48); +test(0xff29,0xff49); +test(0xff2a,0xff4a); +test(0xff2b,0xff4b); +test(0xff2c,0xff4c); +test(0xff2d,0xff4d); +test(0xff2e,0xff4e); +test(0xff2f,0xff4f); +test(0xff30,0xff50); +test(0xff31,0xff51); +test(0xff32,0xff52); +test(0xff33,0xff53); +test(0xff34,0xff54); +test(0xff35,0xff55); +test(0xff36,0xff56); +test(0xff37,0xff57); +test(0xff38,0xff58); +test(0xff39,0xff59); +test(0xff3a,0xff5a); +test(0xff41,0xff21); +test(0xff42,0xff22); +test(0xff43,0xff23); +test(0xff44,0xff24); +test(0xff45,0xff25); +test(0xff46,0xff26); +test(0xff47,0xff27); +test(0xff48,0xff28); +test(0xff49,0xff29); +test(0xff4a,0xff2a); +test(0xff4b,0xff2b); +test(0xff4c,0xff2c); +test(0xff4d,0xff2d); +test(0xff4e,0xff2e); +test(0xff4f,0xff2f); +test(0xff50,0xff30); +test(0xff51,0xff31); +test(0xff52,0xff32); +test(0xff53,0xff33); +test(0xff54,0xff34); +test(0xff55,0xff35); +test(0xff56,0xff36); +test(0xff57,0xff37); +test(0xff58,0xff38); +test(0xff59,0xff39); +test(0xff5a,0xff3a); +test(0x10400,0x10428); +test(0x10401,0x10429); +test(0x10402,0x1042a); +test(0x10403,0x1042b); +test(0x10404,0x1042c); +test(0x10405,0x1042d); +test(0x10406,0x1042e); +test(0x10407,0x1042f); +test(0x10408,0x10430); +test(0x10409,0x10431); +test(0x1040a,0x10432); +test(0x1040b,0x10433); +test(0x1040c,0x10434); +test(0x1040d,0x10435); +test(0x1040e,0x10436); +test(0x1040f,0x10437); +test(0x10410,0x10438); +test(0x10411,0x10439); +test(0x10412,0x1043a); +test(0x10413,0x1043b); +test(0x10414,0x1043c); +test(0x10415,0x1043d); +test(0x10416,0x1043e); +test(0x10417,0x1043f); +test(0x10418,0x10440); +test(0x10419,0x10441); +test(0x1041a,0x10442); +test(0x1041b,0x10443); +test(0x1041c,0x10444); +test(0x1041d,0x10445); +test(0x1041e,0x10446); +test(0x1041f,0x10447); +test(0x10420,0x10448); +test(0x10421,0x10449); +test(0x10422,0x1044a); +test(0x10423,0x1044b); +test(0x10424,0x1044c); +test(0x10425,0x1044d); +test(0x10426,0x1044e); +test(0x10427,0x1044f); +test(0x10428,0x10400); +test(0x10429,0x10401); +test(0x1042a,0x10402); +test(0x1042b,0x10403); +test(0x1042c,0x10404); +test(0x1042d,0x10405); +test(0x1042e,0x10406); +test(0x1042f,0x10407); +test(0x10430,0x10408); +test(0x10431,0x10409); +test(0x10432,0x1040a); +test(0x10433,0x1040b); +test(0x10434,0x1040c); +test(0x10435,0x1040d); +test(0x10436,0x1040e); +test(0x10437,0x1040f); +test(0x10438,0x10410); +test(0x10439,0x10411); +test(0x1043a,0x10412); +test(0x1043b,0x10413); +test(0x1043c,0x10414); +test(0x1043d,0x10415); +test(0x1043e,0x10416); +test(0x1043f,0x10417); +test(0x10440,0x10418); +test(0x10441,0x10419); +test(0x10442,0x1041a); +test(0x10443,0x1041b); +test(0x10444,0x1041c); +test(0x10445,0x1041d); +test(0x10446,0x1041e); +test(0x10447,0x1041f); +test(0x10448,0x10420); +test(0x10449,0x10421); +test(0x1044a,0x10422); +test(0x1044b,0x10423); +test(0x1044c,0x10424); +test(0x1044d,0x10425); +test(0x1044e,0x10426); +test(0x1044f,0x10427); +test(0x104b0,0x104d8); +test(0x104b1,0x104d9); +test(0x104b2,0x104da); +test(0x104b3,0x104db); +test(0x104b4,0x104dc); +test(0x104b5,0x104dd); +test(0x104b6,0x104de); +test(0x104b7,0x104df); +test(0x104b8,0x104e0); +test(0x104b9,0x104e1); +test(0x104ba,0x104e2); +test(0x104bb,0x104e3); +test(0x104bc,0x104e4); +test(0x104bd,0x104e5); +test(0x104be,0x104e6); +test(0x104bf,0x104e7); +test(0x104c0,0x104e8); +test(0x104c1,0x104e9); +test(0x104c2,0x104ea); +test(0x104c3,0x104eb); +test(0x104c4,0x104ec); +test(0x104c5,0x104ed); +test(0x104c6,0x104ee); +test(0x104c7,0x104ef); +test(0x104c8,0x104f0); +test(0x104c9,0x104f1); +test(0x104ca,0x104f2); +test(0x104cb,0x104f3); +test(0x104cc,0x104f4); +test(0x104cd,0x104f5); +test(0x104ce,0x104f6); +test(0x104cf,0x104f7); +test(0x104d0,0x104f8); +test(0x104d1,0x104f9); +test(0x104d2,0x104fa); +test(0x104d3,0x104fb); +test(0x104d8,0x104b0); +test(0x104d9,0x104b1); +test(0x104da,0x104b2); +test(0x104db,0x104b3); +test(0x104dc,0x104b4); +test(0x104dd,0x104b5); +test(0x104de,0x104b6); +test(0x104df,0x104b7); +test(0x104e0,0x104b8); +test(0x104e1,0x104b9); +test(0x104e2,0x104ba); +test(0x104e3,0x104bb); +test(0x104e4,0x104bc); +test(0x104e5,0x104bd); +test(0x104e6,0x104be); +test(0x104e7,0x104bf); +test(0x104e8,0x104c0); +test(0x104e9,0x104c1); +test(0x104ea,0x104c2); +test(0x104eb,0x104c3); +test(0x104ec,0x104c4); +test(0x104ed,0x104c5); +test(0x104ee,0x104c6); +test(0x104ef,0x104c7); +test(0x104f0,0x104c8); +test(0x104f1,0x104c9); +test(0x104f2,0x104ca); +test(0x104f3,0x104cb); +test(0x104f4,0x104cc); +test(0x104f5,0x104cd); +test(0x104f6,0x104ce); +test(0x104f7,0x104cf); +test(0x104f8,0x104d0); +test(0x104f9,0x104d1); +test(0x104fa,0x104d2); +test(0x104fb,0x104d3); +test(0x10c80,0x10cc0); +test(0x10c81,0x10cc1); +test(0x10c82,0x10cc2); +test(0x10c83,0x10cc3); +test(0x10c84,0x10cc4); +test(0x10c85,0x10cc5); +test(0x10c86,0x10cc6); +test(0x10c87,0x10cc7); +test(0x10c88,0x10cc8); +test(0x10c89,0x10cc9); +test(0x10c8a,0x10cca); +test(0x10c8b,0x10ccb); +test(0x10c8c,0x10ccc); +test(0x10c8d,0x10ccd); +test(0x10c8e,0x10cce); +test(0x10c8f,0x10ccf); +test(0x10c90,0x10cd0); +test(0x10c91,0x10cd1); +test(0x10c92,0x10cd2); +test(0x10c93,0x10cd3); +test(0x10c94,0x10cd4); +test(0x10c95,0x10cd5); +test(0x10c96,0x10cd6); +test(0x10c97,0x10cd7); +test(0x10c98,0x10cd8); +test(0x10c99,0x10cd9); +test(0x10c9a,0x10cda); +test(0x10c9b,0x10cdb); +test(0x10c9c,0x10cdc); +test(0x10c9d,0x10cdd); +test(0x10c9e,0x10cde); +test(0x10c9f,0x10cdf); +test(0x10ca0,0x10ce0); +test(0x10ca1,0x10ce1); +test(0x10ca2,0x10ce2); +test(0x10ca3,0x10ce3); +test(0x10ca4,0x10ce4); +test(0x10ca5,0x10ce5); +test(0x10ca6,0x10ce6); +test(0x10ca7,0x10ce7); +test(0x10ca8,0x10ce8); +test(0x10ca9,0x10ce9); +test(0x10caa,0x10cea); +test(0x10cab,0x10ceb); +test(0x10cac,0x10cec); +test(0x10cad,0x10ced); +test(0x10cae,0x10cee); +test(0x10caf,0x10cef); +test(0x10cb0,0x10cf0); +test(0x10cb1,0x10cf1); +test(0x10cb2,0x10cf2); +test(0x10cc0,0x10c80); +test(0x10cc1,0x10c81); +test(0x10cc2,0x10c82); +test(0x10cc3,0x10c83); +test(0x10cc4,0x10c84); +test(0x10cc5,0x10c85); +test(0x10cc6,0x10c86); +test(0x10cc7,0x10c87); +test(0x10cc8,0x10c88); +test(0x10cc9,0x10c89); +test(0x10cca,0x10c8a); +test(0x10ccb,0x10c8b); +test(0x10ccc,0x10c8c); +test(0x10ccd,0x10c8d); +test(0x10cce,0x10c8e); +test(0x10ccf,0x10c8f); +test(0x10cd0,0x10c90); +test(0x10cd1,0x10c91); +test(0x10cd2,0x10c92); +test(0x10cd3,0x10c93); +test(0x10cd4,0x10c94); +test(0x10cd5,0x10c95); +test(0x10cd6,0x10c96); +test(0x10cd7,0x10c97); +test(0x10cd8,0x10c98); +test(0x10cd9,0x10c99); +test(0x10cda,0x10c9a); +test(0x10cdb,0x10c9b); +test(0x10cdc,0x10c9c); +test(0x10cdd,0x10c9d); +test(0x10cde,0x10c9e); +test(0x10cdf,0x10c9f); +test(0x10ce0,0x10ca0); +test(0x10ce1,0x10ca1); +test(0x10ce2,0x10ca2); +test(0x10ce3,0x10ca3); +test(0x10ce4,0x10ca4); +test(0x10ce5,0x10ca5); +test(0x10ce6,0x10ca6); +test(0x10ce7,0x10ca7); +test(0x10ce8,0x10ca8); +test(0x10ce9,0x10ca9); +test(0x10cea,0x10caa); +test(0x10ceb,0x10cab); +test(0x10cec,0x10cac); +test(0x10ced,0x10cad); +test(0x10cee,0x10cae); +test(0x10cef,0x10caf); +test(0x10cf0,0x10cb0); +test(0x10cf1,0x10cb1); +test(0x10cf2,0x10cb2); +test(0x118a0,0x118c0); +test(0x118a1,0x118c1); +test(0x118a2,0x118c2); +test(0x118a3,0x118c3); +test(0x118a4,0x118c4); +test(0x118a5,0x118c5); +test(0x118a6,0x118c6); +test(0x118a7,0x118c7); +test(0x118a8,0x118c8); +test(0x118a9,0x118c9); +test(0x118aa,0x118ca); +test(0x118ab,0x118cb); +test(0x118ac,0x118cc); +test(0x118ad,0x118cd); +test(0x118ae,0x118ce); +test(0x118af,0x118cf); +test(0x118b0,0x118d0); +test(0x118b1,0x118d1); +test(0x118b2,0x118d2); +test(0x118b3,0x118d3); +test(0x118b4,0x118d4); +test(0x118b5,0x118d5); +test(0x118b6,0x118d6); +test(0x118b7,0x118d7); +test(0x118b8,0x118d8); +test(0x118b9,0x118d9); +test(0x118ba,0x118da); +test(0x118bb,0x118db); +test(0x118bc,0x118dc); +test(0x118bd,0x118dd); +test(0x118be,0x118de); +test(0x118bf,0x118df); +test(0x118c0,0x118a0); +test(0x118c1,0x118a1); +test(0x118c2,0x118a2); +test(0x118c3,0x118a3); +test(0x118c4,0x118a4); +test(0x118c5,0x118a5); +test(0x118c6,0x118a6); +test(0x118c7,0x118a7); +test(0x118c8,0x118a8); +test(0x118c9,0x118a9); +test(0x118ca,0x118aa); +test(0x118cb,0x118ab); +test(0x118cc,0x118ac); +test(0x118cd,0x118ad); +test(0x118ce,0x118ae); +test(0x118cf,0x118af); +test(0x118d0,0x118b0); +test(0x118d1,0x118b1); +test(0x118d2,0x118b2); +test(0x118d3,0x118b3); +test(0x118d4,0x118b4); +test(0x118d5,0x118b5); +test(0x118d6,0x118b6); +test(0x118d7,0x118b7); +test(0x118d8,0x118b8); +test(0x118d9,0x118b9); +test(0x118da,0x118ba); +test(0x118db,0x118bb); +test(0x118dc,0x118bc); +test(0x118dd,0x118bd); +test(0x118de,0x118be); +test(0x118df,0x118bf); +test(0x1e900,0x1e922); +test(0x1e901,0x1e923); +test(0x1e902,0x1e924); +test(0x1e903,0x1e925); +test(0x1e904,0x1e926); +test(0x1e905,0x1e927); +test(0x1e906,0x1e928); +test(0x1e907,0x1e929); +test(0x1e908,0x1e92a); +test(0x1e909,0x1e92b); +test(0x1e90a,0x1e92c); +test(0x1e90b,0x1e92d); +test(0x1e90c,0x1e92e); +test(0x1e90d,0x1e92f); +test(0x1e90e,0x1e930); +test(0x1e90f,0x1e931); +test(0x1e910,0x1e932); +test(0x1e911,0x1e933); +test(0x1e912,0x1e934); +test(0x1e913,0x1e935); +test(0x1e914,0x1e936); +test(0x1e915,0x1e937); +test(0x1e916,0x1e938); +test(0x1e917,0x1e939); +test(0x1e918,0x1e93a); +test(0x1e919,0x1e93b); +test(0x1e91a,0x1e93c); +test(0x1e91b,0x1e93d); +test(0x1e91c,0x1e93e); +test(0x1e91d,0x1e93f); +test(0x1e91e,0x1e940); +test(0x1e91f,0x1e941); +test(0x1e920,0x1e942); +test(0x1e921,0x1e943); +test(0x1e922,0x1e900); +test(0x1e923,0x1e901); +test(0x1e924,0x1e902); +test(0x1e925,0x1e903); +test(0x1e926,0x1e904); +test(0x1e927,0x1e905); +test(0x1e928,0x1e906); +test(0x1e929,0x1e907); +test(0x1e92a,0x1e908); +test(0x1e92b,0x1e909); +test(0x1e92c,0x1e90a); +test(0x1e92d,0x1e90b); +test(0x1e92e,0x1e90c); +test(0x1e92f,0x1e90d); +test(0x1e930,0x1e90e); +test(0x1e931,0x1e90f); +test(0x1e932,0x1e910); +test(0x1e933,0x1e911); +test(0x1e934,0x1e912); +test(0x1e935,0x1e913); +test(0x1e936,0x1e914); +test(0x1e937,0x1e915); +test(0x1e938,0x1e916); +test(0x1e939,0x1e917); +test(0x1e93a,0x1e918); +test(0x1e93b,0x1e919); +test(0x1e93c,0x1e91a); +test(0x1e93d,0x1e91b); +test(0x1e93e,0x1e91c); +test(0x1e93f,0x1e91d); +test(0x1e940,0x1e91e); +test(0x1e941,0x1e91f); +test(0x1e942,0x1e920); +test(0x1e943,0x1e921); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-index.js b/js/src/tests/ecma_6/RegExp/unicode-index.js new file mode 100644 index 000000000..a4b2eb203 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-index.js @@ -0,0 +1,17 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- Pattern match should start from lead surrogate when lastIndex points corresponding trail surrogate."; + +print(BUGNUMBER + ": " + summary); + +var r = /\uD83D\uDC38/ug; +r.lastIndex = 1; +var str = "\uD83D\uDC38"; +var result = r.exec(str); +assertEq(result.length, 1); +assertEq(result[0], "\uD83D\uDC38"); + +// This does not match to ES6 spec, but the spec will be changed. +assertEq(result.index, 0); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-lead-trail.js b/js/src/tests/ecma_6/RegExp/unicode-lead-trail.js new file mode 100644 index 000000000..7ecdb9ace --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-lead-trail.js @@ -0,0 +1,218 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- lead and trail patterns in RegExpUnicodeEscapeSequence."; + +print(BUGNUMBER + ": " + summary); + +// ==== standalone ==== + +assertEqArray(/\uD83D\uDC38/u.exec("\u{1F438}"), + ["\u{1F438}"]); + +// no unicode flag +assertEqArray(/\uD83D\uDC38/.exec("\u{1F438}"), + ["\u{1F438}"]); + +// RegExp constructor +assertEqArray(new RegExp("\\uD83D\\uDC38", "u").exec("\u{1F438}"), + ["\u{1F438}"]); + +// RegExp constructor, no unicode flag +assertEqArray(new RegExp("\\uD83D\\uDC38", "").exec("\u{1F438}"), + ["\u{1F438}"]); + +// ==== ? ==== + +assertEqArray(/\uD83D\uDC38?/u.exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(/\uD83D\uDC38?/u.exec(""), + [""]); + +// lead-only target +assertEqArray(/\uD83D\uDC38?/u.exec("\uD83D"), + [""]); + +// no unicode flag +assertEqArray(/\uD83D\uDC38?/.exec("\u{1F438}"), + ["\u{1F438}"]); +assertEq(/\uD83D\uDC38?/.exec(""), + null); + +assertEqArray(/\uD83D\uDC38?/.exec("\uD83D"), + ["\uD83D"]); + +// RegExp constructor +assertEqArray(new RegExp("\\uD83D\\uDC38?", "u").exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(new RegExp("\\uD83D\\uDC38?", "u").exec(""), + [""]); + +assertEqArray(new RegExp("\\uD83D\\uDC38?", "u").exec("\uD83D"), + [""]); + +// RegExp constructor, no unicode flag +assertEqArray(new RegExp("\\uD83D\\uDC38?", "").exec("\u{1F438}"), + ["\u{1F438}"]); +assertEq(new RegExp("\\uD83D\\uDC38?", "").exec(""), + null); + +assertEqArray(new RegExp("\\uD83D\\uDC38?", "").exec("\uD83D"), + ["\uD83D"]); + +// ==== + ==== + +assertEqArray(/\uD83D\uDC38+/u.exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(/\uD83D\uDC38+/u.exec("\u{1F438}\u{1F438}"), + ["\u{1F438}\u{1F438}"]); +assertEq(/\uD83D\uDC38+/u.exec(""), + null); + +// lead-only target +assertEq(/\uD83D\uDC38+/u.exec("\uD83D"), + null); +assertEqArray(/\uD83D\uDC38+/u.exec("\uD83D\uDC38\uDC38"), + ["\uD83D\uDC38"]); + +// no unicode flag +assertEqArray(/\uD83D\uDC38+/.exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(/\uD83D\uDC38+/.exec("\u{1F438}\u{1F438}"), + ["\u{1F438}"]); +assertEq(/\uD83D\uDC38+/.exec("\uD83D"), + null); +assertEqArray(/\uD83D\uDC38+/.exec("\uD83D\uDC38\uDC38"), + ["\uD83D\uDC38\uDC38"]); +assertEq(/\uD83D\uDC38+/.exec(""), + null); + +// ==== * ==== + +assertEqArray(/\uD83D\uDC38*/u.exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(/\uD83D\uDC38*/u.exec("\u{1F438}\u{1F438}"), + ["\u{1F438}\u{1F438}"]); +assertEqArray(/\uD83D\uDC38*/u.exec(""), + [""]); + +// lead-only target +assertEqArray(/\uD83D\uDC38*/u.exec("\uD83D"), + [""]); +assertEqArray(/\uD83D\uDC38*/u.exec("\uD83D\uDC38\uDC38"), + ["\uD83D\uDC38"]); + +// no unicode flag +assertEqArray(/\uD83D\uDC38*/.exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(/\uD83D\uDC38*/.exec("\u{1F438}\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(/\uD83D\uDC38*/.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/\uD83D\uDC38*/.exec("\uD83D\uDC38\uDC38"), + ["\uD83D\uDC38\uDC38"]); +assertEq(/\uD83D\uDC38*/.exec(""), + null); + +// ==== lead-only ==== + +// match only non-surrogate pair +assertEqArray(/\uD83D/u.exec("\uD83D\uDBFF"), + ["\uD83D"]); +assertEq(/\uD83D/u.exec("\uD83D\uDC00"), + null); +assertEq(/\uD83D/u.exec("\uD83D\uDFFF"), + null); +assertEqArray(/\uD83D/u.exec("\uD83D\uE000"), + ["\uD83D"]); + +// match before non-tail char +assertEqArray(/\uD83D/u.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/\uD83D/u.exec("\uD83DA"), + ["\uD83D"]); + +// no unicode flag +assertEqArray(/\uD83D/.exec("\uD83D\uDBFF"), + ["\uD83D"]); +assertEqArray(/\uD83D/.exec("\uD83D\uDC00"), + ["\uD83D"]); +assertEqArray(/\uD83D/.exec("\uD83D\uDFFF"), + ["\uD83D"]); +assertEqArray(/\uD83D/.exec("\uD83D\uE000"), + ["\uD83D"]); +assertEqArray(/\uD83D/.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/\uD83D/.exec("\uD83DA"), + ["\uD83D"]); + +// ==== trail-only ==== + +// match only non-surrogate pair +assertEqArray(/\uDC38/u.exec("\uD7FF\uDC38"), + ["\uDC38"]); +assertEq(/\uDC38/u.exec("\uD800\uDC38"), + null); +assertEq(/\uDC38/u.exec("\uDBFF\uDC38"), + null); +assertEqArray(/\uDC38/u.exec("\uDC00\uDC38"), + ["\uDC38"]); + +// match after non-lead char +assertEqArray(/\uDC38/u.exec("\uDC38"), + ["\uDC38"]); +assertEqArray(/\uDC38/u.exec("A\uDC38"), + ["\uDC38"]); + +// no unicode flag +assertEqArray(/\uDC38/.exec("\uD7FF\uDC38"), + ["\uDC38"]); +assertEqArray(/\uDC38/.exec("\uD800\uDC38"), + ["\uDC38"]); +assertEqArray(/\uDC38/.exec("\uDBFF\uDC38"), + ["\uDC38"]); +assertEqArray(/\uDC38/.exec("\uDC00\uDC38"), + ["\uDC38"]); +assertEqArray(/\uDC38/.exec("\uDC38"), + ["\uDC38"]); +assertEqArray(/\uDC38/.exec("A\uDC38"), + ["\uDC38"]); + +// ==== invalid trail ==== + +assertEqArray(/\uD83D\u3042*/u.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/\uD83D\u3042*/u.exec("\uD83D\u3042"), + ["\uD83D\u3042"]); +assertEqArray(/\uD83D\u3042*/u.exec("\uD83D\u3042\u3042"), + ["\uD83D\u3042\u3042"]); + +assertEqArray(/\uD83D\u{3042}*/u.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/\uD83D\u{3042}*/u.exec("\uD83D\u3042"), + ["\uD83D\u3042"]); +assertEqArray(/\uD83D\u{3042}*/u.exec("\uD83D\u3042\u3042"), + ["\uD83D\u3042\u3042"]); + +assertEqArray(/\uD83DA*/u.exec("\uD83D"), + ["\uD83D"]); +assertEqArray(/\uD83DA*/u.exec("\uD83DA"), + ["\uD83DA"]); +assertEqArray(/\uD83DA*/u.exec("\uD83DAA"), + ["\uD83DAA"]); + +// ==== wrong patterns ==== + +assertThrowsInstanceOf(() => eval(`/\\u/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u0/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u00/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u000/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u000G/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\u0.00/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\uD83D\\u/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\uD83D\\u0/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\uD83D\\u00/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\uD83D\\u000/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\uD83D\\u000G/u`), SyntaxError); +assertThrowsInstanceOf(() => eval(`/\\uD83D\\u0.00/u`), SyntaxError); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_6/RegExp/unicode-raw.js b/js/src/tests/ecma_6/RegExp/unicode-raw.js new file mode 100644 index 000000000..37b572cd8 --- /dev/null +++ b/js/src/tests/ecma_6/RegExp/unicode-raw.js @@ -0,0 +1,139 @@ +var BUGNUMBER = 1135377; +var summary = "Implement RegExp unicode flag -- raw unicode."; + +print(BUGNUMBER + ": " + summary); + +// ==== standalone ==== + +assertEqArray(eval(`/\uD83D\uDC38/u`).exec("\u{1F438}"), + ["\u{1F438}"]); + +// no unicode flag +assertEqArray(eval(`/\uD83D\uDC38/`).exec("\u{1F438}"), + ["\u{1F438}"]); + +// escaped (lead) +assertEq(eval(`/\\uD83D\uDC38/u`).exec("\u{1F438}"), + null); +assertEq(eval(`/\\u{D83D}\uDC38/u`).exec("\u{1F438}"), + null); + +// escaped (trail) +assertEq(eval(`/\uD83D\\uDC38/u`).exec("\u{1F438}"), + null); +assertEq(eval(`/\uD83D\\u{DC38}/u`).exec("\u{1F438}"), + null); + +// escaped (lead), no unicode flag +assertEqArray(eval(`/\\uD83D\uDC38/`).exec("\u{1F438}"), + ["\u{1F438}"]); + +// escaped (trail), no unicode flag +assertEqArray(eval(`/\uD83D\\uDC38/`).exec("\u{1F438}"), + ["\u{1F438}"]); + +// ==== RegExp constructor ==== + +assertEqArray(new RegExp("\uD83D\uDC38", "u").exec("\u{1F438}"), + ["\u{1F438}"]); + +// no unicode flag +assertEqArray(new RegExp("\uD83D\uDC38", "").exec("\u{1F438}"), + ["\u{1F438}"]); + +// escaped(lead) +assertEq(new RegExp("\\uD83D\uDC38", "u").exec("\u{1F438}"), + null); +assertEq(new RegExp("\\u{D83D}\uDC38", "u").exec("\u{1F438}"), + null); + +// escaped(trail) +assertEq(new RegExp("\uD83D\\uDC38", "u").exec("\u{1F438}"), + null); +assertEq(new RegExp("\uD83D\\u{DC38}", "u").exec("\u{1F438}"), + null); + +// escaped(lead), no unicode flag +assertEqArray(new RegExp("\\uD83D\uDC38", "").exec("\u{1F438}"), + ["\u{1F438}"]); + +// escaped(trail), no unicode flag +assertEqArray(new RegExp("\uD83D\\uDC38", "").exec("\u{1F438}"), + ["\u{1F438}"]); + +// ==== ? ==== + +assertEqArray(eval(`/\uD83D\uDC38?/u`).exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(eval(`/\uD83D\uDC38?/u`).exec(""), + [""]); + +assertEqArray(eval(`/\uD83D\uDC38?/u`).exec("\uD83D"), + [""]); + +// no unicode flag +assertEqArray(eval(`/\uD83D\uDC38?/`).exec("\u{1F438}"), + ["\u{1F438}"]); +assertEq(eval(`/\uD83D\uDC38?/`).exec(""), + null); + +assertEqArray(eval(`/\uD83D\uDC38?/`).exec("\uD83D"), + ["\uD83D"]); + +// escaped (lead) +assertEq(eval(`/\\uD83D\uDC38?/u`).exec("\u{1F438}"), + null); +assertEq(eval(`/\\uD83D\uDC38?/u`).exec(""), + null); + +assertEqArray(eval(`/\\uD83D\uDC38?/u`).exec("\uD83D"), + ["\uD83D"]); + +// escaped (trail) +assertEq(eval(`/\uD83D\\uDC38?/u`).exec("\u{1F438}"), + null); +assertEq(eval(`/\uD83D\\uDC38?/u`).exec(""), + null); + +assertEqArray(eval(`/\uD83D\\uDC38?/u`).exec("\uD83D"), + ["\uD83D"]); + +// escaped (lead), no unicode flag +assertEqArray(eval(`/\\uD83D\uDC38?/`).exec("\u{1F438}"), + ["\u{1F438}"]); +assertEq(eval(`/\\uD83D\uDC38?/`).exec(""), + null); + +assertEqArray(eval(`/\\uD83D\uDC38?/`).exec("\uD83D"), + ["\uD83D"]); + +// escaped (trail), no unicode flag +assertEqArray(eval(`/\uD83D\\uDC38?/`).exec("\u{1F438}"), + ["\u{1F438}"]); +assertEq(eval(`/\uD83D\\uDC38?/`).exec(""), + null); + +assertEqArray(eval(`/\uD83D\\uDC38?/`).exec("\uD83D"), + ["\uD83D"]); + +// ==== RegExp constructor, ? ==== + +assertEqArray(new RegExp("\uD83D\uDC38?", "u").exec("\u{1F438}"), + ["\u{1F438}"]); +assertEqArray(new RegExp("\uD83D\uDC38?", "u").exec(""), + [""]); + +assertEqArray(new RegExp("\uD83D\uDC38?", "u").exec("\uD83D"), + [""]); + +// no unicode flag +assertEqArray(new RegExp("\uD83D\uDC38?", "").exec("\u{1F438}"), + ["\u{1F438}"]); +assertEq(new RegExp("\uD83D\uDC38?", "").exec(""), + null); + +assertEqArray(new RegExp("\uD83D\uDC38?", "").exec("\uD83D"), + ["\uD83D"]); + +if (typeof reportCompare === "function") + reportCompare(true, true); -- cgit v1.2.3