diff options
Diffstat (limited to '')
178 files changed, 20289 insertions, 0 deletions
diff --git a/js/src/tests/non262/RegExp/15.10.5-01.js b/js/src/tests/non262/RegExp/15.10.5-01.js new file mode 100644 index 0000000000..2f8429218a --- /dev/null +++ b/js/src/tests/non262/RegExp/15.10.5-01.js @@ -0,0 +1,21 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var BUGNUMBER = 614603; +var summary = "RegExp.length"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +assertEq(RegExp.length, 2); +assertEq(/a/.constructor.length, 2); + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/RegExp/15.10.6.2-2.js b/js/src/tests/non262/RegExp/15.10.6.2-2.js new file mode 100644 index 0000000000..3dfb6ac74f --- /dev/null +++ b/js/src/tests/non262/RegExp/15.10.6.2-2.js @@ -0,0 +1,292 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 18 Feb 2002 + * SUMMARY: Testing re.exec(str) when re.lastIndex is < 0 or > str.length + * + * Case 1: If re has the global flag set, then re(str) should be null + * Case 2: If re doesn't have this set, then re(str) should be unaffected + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=76717 + * + * + * From the ECMA-262 Final spec: + * + * 15.10.6.2 RegExp.prototype.exec(string) + * Performs a regular expression match of string against the regular + * expression and returns an Array object containing the results of + * the match, or null if the string did not match. + * + * The string ToString(string) is searched for an occurrence of the + * regular expression pattern as follows: + * + * 1. Let S be the value of ToString(string). + * 2. Let length be the length of S. + * 3. Let lastIndex be the value of the lastIndex property. + * 4. Let i be the value of ToInteger(lastIndex). + * 5. If the global property is false, let i = 0. + * 6. If i < 0 or i > length then set lastIndex to 0 and return null. + * 7. Call [[Match]], giving it the arguments S and i. + * If [[Match]] returned failure, go to step 8; + * otherwise let r be its State result and go to step 10. + * 8. Let i = i+1. + * 9. Go to step 6. + * 10. Let e be r's endIndex value. + * 11. If the global property is true, set lastIndex to e. + * + * etc. + * + * + * So: + * + * A. If the global flag is not set, |lastIndex| is set to 0 + * before the match is attempted; thus the match is unaffected. + * + * B. If the global flag IS set and re.lastIndex is >= 0 and <= str.length, + * |lastIndex| is incremented every time there is a match; not from + * i to i+1, but from i to "endIndex" e: + * + * e = (index of last input character matched so far by the pattern) + 1 + * + * The match is then attempted from this position in the string (Step 7). + * + * C. When the global flag IS set and re.lastIndex is < 0 or > str.length, + * |lastIndex| is set to 0 and the match returns null. + * + * + * Note the |lastIndex| property is writeable, and may be set arbitrarily + * by the programmer - and we will do that below. + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 76717; +var summary = 'Testing re.exec(str) when re.lastIndex is < 0 or > str.length'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +/****************************************************************************** + * + * Case 1 : when the global flag is set - + * + *****************************************************************************/ +pattern = /abc/gi; +string = 'AbcaBcabC'; + +status = inSection(1); +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc'); +addThis(); + +status = inSection(2); +actualmatch = pattern.exec(string); +expectedmatch = Array('aBc'); +addThis(); + +status = inSection(3); +actualmatch = pattern.exec(string); +expectedmatch = Array('abC'); +addThis(); + +/* + * At this point |lastIndex| is > string.length, so the match should be null - + */ +status = inSection(4); +actualmatch = pattern.exec(string); +expectedmatch = null; +addThis(); + +/* + * Now try some edge-case values. Thanks to the work done in + * http://bugzilla.mozilla.org/show_bug.cgi?id=124339, |lastIndex| + * is now stored as a double instead of a uint32_t (unsigned integer). + * + * Note 2^32 -1 is the upper bound for uint32's, but doubles can go + * all the way up to Number.MAX_VALUE. So that's why we need cases + * between those two numbers. + */ +status = inSection(6); +pattern.lastIndex = Math.pow(2,32); +actualmatch = pattern.exec(string); +expectedmatch = null; +addThis(); + +status = inSection(8); +pattern.lastIndex = Math.pow(2,32) + 1; +actualmatch = pattern.exec(string); +expectedmatch = null; +addThis(); + +status = inSection(10); +pattern.lastIndex = Math.pow(2,32) * 2; +actualmatch = pattern.exec(string); +expectedmatch = null; +addThis(); + +status = inSection(12); +pattern.lastIndex = Math.pow(2,40); +actualmatch = pattern.exec(string); +expectedmatch = null; +addThis(); + +status = inSection(14); +pattern.lastIndex = Number.MAX_VALUE; +actualmatch = pattern.exec(string); +expectedmatch = null; +addThis(); + + + +/****************************************************************************** + * + * Case 2: repeat all the above cases WITHOUT the global flag set. + * According to EMCA. |lastIndex| should get set to 0 before the match. + * + * Therefore re.exec(str) should be unaffected; thus our expected values + * below are now DIFFERENT when |lastIndex| is < 0 or > str.length + * + *****************************************************************************/ + +pattern = /abc/i; +string = 'AbcaBcabC'; + +status = inSection(16); +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc'); +addThis(); + +status = inSection(17); +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc'); // NOT Array('aBc') as before - +addThis(); + +status = inSection(18); +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc'); // NOT Array('abC') as before - +addThis(); + +/* + * At this point above, |lastIndex| WAS > string.length, but not here - + */ +status = inSection(19); +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc') // NOT null as before - + addThis(); + +/* + * Now let's set |lastIndex| to -1 + */ +status = inSection(20); +pattern.lastIndex = -1; +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc') // NOT null as before - + addThis(); + +/* + * Now try some edge-case values. Thanks to the work done in + * http://bugzilla.mozilla.org/show_bug.cgi?id=124339, |lastIndex| + * is now stored as a double instead of a uint32_t (unsigned integer). + * + * Note 2^32 -1 is the upper bound for uint32's, but doubles can go + * all the way up to Number.MAX_VALUE. So that's why we need cases + * between those two numbers. + */ +status = inSection(21); +pattern.lastIndex = Math.pow(2,32); +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc') // NOT null as before - + addThis(); + +status = inSection(22); +pattern.lastIndex = -Math.pow(2,32); +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc') // NOT null as before - + addThis(); + +status = inSection(23); +pattern.lastIndex = Math.pow(2,32) + 1; +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc') // NOT null as before - + addThis(); + +status = inSection(24); +pattern.lastIndex = -(Math.pow(2,32) + 1); +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc') // NOT null as before - + addThis(); + +status = inSection(25); +pattern.lastIndex = Math.pow(2,32) * 2; +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc') // NOT null as before - + addThis(); + +status = inSection(26); +pattern.lastIndex = -Math.pow(2,32) * 2; +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc') // NOT null as before - + addThis(); + +status = inSection(27); +pattern.lastIndex = Math.pow(2,40); +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc') // NOT null as before -; + addThis(); + +status = inSection(28); +pattern.lastIndex = -Math.pow(2,40); +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc') // NOT null as before - + addThis(); + +status = inSection(29); +pattern.lastIndex = Number.MAX_VALUE; +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc') // NOT null as before - + addThis(); + +status = inSection(30); +pattern.lastIndex = -Number.MAX_VALUE; +actualmatch = pattern.exec(string); +expectedmatch = Array('Abc') // NOT null as before - + addThis(); + + + + +//------------------------------------------------------------------------------------------------- +test(); +//------------------------------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/15.10.7.5-01.js b/js/src/tests/non262/RegExp/15.10.7.5-01.js new file mode 100644 index 0000000000..ab9d071a7e --- /dev/null +++ b/js/src/tests/non262/RegExp/15.10.7.5-01.js @@ -0,0 +1,71 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var BUGNUMBER = 465199; +var summary = "RegExp lastIndex property set should not coerce type to number"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var called = false; +var o = { valueOf: function() { called = true; return 1; } }; +var r = /a/g; +var desc, m; + +assertEq(r.lastIndex, 0); + +desc = Object.getOwnPropertyDescriptor(r, "lastIndex"); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, false); +assertEq(desc.value, 0); +assertEq(desc.writable, true); + +r.lastIndex = o; + +assertEq(r.lastIndex, o); + +desc = Object.getOwnPropertyDescriptor(r, "lastIndex"); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, false); +assertEq(desc.value, o); +assertEq(desc.writable, true); + +assertEq(called, false); +assertEq(r.exec("aaaa").length, 1); +assertEq(called, true); +assertEq(r.lastIndex, 2); + +desc = Object.getOwnPropertyDescriptor(r, "lastIndex"); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, false); +assertEq(desc.value, 2); +assertEq(desc.writable, true); + + +r.lastIndex = -0.2; +assertEq(r.lastIndex, -0.2); + +m = r.exec("aaaa"); +assertEq(Array.isArray(m), true); +assertEq(m.length, 1); +assertEq(m[0], "a"); +assertEq(r.lastIndex, 1); + +m = r.exec("aaaa"); +assertEq(Array.isArray(m), true); +assertEq(m.length, 1); +assertEq(m[0], "a"); +assertEq(r.lastIndex, 2); + + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/RegExp/15.5.4.11.js b/js/src/tests/non262/RegExp/15.5.4.11.js new file mode 100644 index 0000000000..a5515286a0 --- /dev/null +++ b/js/src/tests/non262/RegExp/15.5.4.11.js @@ -0,0 +1,498 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var BUGNUMBER = 392378; +var summary = '15.5.4.11 - String.prototype.replace'; +var rex, f, a, i; + +reportCompare( + 2, + String.prototype.replace.length, + "Section 1" +); + +reportCompare( + "321", + String.prototype.replace.call(123, "123", "321"), + "Section 2" +); + +reportCompare( + "ok", + "ok".replace(), + "Section 3" +); + +reportCompare( + "undefined**", + "***".replace("*"), + "Section 4" +); + +reportCompare( + "xnullz", + "xyz".replace("y", null), + "Section 5" +); + +reportCompare( + "x123", + "xyz".replace("yz", 123), + "Section 6" +); + +reportCompare( + "/x/g/x/g/x/g", + "xxx".replace(/x/g, /x/g), + "Section 7" +); + +reportCompare( + "ok", + "undefined".replace(undefined, "ok"), + "Section 8" +); + +reportCompare( + "ok", + "null".replace(null, "ok"), + "Section 9" +); + +reportCompare( + "ok", + "123".replace(123, "ok"), + "Section 10" +); + +reportCompare( + "xzyxyz", + "xyzxyz".replace("yz", "zy"), + "Section 11" +); + +reportCompare( + "ok", + "(xyz)".replace("(xyz)", "ok"), + "Section 12" +); + +reportCompare( + "*$&yzxyz", + "xyzxyz".replace("x", "*$$&"), + "Section 13" +); + +reportCompare( + "xy*z*", + "xyz".replace("z", "*$&*"), + "Section 14" +); + +reportCompare( + "xyxyzxyz", + "xyzxyzxyz".replace("zxy", "$`"), + "Section 15" +); + +reportCompare( + "zxyzxyzzxyz", + "xyzxyz".replace("xy", "$'xyz"), + "Section 16" +); + +reportCompare( + "$", + "xyzxyz".replace("xyzxyz", "$"), + "Section 17" +); + +reportCompare( + "x$0$00xyz", + "xyzxyz".replace("yz", "$0$00"), + "Section 18" +); + +// Result for $1/$01 .. $99 is implementation-defined if searchValue is no +// regular expression. $+ is a non-standard Mozilla extension. + +reportCompare( + "$!$\"$-1$*$#$.$xyz$$", + "xyzxyz$$".replace("xyz", "$!$\"$-1$*$#$.$"), + "Section 19" +); + +reportCompare( + "$$$&$$$&$&", + "$$$&".replace("$$", "$$$$$$&$&$$&"), + "Section 20" +); + +reportCompare( + "yxx", + "xxx".replace(/x/, "y"), + "Section 21" +); + +reportCompare( + "yyy", + "xxx".replace(/x/g, "y"), + "Section 22" +); + +rex = /x/, rex.lastIndex = 1; +reportCompare( + "yxx1", + "xxx".replace(rex, "y") + rex.lastIndex, + "Section 23" +); + +rex = /x/g, rex.lastIndex = 1; +reportCompare( + "yyy0", + "xxx".replace(rex, "y") + rex.lastIndex, + "Section 24" +); + +rex = /y/, rex.lastIndex = 1; +reportCompare( + "xxx1", + "xxx".replace(rex, "y") + rex.lastIndex, + "Section 25" +); + +rex = /y/g, rex.lastIndex = 1; +reportCompare( + "xxx0", + "xxx".replace(rex, "y") + rex.lastIndex, + "Section 26" +); + +rex = /x?/, rex.lastIndex = 1; +reportCompare( + "(x)xx1", + "xxx".replace(rex, "($&)") + rex.lastIndex, + "Section 27" +); + +rex = /x?/g, rex.lastIndex = 1; +reportCompare( + "(x)(x)(x)()0", + "xxx".replace(rex, "($&)") + rex.lastIndex, + "Section 28" +); + +rex = /y?/, rex.lastIndex = 1; +reportCompare( + "()xxx1", + "xxx".replace(rex, "($&)") + rex.lastIndex, + "Section 29" +); + +rex = /y?/g, rex.lastIndex = 1; +reportCompare( + "()x()x()x()0", + "xxx".replace(rex, "($&)") + rex.lastIndex, + "Section 30" +); + +reportCompare( + "xy$0xy$zxy$zxyz$zxyz", + "xyzxyzxyz".replace(/zxy/, "$0$`$$$&$$$'$"), + "Section 31" +); + +reportCompare( + "xy$0xy$zxy$zxyz$$0xyzxy$zxy$z$z", + "xyzxyzxyz".replace(/zxy/g, "$0$`$$$&$$$'$"), + "Section 32" +); + +reportCompare( + "xyxyxyzxyxyxyz", + "xyzxyz".replace(/(((x)(y)()()))()()()(z)/g, "$01$2$3$04$5$6$7$8$09$10"), + "Section 33" +); + +rex = RegExp( + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()(y)"); +reportCompare( + "x(y)z", + "xyz".replace(rex, "($99)"), + "Section 34" +); + +rex = RegExp( + "()()()()()()()()()(x)" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()(y)"); +reportCompare( + "(x0)z", + "xyz".replace(rex, "($100)"), + "Section 35" +); + +reportCompare( + "xyz(XYZ)", + "xyzXYZ".replace(/XYZ/g, "($&)"), + "Section 36" +); + +reportCompare( + "(xyz)(XYZ)", + "xyzXYZ".replace(/xYz/gi, "($&)"), + "Section 37" +); + +reportCompare( + "xyz\rxyz\n", + "xyz\rxyz\n".replace(/xyz$/g, "($&)"), + "Section 38" +); + +reportCompare( + "(xyz)\r(xyz)\n", + "xyz\rxyz\n".replace(/xyz$/gm, "($&)"), + "Section 39" +); + +f = function () { return "failure" }; + +reportCompare( + "ok", + "ok".replace("x", f), + "Section 40" +); + +reportCompare( + "ok", + "ok".replace(/(?=k)ok/, f), + "Section 41" +); + +reportCompare( + "ok", + "ok".replace(/(?!)ok/, f), + "Section 42" +); + +reportCompare( + "ok", + "ok".replace(/ok(?!$)/, f), + "Section 43" +); + +f = function (sub, offs, str) { + return ["", sub, typeof sub, offs, typeof offs, str, typeof str, ""] + .join("|"); +}; + +reportCompare( + "x|y|string|1|number|xyz|string|z", + "xyz".replace("y", f), + "Section 44" +); + +reportCompare( + "x|(y)|string|1|number|x(y)z|string|z", + "x(y)z".replace("(y)", f), + "Section 45" +); + +reportCompare( + "x|y*|string|1|number|xy*z|string|z", + "xy*z".replace("y*", f), + "Section 46" +); + +reportCompare( + "12|3|string|2|number|12345|string|45", + String.prototype.replace.call(1.2345e4, 3, f), + "Section 47" +); + +reportCompare( + "|x|string|0|number|xxx|string|xx", + "xxx".replace(/^x/g, f), + "Section 48" +); + +reportCompare( + "xx|x|string|2|number|xxx|string|", + "xxx".replace(/x$/g, f), + "Section 49" +); + +f = function (sub, paren, offs, str) { + return ["", sub, typeof sub, paren, typeof paren, offs, typeof offs, + str, typeof str, ""].join("|"); +}; + +reportCompare( + "xy|z|string|z|string|2|number|xyz|string|", + "xyz".replace(/(z)/g, f), + "Section 50" +); + +reportCompare( + "xyz||string||string|3|number|xyz|string|", + "xyz".replace(/($)/g, f), + "Section 51" +); + +reportCompare( + "|xy|string|y|string|0|number|xyz|string|z", + "xyz".replace(/(?:x)(y)/g, f), + "Section 52" +); + +reportCompare( + "|x|string|x|string|0|number|xyz|string|yz", + "xyz".replace(/((?=xy)x)/g, f), + "Section 53" +); + +reportCompare( + "|x|string|x|string|0|number|xyz|string|yz", + "xyz".replace(/(x(?=y))/g, f), + "Section 54" +); + +reportCompare( + "x|y|string|y|string|1|number|xyz|string|z", + "xyz".replace(/((?!x)y)/g, f), + "Section 55" +); + +reportCompare( + "|x|string|x|string|0|number|xyz|string|" + + "|y|string||undefined|1|number|xyz|string|z", + "xyz".replace(/y|(x)/g, f), + "Section 56" +); + +reportCompare( + "xy|z|string||string|2|number|xyz|string|", + "xyz".replace(/(z?)z/, f), + "Section 57" +); + +reportCompare( + "xy|z|string||undefined|2|number|xyz|string|", + "xyz".replace(/(z)?z/, f), + "Section 58" +); + +reportCompare( + "xy|z|string||undefined|2|number|xyz|string|", + "xyz".replace(/(z)?\1z/, f), + "Section 59" +); + +reportCompare( + "xy|z|string||undefined|2|number|xyz|string|", + "xyz".replace(/\1(z)?z/, f), + "Section 60" +); + +reportCompare( + "xy|z|string||string|2|number|xyz|string|", + "xyz".replace(/(z?\1)z/, f), + "Section 61" +); + +f = function (sub, paren1, paren2, offs, str) { + return ["", sub, typeof sub, paren1, typeof paren1, paren2, typeof paren2, + offs, typeof offs, str, typeof str, ""].join("|"); +}; + +reportCompare( + "x|y|string|y|string||undefined|1|number|xyz|string|z", + "xyz".replace(/(y)(\1)?/, f), + "Section 62" +); + +reportCompare( + "x|yy|string|y|string|y|string|1|number|xyyz|string|z", + "xyyz".replace(/(y)(\1)?/g, f), + "Section 63" +); + +reportCompare( + "x|y|string|y|string||undefined|1|number|xyyz|string|" + + "|y|string|y|string||undefined|2|number|xyyz|string|z", + "xyyz".replace(/(y)(\1)??/g, f), + "Section 64" +); + +reportCompare( + "x|y|string|y|string|y|string|1|number|xyz|string|z", + "xyz".replace(/(?=(y))(\1)?/, f), + "Section 65" +); + +reportCompare( + "xyy|z|string||undefined||string|3|number|xyyz|string|", + "xyyz".replace(/(?!(y)y)(\1)z/, f), + "Section 66" +); + +rex = RegExp( + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()" + + "()()()()()()()()()()(z)?(y)"); +a = ["sub"]; +for (i = 1; i <= 102; ++i) + a[i] = "p" + i; +a[103] = "offs"; +a[104] = "str"; +a[105] = "return ['', sub, typeof sub, offs, typeof offs, str, typeof str, " + + "p100, typeof p100, p101, typeof p101, p102, typeof p102, ''].join('|');"; +f = Function.apply(null, a); +reportCompare( + "x|y|string|1|number|xyz|string||string||undefined|y|string|z", + "xyz".replace(rex, f), + "Section 67" +); + +reportCompare( + "undefined", + "".replace(/.*/g, function () {}), + "Section 68" +); + +reportCompare( + "nullxnullynullznull", + "xyz".replace(/.??/g, function () { return null; }), + "Section 69" +); + +reportCompare( + "111", + "xyz".replace(/./g, function () { return 1; }), + "Section 70" +); diff --git a/js/src/tests/non262/RegExp/7.8.5-01.js b/js/src/tests/non262/RegExp/7.8.5-01.js new file mode 100644 index 0000000000..be09bbc142 --- /dev/null +++ b/js/src/tests/non262/RegExp/7.8.5-01.js @@ -0,0 +1,35 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var BUGNUMBER = 615070; +var summary = "Line terminator after backslash is invalid in regexp literals"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var regexps = ["/\\\u000A/", "/\\\u000D/", "/\\\u2028/", "/\\\u2029/", + "/ab\\\n/", "/ab\\\r/", "/ab\\\u2028/", "/ab\\\u2029/", + "/ab[c\\\n]/", "/a[bc\\", "/\\"]; + +for(var i=0; i<regexps.length; i++) { + var src = regexps[i]; + try { + x = eval(src).source; + } catch(e) { + assertEq(e.constructor, SyntaxError); + continue; + } + assertEq(0, 1); +} + +/**************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/RegExp/RegExpExec-exec-type-check.js b/js/src/tests/non262/RegExp/RegExpExec-exec-type-check.js new file mode 100644 index 0000000000..6d0eba40ec --- /dev/null +++ b/js/src/tests/non262/RegExp/RegExpExec-exec-type-check.js @@ -0,0 +1,12 @@ +// Bug 1667094. + +var obj = { + exec() { + return function(){}; + } +}; + +assertEq(RegExp.prototype.test.call(obj, ""), true); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/RegExpExec-exec.js b/js/src/tests/non262/RegExp/RegExpExec-exec.js new file mode 100644 index 0000000000..e92792fcf4 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/RegExpExec-return.js b/js/src/tests/non262/RegExp/RegExpExec-return.js new file mode 100644 index 0000000000..1148aac07f --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/RegExp_dollar_number.js b/js/src/tests/non262/RegExp/RegExp_dollar_number.js new file mode 100644 index 0000000000..52680a1870 --- /dev/null +++ b/js/src/tests/non262/RegExp/RegExp_dollar_number.js @@ -0,0 +1,76 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + Filename: RegExp_dollar_number.js + Description: 'Tests RegExps $1, ..., $9 properties' + + Author: Nick Lerissa + Date: March 12, 1998 +*/ + +var SECTION = 'As described in Netscape doc "What\'s new in JavaScript 1.2"'; +var TITLE = 'RegExp: $1, ..., $9'; +var BUGNUMBER="123802"; + +printBugNumber(BUGNUMBER); +writeHeaderToLog('Executing script: RegExp_dollar_number.js'); +writeHeaderToLog( SECTION + " "+ TITLE); + + +// 'abcdefghi'.match(/(a(b(c(d(e)f)g)h)i)/); RegExp.$1 +'abcdefghi'.match(/(a(b(c(d(e)f)g)h)i)/); +new TestCase ( "'abcdefghi'.match(/(a(b(c(d(e)f)g)h)i)/); RegExp.$1", + 'abcdefghi', RegExp.$1); + +// 'abcdefghi'.match(/(a(b(c(d(e)f)g)h)i)/); RegExp.$2 +new TestCase ( "'abcdefghi'.match(/(a(b(c(d(e)f)g)h)i)/); RegExp.$2", + 'bcdefgh', RegExp.$2); + +// 'abcdefghi'.match(/(a(b(c(d(e)f)g)h)i)/); RegExp.$3 +new TestCase ( "'abcdefghi'.match(/(a(b(c(d(e)f)g)h)i)/); RegExp.$3", + 'cdefg', RegExp.$3); + +// 'abcdefghi'.match(/(a(b(c(d(e)f)g)h)i)/); RegExp.$4 +new TestCase ( "'abcdefghi'.match(/(a(b(c(d(e)f)g)h)i)/); RegExp.$4", + 'def', RegExp.$4); + +// 'abcdefghi'.match(/(a(b(c(d(e)f)g)h)i)/); RegExp.$5 +new TestCase ( "'abcdefghi'.match(/(a(b(c(d(e)f)g)h)i)/); RegExp.$5", + 'e', RegExp.$5); + +// 'abcdefghi'.match(/(a(b(c(d(e)f)g)h)i)/); RegExp.$6 +new TestCase ( "'abcdefghi'.match(/(a(b(c(d(e)f)g)h)i)/); RegExp.$6", + '', RegExp.$6); + +var a_to_z = 'abcdefghijklmnopqrstuvwxyz'; +var regexp1 = /(a)b(c)d(e)f(g)h(i)j(k)l(m)n(o)p(q)r(s)t(u)v(w)x(y)z/ + // 'abcdefghijklmnopqrstuvwxyz'.match(/(a)b(c)d(e)f(g)h(i)j(k)l(m)n(o)p(q)r(s)t(u)v(w)x(y)z/); RegExp.$1 + a_to_z.match(regexp1); + +new TestCase ( "'" + a_to_z + "'.match((a)b(c)....(y)z); RegExp.$1", + 'a', RegExp.$1); +new TestCase ( "'" + a_to_z + "'.match((a)b(c)....(y)z); RegExp.$2", + 'c', RegExp.$2); +new TestCase ( "'" + a_to_z + "'.match((a)b(c)....(y)z); RegExp.$3", + 'e', RegExp.$3); +new TestCase ( "'" + a_to_z + "'.match((a)b(c)....(y)z); RegExp.$4", + 'g', RegExp.$4); +new TestCase ( "'" + a_to_z + "'.match((a)b(c)....(y)z); RegExp.$5", + 'i', RegExp.$5); +new TestCase ( "'" + a_to_z + "'.match((a)b(c)....(y)z); RegExp.$6", + 'k', RegExp.$6); +new TestCase ( "'" + a_to_z + "'.match((a)b(c)....(y)z); RegExp.$7", + 'm', RegExp.$7); +new TestCase ( "'" + a_to_z + "'.match((a)b(c)....(y)z); RegExp.$8", + 'o', RegExp.$8); +new TestCase ( "'" + a_to_z + "'.match((a)b(c)....(y)z); RegExp.$9", + 'q', RegExp.$9); +/* + new TestCase ( "'" + a_to_z + "'.match((a)b(c)....(y)z); RegExp.$10", + 's', RegExp.$10); +*/ +test(); diff --git a/js/src/tests/non262/RegExp/RegExp_lastMatch.js b/js/src/tests/non262/RegExp/RegExp_lastMatch.js new file mode 100644 index 0000000000..b3a02bd4d4 --- /dev/null +++ b/js/src/tests/non262/RegExp/RegExp_lastMatch.js @@ -0,0 +1,52 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + Filename: RegExp_lastMatch.js + Description: 'Tests RegExps lastMatch property' + + Author: Nick Lerissa + Date: March 12, 1998 +*/ + +var SECTION = 'As described in Netscape doc "Whats new in JavaScript 1.2"'; +var TITLE = 'RegExp: lastMatch'; + +writeHeaderToLog('Executing script: RegExp_lastMatch.js'); +writeHeaderToLog( SECTION + " "+ TITLE); + + +// 'foo'.match(/foo/); RegExp.lastMatch +'foo'.match(/foo/); +new TestCase ( "'foo'.match(/foo/); RegExp.lastMatch", + 'foo', RegExp.lastMatch); + +// 'foo'.match(new RegExp('foo')); RegExp.lastMatch +'foo'.match(new RegExp('foo')); +new TestCase ( "'foo'.match(new RegExp('foo')); RegExp.lastMatch", + 'foo', RegExp.lastMatch); + +// 'xxx'.match(/bar/); RegExp.lastMatch +'xxx'.match(/bar/); +new TestCase ( "'xxx'.match(/bar/); RegExp.lastMatch", + 'foo', RegExp.lastMatch); + +// 'xxx'.match(/$/); RegExp.lastMatch +'xxx'.match(/$/); +new TestCase ( "'xxx'.match(/$/); RegExp.lastMatch", + '', RegExp.lastMatch); + +// 'abcdefg'.match(/^..(cd)[a-z]+/); RegExp.lastMatch +'abcdefg'.match(/^..(cd)[a-z]+/); +new TestCase ( "'abcdefg'.match(/^..(cd)[a-z]+/); RegExp.lastMatch", + 'abcdefg', RegExp.lastMatch); + +// 'abcdefgabcdefg'.match(/(a(b(c(d)e)f)g)\1/); RegExp.lastMatch +'abcdefgabcdefg'.match(/(a(b(c(d)e)f)g)\1/); +new TestCase ( "'abcdefgabcdefg'.match(/(a(b(c(d)e)f)g)\\1/); RegExp.lastMatch", + 'abcdefgabcdefg', RegExp.lastMatch); + +test(); diff --git a/js/src/tests/non262/RegExp/RegExp_lastMatch_as_array.js b/js/src/tests/non262/RegExp/RegExp_lastMatch_as_array.js new file mode 100644 index 0000000000..7356bd0464 --- /dev/null +++ b/js/src/tests/non262/RegExp/RegExp_lastMatch_as_array.js @@ -0,0 +1,52 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + Filename: RegExp_lastMatch_as_array.js + Description: 'Tests RegExps $& property (same tests as RegExp_lastMatch.js but using $&)' + + Author: Nick Lerissa + Date: March 13, 1998 +*/ + +var SECTION = 'As described in Netscape doc "Whats new in JavaScript 1.2"'; +var TITLE = 'RegExp: $&'; + +writeHeaderToLog('Executing script: RegExp_lastMatch_as_array.js'); +writeHeaderToLog( SECTION + " "+ TITLE); + + +// 'foo'.match(/foo/); RegExp['$&'] +'foo'.match(/foo/); +new TestCase ( "'foo'.match(/foo/); RegExp['$&']", + 'foo', RegExp['$&']); + +// 'foo'.match(new RegExp('foo')); RegExp['$&'] +'foo'.match(new RegExp('foo')); +new TestCase ( "'foo'.match(new RegExp('foo')); RegExp['$&']", + 'foo', RegExp['$&']); + +// 'xxx'.match(/bar/); RegExp['$&'] +'xxx'.match(/bar/); +new TestCase ( "'xxx'.match(/bar/); RegExp['$&']", + 'foo', RegExp['$&']); + +// 'xxx'.match(/$/); RegExp['$&'] +'xxx'.match(/$/); +new TestCase ( "'xxx'.match(/$/); RegExp['$&']", + '', RegExp['$&']); + +// 'abcdefg'.match(/^..(cd)[a-z]+/); RegExp['$&'] +'abcdefg'.match(/^..(cd)[a-z]+/); +new TestCase ( "'abcdefg'.match(/^..(cd)[a-z]+/); RegExp['$&']", + 'abcdefg', RegExp['$&']); + +// 'abcdefgabcdefg'.match(/(a(b(c(d)e)f)g)\1/); RegExp['$&'] +'abcdefgabcdefg'.match(/(a(b(c(d)e)f)g)\1/); +new TestCase ( "'abcdefgabcdefg'.match(/(a(b(c(d)e)f)g)\\1/); RegExp['$&']", + 'abcdefgabcdefg', RegExp['$&']); + +test(); diff --git a/js/src/tests/non262/RegExp/RegExp_lastParen.js b/js/src/tests/non262/RegExp/RegExp_lastParen.js new file mode 100644 index 0000000000..06f9d6c524 --- /dev/null +++ b/js/src/tests/non262/RegExp/RegExp_lastParen.js @@ -0,0 +1,66 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + Filename: RegExp_lastParen.js + Description: 'Tests RegExps lastParen property' + + Author: Nick Lerissa + Date: March 12, 1998 +*/ + +var SECTION = 'As described in Netscape doc "Whats new in JavaScript 1.2"'; +var TITLE = 'RegExp: lastParen'; + +writeHeaderToLog('Executing script: RegExp_lastParen.js'); +writeHeaderToLog( SECTION + " "+ TITLE); + +// 'abcd'.match(/(abc)d/); RegExp.lastParen +'abcd'.match(/(abc)d/); +new TestCase ( "'abcd'.match(/(abc)d/); RegExp.lastParen", + 'abc', RegExp.lastParen); + +// 'abcd'.match(new RegExp('(abc)d')); RegExp.lastParen +'abcd'.match(new RegExp('(abc)d')); +new TestCase ( "'abcd'.match(new RegExp('(abc)d')); RegExp.lastParen", + 'abc', RegExp.lastParen); + +// 'abcd'.match(/(bcd)e/); RegExp.lastParen +'abcd'.match(/(bcd)e/); +new TestCase ( "'abcd'.match(/(bcd)e/); RegExp.lastParen", + 'abc', RegExp.lastParen); + +// 'abcdefg'.match(/(a(b(c(d)e)f)g)/); RegExp.lastParen +'abcdefg'.match(/(a(b(c(d)e)f)g)/); +new TestCase ( "'abcdefg'.match(/(a(b(c(d)e)f)g)/); RegExp.lastParen", + 'd', RegExp.lastParen); + +// 'abcdefg'.match(/(a(b)c)(d(e)f)/); RegExp.lastParen +'abcdefg'.match(/(a(b)c)(d(e)f)/); +new TestCase ( "'abcdefg'.match(/(a(b)c)(d(e)f)/); RegExp.lastParen", + 'e', RegExp.lastParen); + +// 'abcdefg'.match(/(^)abc/); RegExp.lastParen +'abcdefg'.match(/(^)abc/); +new TestCase ( "'abcdefg'.match(/(^)abc/); RegExp.lastParen", + '', RegExp.lastParen); + +// 'abcdefg'.match(/(^a)bc/); RegExp.lastParen +'abcdefg'.match(/(^a)bc/); +new TestCase ( "'abcdefg'.match(/(^a)bc/); RegExp.lastParen", + 'a', RegExp.lastParen); + +// 'abcdefg'.match(new RegExp('(^a)bc')); RegExp.lastParen +'abcdefg'.match(new RegExp('(^a)bc')); +new TestCase ( "'abcdefg'.match(new RegExp('(^a)bc')); RegExp.lastParen", + 'a', RegExp.lastParen); + +// 'abcdefg'.match(/bc/); RegExp.lastParen +'abcdefg'.match(/bc/); +new TestCase ( "'abcdefg'.match(/bc/); RegExp.lastParen", + '', RegExp.lastParen); + +test(); diff --git a/js/src/tests/non262/RegExp/RegExp_lastParen_as_array.js b/js/src/tests/non262/RegExp/RegExp_lastParen_as_array.js new file mode 100644 index 0000000000..4a5663ab67 --- /dev/null +++ b/js/src/tests/non262/RegExp/RegExp_lastParen_as_array.js @@ -0,0 +1,66 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + Filename: RegExp_lastParen_as_array.js + Description: 'Tests RegExps $+ property (same tests as RegExp_lastParen.js but using $+)' + + Author: Nick Lerissa + Date: March 13, 1998 +*/ + +var SECTION = 'As described in Netscape doc "Whats new in JavaScript 1.2"'; +var TITLE = 'RegExp: $+'; + +writeHeaderToLog('Executing script: RegExp_lastParen_as_array.js'); +writeHeaderToLog( SECTION + " "+ TITLE); + +// 'abcd'.match(/(abc)d/); RegExp['$+'] +'abcd'.match(/(abc)d/); +new TestCase ( "'abcd'.match(/(abc)d/); RegExp['$+']", + 'abc', RegExp['$+']); + +// 'abcd'.match(/(bcd)e/); RegExp['$+'] +'abcd'.match(/(bcd)e/); +new TestCase ( "'abcd'.match(/(bcd)e/); RegExp['$+']", + 'abc', RegExp['$+']); + +// 'abcdefg'.match(/(a(b(c(d)e)f)g)/); RegExp['$+'] +'abcdefg'.match(/(a(b(c(d)e)f)g)/); +new TestCase ( "'abcdefg'.match(/(a(b(c(d)e)f)g)/); RegExp['$+']", + 'd', RegExp['$+']); + +// 'abcdefg'.match(new RegExp('(a(b(c(d)e)f)g)')); RegExp['$+'] +'abcdefg'.match(new RegExp('(a(b(c(d)e)f)g)')); +new TestCase ( "'abcdefg'.match(new RegExp('(a(b(c(d)e)f)g)')); RegExp['$+']", + 'd', RegExp['$+']); + +// 'abcdefg'.match(/(a(b)c)(d(e)f)/); RegExp['$+'] +'abcdefg'.match(/(a(b)c)(d(e)f)/); +new TestCase ( "'abcdefg'.match(/(a(b)c)(d(e)f)/); RegExp['$+']", + 'e', RegExp['$+']); + +// 'abcdefg'.match(/(^)abc/); RegExp['$+'] +'abcdefg'.match(/(^)abc/); +new TestCase ( "'abcdefg'.match(/(^)abc/); RegExp['$+']", + '', RegExp['$+']); + +// 'abcdefg'.match(/(^a)bc/); RegExp['$+'] +'abcdefg'.match(/(^a)bc/); +new TestCase ( "'abcdefg'.match(/(^a)bc/); RegExp['$+']", + 'a', RegExp['$+']); + +// 'abcdefg'.match(new RegExp('(^a)bc')); RegExp['$+'] +'abcdefg'.match(new RegExp('(^a)bc')); +new TestCase ( "'abcdefg'.match(new RegExp('(^a)bc')); RegExp['$+']", + 'a', RegExp['$+']); + +// 'abcdefg'.match(/bc/); RegExp['$+'] +'abcdefg'.match(/bc/); +new TestCase ( "'abcdefg'.match(/bc/); RegExp['$+']", + '', RegExp['$+']); + +test(); diff --git a/js/src/tests/non262/RegExp/RegExp_leftContext.js b/js/src/tests/non262/RegExp/RegExp_leftContext.js new file mode 100644 index 0000000000..616f0a3e00 --- /dev/null +++ b/js/src/tests/non262/RegExp/RegExp_leftContext.js @@ -0,0 +1,56 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + Filename: RegExp_leftContext.js + Description: 'Tests RegExps leftContext property' + + Author: Nick Lerissa + Date: March 12, 1998 +*/ + +var SECTION = 'As described in Netscape doc "Whats new in JavaScript 1.2"'; +var TITLE = 'RegExp: leftContext'; + +writeHeaderToLog('Executing script: RegExp_leftContext.js'); +writeHeaderToLog( SECTION + " "+ TITLE); + +// 'abc123xyz'.match(/123/); RegExp.leftContext +'abc123xyz'.match(/123/); +new TestCase ( "'abc123xyz'.match(/123/); RegExp.leftContext", + 'abc', RegExp.leftContext); + +// 'abc123xyz'.match(/456/); RegExp.leftContext +'abc123xyz'.match(/456/); +new TestCase ( "'abc123xyz'.match(/456/); RegExp.leftContext", + 'abc', RegExp.leftContext); + +// 'abc123xyz'.match(/abc123xyz/); RegExp.leftContext +'abc123xyz'.match(/abc123xyz/); +new TestCase ( "'abc123xyz'.match(/abc123xyz/); RegExp.leftContext", + '', RegExp.leftContext); + +// 'xxxx'.match(/$/); RegExp.leftContext +'xxxx'.match(/$/); +new TestCase ( "'xxxx'.match(/$/); RegExp.leftContext", + 'xxxx', RegExp.leftContext); + +// 'test'.match(/^/); RegExp.leftContext +'test'.match(/^/); +new TestCase ( "'test'.match(/^/); RegExp.leftContext", + '', RegExp.leftContext); + +// 'xxxx'.match(new RegExp('$')); RegExp.leftContext +'xxxx'.match(new RegExp('$')); +new TestCase ( "'xxxx'.match(new RegExp('$')); RegExp.leftContext", + 'xxxx', RegExp.leftContext); + +// 'test'.match(new RegExp('^')); RegExp.leftContext +'test'.match(new RegExp('^')); +new TestCase ( "'test'.match(new RegExp('^')); RegExp.leftContext", + '', RegExp.leftContext); + +test(); diff --git a/js/src/tests/non262/RegExp/RegExp_leftContext_as_array.js b/js/src/tests/non262/RegExp/RegExp_leftContext_as_array.js new file mode 100644 index 0000000000..04e7948476 --- /dev/null +++ b/js/src/tests/non262/RegExp/RegExp_leftContext_as_array.js @@ -0,0 +1,56 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + Filename: RegExp_leftContext_as_array.js + Description: 'Tests RegExps leftContext property (same tests as RegExp_leftContext.js but using $`)' + + Author: Nick Lerissa + Date: March 12, 1998 +*/ + +var SECTION = 'As described in Netscape doc "Whats new in JavaScript 1.2"'; +var TITLE = 'RegExp: $`'; + +writeHeaderToLog('Executing script: RegExp_leftContext_as_array.js'); +writeHeaderToLog( SECTION + " "+ TITLE); + +// 'abc123xyz'.match(/123/); RegExp['$`'] +'abc123xyz'.match(/123/); +new TestCase ( "'abc123xyz'.match(/123/); RegExp['$`']", + 'abc', RegExp['$`']); + +// 'abc123xyz'.match(/456/); RegExp['$`'] +'abc123xyz'.match(/456/); +new TestCase ( "'abc123xyz'.match(/456/); RegExp['$`']", + 'abc', RegExp['$`']); + +// 'abc123xyz'.match(/abc123xyz/); RegExp['$`'] +'abc123xyz'.match(/abc123xyz/); +new TestCase ( "'abc123xyz'.match(/abc123xyz/); RegExp['$`']", + '', RegExp['$`']); + +// 'xxxx'.match(/$/); RegExp['$`'] +'xxxx'.match(/$/); +new TestCase ( "'xxxx'.match(/$/); RegExp['$`']", + 'xxxx', RegExp['$`']); + +// 'test'.match(/^/); RegExp['$`'] +'test'.match(/^/); +new TestCase ( "'test'.match(/^/); RegExp['$`']", + '', RegExp['$`']); + +// 'xxxx'.match(new RegExp('$')); RegExp['$`'] +'xxxx'.match(new RegExp('$')); +new TestCase ( "'xxxx'.match(new RegExp('$')); RegExp['$`']", + 'xxxx', RegExp['$`']); + +// 'test'.match(new RegExp('^')); RegExp['$`'] +'test'.match(new RegExp('^')); +new TestCase ( "'test'.match(new RegExp('^')); RegExp['$`']", + '', RegExp['$`']); + +test(); diff --git a/js/src/tests/non262/RegExp/RegExp_object.js b/js/src/tests/non262/RegExp/RegExp_object.js new file mode 100644 index 0000000000..69fe4946ad --- /dev/null +++ b/js/src/tests/non262/RegExp/RegExp_object.js @@ -0,0 +1,54 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + Filename: RegExp_object.js + Description: 'Tests regular expressions creating RexExp Objects' + + Author: Nick Lerissa + Date: March 10, 1998 +*/ + +var SECTION = 'As described in Netscape doc "Whats new in JavaScript 1.2"'; +var TITLE = 'RegExp: object'; + +writeHeaderToLog('Executing script: RegExp_object.js'); +writeHeaderToLog( SECTION + " "+ TITLE); + +var SSN_pattern = new RegExp("\\d{3}-\\d{2}-\\d{4}"); + +// testing SSN pattern +new TestCase ( "'Test SSN is 123-34-4567'.match(SSN_pattern))", + String(["123-34-4567"]), String('Test SSN is 123-34-4567'.match(SSN_pattern))); + +// testing SSN pattern +new TestCase ( "'Test SSN is 123-34-4567'.match(SSN_pattern))", + String(["123-34-4567"]), String('Test SSN is 123-34-4567'.match(SSN_pattern))); + +var PHONE_pattern = new RegExp("\\(?(\\d{3})\\)?-?(\\d{3})-(\\d{4})"); +// testing PHONE pattern +new TestCase ( "'Our phone number is (408)345-2345.'.match(PHONE_pattern))", + String(["(408)345-2345","408","345","2345"]), String('Our phone number is (408)345-2345.'.match(PHONE_pattern))); + +// testing PHONE pattern +new TestCase ( "'The phone number is 408-345-2345!'.match(PHONE_pattern))", + String(["408-345-2345","408","345","2345"]), String('The phone number is 408-345-2345!'.match(PHONE_pattern))); + +// testing PHONE pattern +new TestCase ( "String(PHONE_pattern.toString())", + "/\\(?(\\d{3})\\)?-?(\\d{3})-(\\d{4})/", String(PHONE_pattern.toString())); + +// testing conversion to String +new TestCase ( "PHONE_pattern + ' is the string'", + "/\\(?(\\d{3})\\)?-?(\\d{3})-(\\d{4})/ is the string",PHONE_pattern + ' is the string'); + +// testing conversion to int +new TestCase ( "SSN_pattern - 8", + NaN,SSN_pattern - 8); + +var testPattern = new RegExp("(\\d+)45(\\d+)90"); + +test(); diff --git a/js/src/tests/non262/RegExp/RegExp_rightContext.js b/js/src/tests/non262/RegExp/RegExp_rightContext.js new file mode 100644 index 0000000000..131e989ad1 --- /dev/null +++ b/js/src/tests/non262/RegExp/RegExp_rightContext.js @@ -0,0 +1,56 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + Filename: RegExp_rightContext.js + Description: 'Tests RegExps rightContext property' + + Author: Nick Lerissa + Date: March 12, 1998 +*/ + +var SECTION = 'As described in Netscape doc "Whats new in JavaScript 1.2"'; +var TITLE = 'RegExp: rightContext'; + +writeHeaderToLog('Executing script: RegExp_rightContext.js'); +writeHeaderToLog( SECTION + " "+ TITLE); + +// 'abc123xyz'.match(/123/); RegExp.rightContext +'abc123xyz'.match(/123/); +new TestCase ( "'abc123xyz'.match(/123/); RegExp.rightContext", + 'xyz', RegExp.rightContext); + +// 'abc123xyz'.match(/456/); RegExp.rightContext +'abc123xyz'.match(/456/); +new TestCase ( "'abc123xyz'.match(/456/); RegExp.rightContext", + 'xyz', RegExp.rightContext); + +// 'abc123xyz'.match(/abc123xyz/); RegExp.rightContext +'abc123xyz'.match(/abc123xyz/); +new TestCase ( "'abc123xyz'.match(/abc123xyz/); RegExp.rightContext", + '', RegExp.rightContext); + +// 'xxxx'.match(/$/); RegExp.rightContext +'xxxx'.match(/$/); +new TestCase ( "'xxxx'.match(/$/); RegExp.rightContext", + '', RegExp.rightContext); + +// 'test'.match(/^/); RegExp.rightContext +'test'.match(/^/); +new TestCase ( "'test'.match(/^/); RegExp.rightContext", + 'test', RegExp.rightContext); + +// 'xxxx'.match(new RegExp('$')); RegExp.rightContext +'xxxx'.match(new RegExp('$')); +new TestCase ( "'xxxx'.match(new RegExp('$')); RegExp.rightContext", + '', RegExp.rightContext); + +// 'test'.match(new RegExp('^')); RegExp.rightContext +'test'.match(new RegExp('^')); +new TestCase ( "'test'.match(new RegExp('^')); RegExp.rightContext", + 'test', RegExp.rightContext); + +test(); diff --git a/js/src/tests/non262/RegExp/RegExp_rightContext_as_array.js b/js/src/tests/non262/RegExp/RegExp_rightContext_as_array.js new file mode 100644 index 0000000000..34dbcaac4d --- /dev/null +++ b/js/src/tests/non262/RegExp/RegExp_rightContext_as_array.js @@ -0,0 +1,56 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + Filename: RegExp_rightContext_as_array.js + Description: 'Tests RegExps $\' property (same tests as RegExp_rightContext.js but using $\)' + + Author: Nick Lerissa + Date: March 12, 1998 +*/ + +var SECTION = 'As described in Netscape doc "Whats new in JavaScript 1.2"'; +var TITLE = 'RegExp: $\''; + +writeHeaderToLog('Executing script: RegExp_rightContext.js'); +writeHeaderToLog( SECTION + " "+ TITLE); + +// 'abc123xyz'.match(/123/); RegExp['$\''] +'abc123xyz'.match(/123/); +new TestCase ( "'abc123xyz'.match(/123/); RegExp['$\'']", + 'xyz', RegExp['$\'']); + +// 'abc123xyz'.match(/456/); RegExp['$\''] +'abc123xyz'.match(/456/); +new TestCase ( "'abc123xyz'.match(/456/); RegExp['$\'']", + 'xyz', RegExp['$\'']); + +// 'abc123xyz'.match(/abc123xyz/); RegExp['$\''] +'abc123xyz'.match(/abc123xyz/); +new TestCase ( "'abc123xyz'.match(/abc123xyz/); RegExp['$\'']", + '', RegExp['$\'']); + +// 'xxxx'.match(/$/); RegExp['$\''] +'xxxx'.match(/$/); +new TestCase ( "'xxxx'.match(/$/); RegExp['$\'']", + '', RegExp['$\'']); + +// 'test'.match(/^/); RegExp['$\''] +'test'.match(/^/); +new TestCase ( "'test'.match(/^/); RegExp['$\'']", + 'test', RegExp['$\'']); + +// 'xxxx'.match(new RegExp('$')); RegExp['$\''] +'xxxx'.match(new RegExp('$')); +new TestCase ( "'xxxx'.match(new RegExp('$')); RegExp['$\'']", + '', RegExp['$\'']); + +// 'test'.match(new RegExp('^')); RegExp['$\''] +'test'.match(new RegExp('^')); +new TestCase ( "'test'.match(new RegExp('^')); RegExp['$\'']", + 'test', RegExp['$\'']); + +test(); diff --git a/js/src/tests/non262/RegExp/browser.js b/js/src/tests/non262/RegExp/browser.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/js/src/tests/non262/RegExp/browser.js diff --git a/js/src/tests/non262/RegExp/character-class-escape-s.js b/js/src/tests/non262/RegExp/character-class-escape-s.js new file mode 100644 index 0000000000..88514c4dda --- /dev/null +++ b/js/src/tests/non262/RegExp/character-class-escape-s.js @@ -0,0 +1,54 @@ +/* Generated by make_unicode.py DO NOT MODIFY */ +/* Unicode version: 15.0.0 */ + +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ +var onlySpace = String.fromCodePoint( + 0x0009 /* <control> (CHARACTER TABULATION) */, + 0x000A /* <control> (LINE FEED (LF)) */, + 0x000B /* <control> (LINE TABULATION) */, + 0x000C /* <control> (FORM FEED (FF)) */, + 0x000D /* <control> (CARRIAGE RETURN (CR)) */, + 0x0020 /* SPACE */, + 0x00A0 /* NO-BREAK SPACE (NON-BREAKING SPACE) */, + 0x1680 /* OGHAM SPACE MARK */, + 0x2000 /* EN QUAD */, + 0x2001 /* EM QUAD */, + 0x2002 /* EN SPACE */, + 0x2003 /* EM SPACE */, + 0x2004 /* THREE-PER-EM SPACE */, + 0x2005 /* FOUR-PER-EM SPACE */, + 0x2006 /* SIX-PER-EM SPACE */, + 0x2007 /* FIGURE SPACE */, + 0x2008 /* PUNCTUATION SPACE */, + 0x2009 /* THIN SPACE */, + 0x200A /* HAIR SPACE */, + 0x2028 /* LINE SEPARATOR */, + 0x2029 /* PARAGRAPH SEPARATOR */, + 0x202F /* NARROW NO-BREAK SPACE */, + 0x205F /* MEDIUM MATHEMATICAL SPACE */, + 0x3000 /* IDEOGRAPHIC SPACE */, + 0xFEFF /* ZERO WIDTH NO-BREAK SPACE (BYTE ORDER MARK) */ +); + +assertEq(/^\s+$/.exec(onlySpace) !== null, true); +assertEq(/^[\s]+$/.exec(onlySpace) !== null, true); +assertEq(/^[^\s]+$/.exec(onlySpace) === null, true); + +assertEq(/^\S+$/.exec(onlySpace) === null, true); +assertEq(/^[\S]+$/.exec(onlySpace) === null, true); +assertEq(/^[^\S]+$/.exec(onlySpace) !== null, true); + +// Also test with Unicode RegExps. +assertEq(/^\s+$/u.exec(onlySpace) !== null, true); +assertEq(/^[\s]+$/u.exec(onlySpace) !== null, true); +assertEq(/^[^\s]+$/u.exec(onlySpace) === null, true); + +assertEq(/^\S+$/u.exec(onlySpace) === null, true); +assertEq(/^[\S]+$/u.exec(onlySpace) === null, true); +assertEq(/^[^\S]+$/u.exec(onlySpace) !== null, true); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/character-escape-class-s-mongolian-vowel-separator.js b/js/src/tests/non262/RegExp/character-escape-class-s-mongolian-vowel-separator.js new file mode 100644 index 0000000000..d7a8b980da --- /dev/null +++ b/js/src/tests/non262/RegExp/character-escape-class-s-mongolian-vowel-separator.js @@ -0,0 +1,25 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var mongolian_vowel_separator = "\u180e"; + +assertEq(/^\s+$/.exec(mongolian_vowel_separator) === null, true); +assertEq(/^[\s]+$/.exec(mongolian_vowel_separator) === null, true); +assertEq(/^[^\s]+$/.exec(mongolian_vowel_separator) !== null, true); + +assertEq(/^\S+$/.exec(mongolian_vowel_separator) !== null, true); +assertEq(/^[\S]+$/.exec(mongolian_vowel_separator) !== null, true); +assertEq(/^[^\S]+$/.exec(mongolian_vowel_separator) === null, true); + +// Also test with Unicode RegExps. +assertEq(/^\s+$/u.exec(mongolian_vowel_separator) === null, true); +assertEq(/^[\s]+$/u.exec(mongolian_vowel_separator) === null, true); +assertEq(/^[^\s]+$/u.exec(mongolian_vowel_separator) !== null, true); + +assertEq(/^\S+$/u.exec(mongolian_vowel_separator) !== null, true); +assertEq(/^[\S]+$/u.exec(mongolian_vowel_separator) !== null, true); +assertEq(/^[^\S]+$/u.exec(mongolian_vowel_separator) === null, true); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/class-null.js b/js/src/tests/non262/RegExp/class-null.js new file mode 100644 index 0000000000..c95e5a4d79 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/compile-lastIndex.js b/js/src/tests/non262/RegExp/compile-lastIndex.js new file mode 100644 index 0000000000..5bd7e0b983 --- /dev/null +++ b/js/src/tests/non262/RegExp/compile-lastIndex.js @@ -0,0 +1,82 @@ +/* + * 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 one incidental effect +// ubiquitously tested through the remainder of this test: +// +// * RegExp.prototype.compile will do everything it ordinarily does, BUT it +// will throw a TypeError when attempting to zero .lastIndex immediately +// before succeeding overall. +// +// 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); +assertEq(regex.test("bar"), false); +assertEq(regex.test("BAR"), false); + +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); +assertEq(regex.test("foo"), false); +assertEq(regex.test("FOO"), false); +assertEq(regex.test("bar"), true); +assertEq(regex.test("BAR"), false); + +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); +assertEq(regex.test("foo"), false); +assertEq(regex.test("FOO"), false); +assertEq(regex.test("bar"), false); +assertEq(regex.test("BAR"), false); +assertEq(regex.test("baz"), true); +assertEq(regex.test("BAZ"), false); +assertEq(regex.test("012345678901234567890123456789012345678901baz"), false); +assertEq(regex.test("012345678901234567890123456789012345678901\nbaz"), true); +assertEq(regex.test("012345678901234567890123456789012345678901BAZ"), false); +assertEq(regex.test("012345678901234567890123456789012345678901\nBAZ"), false); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/tests/non262/RegExp/compile-symbol.js b/js/src/tests/non262/RegExp/compile-symbol.js new file mode 100644 index 0000000000..9eea1124c8 --- /dev/null +++ b/js/src/tests/non262/RegExp/compile-symbol.js @@ -0,0 +1,14 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +for (let sym of [Symbol.iterator, Symbol(), Symbol("description")]) { + let re = /a/; + + assertEq(re.source, "a"); + assertThrowsInstanceOf(() => re.compile(sym), TypeError); + assertEq(re.source, "a"); +} + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/RegExp/constructor-IsRegExp.js b/js/src/tests/non262/RegExp/constructor-IsRegExp.js new file mode 100644 index 0000000000..8c735e4b97 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/constructor-constructor.js b/js/src/tests/non262/RegExp/constructor-constructor.js new file mode 100644 index 0000000000..528f4978c2 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/constructor-ordering-2.js b/js/src/tests/non262/RegExp/constructor-ordering-2.js new file mode 100644 index 0000000000..21a6bbeca7 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/constructor-ordering.js b/js/src/tests/non262/RegExp/constructor-ordering.js new file mode 100644 index 0000000000..3e3a9b695b --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/constructor-regexp-unicode.js b/js/src/tests/non262/RegExp/constructor-regexp-unicode.js new file mode 100644 index 0000000000..b348c34a01 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/constructor-regexp.js b/js/src/tests/non262/RegExp/constructor-regexp.js new file mode 100644 index 0000000000..419b027138 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/constructor-symbol.js b/js/src/tests/non262/RegExp/constructor-symbol.js new file mode 100644 index 0000000000..503d7e5a85 --- /dev/null +++ b/js/src/tests/non262/RegExp/constructor-symbol.js @@ -0,0 +1,14 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +for (let sym of [Symbol.iterator, Symbol(), Symbol("description")]) { + assertThrowsInstanceOf(() => RegExp(sym), TypeError); + assertThrowsInstanceOf(() => new RegExp(sym), TypeError); + + assertThrowsInstanceOf(() => RegExp(sym, "g"), TypeError); + assertThrowsInstanceOf(() => new RegExp(sym, "g"), TypeError); +} + +if (typeof reportCompare === 'function') + reportCompare(0, 0); diff --git a/js/src/tests/non262/RegExp/control_characters.js b/js/src/tests/non262/RegExp/control_characters.js new file mode 100644 index 0000000000..dcef462a9a --- /dev/null +++ b/js/src/tests/non262/RegExp/control_characters.js @@ -0,0 +1,39 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + Filename: control_characters.js + Description: 'Tests regular expressions containing .' + + Author: Nick Lerissa + Date: April 8, 1998 +*/ + +var SECTION = 'As described in Netscape doc "Whats new in JavaScript 1.2"'; +var TITLE = 'RegExp: .'; +var BUGNUMBER="123802"; + +printBugNumber(BUGNUMBER); +writeHeaderToLog('Executing script: control_characters.js'); +writeHeaderToLog( SECTION + " "+ TITLE); + + +// 'àOÐ ê:i¢Ø'.match(new RegExp('.+')) +new TestCase ( "'àOÐ ê:i¢Ø'.match(new RegExp('.+'))", + String(['àOÐ ê:i¢Ø']), String('àOÐ ê:i¢Ø'.match(new RegExp('.+')))); + +// string1.match(new RegExp(string1)) +var string1 = 'àOÐ ê:i¢Ø'; +new TestCase ( "string1 = " + string1 + " string1.match(string1)", + String([string1]), String(string1.match(string1))); + +string1 = ""; +for (var i = 0; i < 32; i++) + string1 += String.fromCharCode(i); +new TestCase ( "string1 = " + string1 + " string1.match(string1)", + String([string1]), String(string1.match(string1))); + +test(); diff --git a/js/src/tests/non262/RegExp/cross-compartment-getter.js b/js/src/tests/non262/RegExp/cross-compartment-getter.js new file mode 100644 index 0000000000..c625c63177 --- /dev/null +++ b/js/src/tests/non262/RegExp/cross-compartment-getter.js @@ -0,0 +1,43 @@ +const otherGlobal = newGlobal({newCompartment: true}); + +let regExp = otherGlobal.eval("/a(b|c)/iy"); + +function get(name) { + const descriptor = Object.getOwnPropertyDescriptor(RegExp.prototype, name); + return descriptor.get.call(regExp); +} + +assertEq(get("flags"), "iy"); +assertEq(get("global"), false); +assertEq(get("ignoreCase"), true); +assertEq(get("multiline"), false); +assertEq(get("dotAll"), false); +assertEq(get("source"), "a(b|c)"); +assertEq(get("sticky"), true); +assertEq(get("unicode"), false); + +regExp = otherGlobal.eval("new RegExp('', 'gu')"); + +assertEq(get("flags"), "gu"); +assertEq(get("global"), true); +assertEq(get("ignoreCase"), false); +assertEq(get("multiline"), false); +assertEq(get("dotAll"), false); +assertEq(get("source"), "(?:)"); +assertEq(get("sticky"), false); +assertEq(get("unicode"), true); + +// Trigger escaping +regExp = otherGlobal.eval("new RegExp('a/b', '')"); + +assertEq(get("flags"), ""); +assertEq(get("global"), false); +assertEq(get("ignoreCase"), false); +assertEq(get("multiline"), false); +assertEq(get("dotAll"), false); +assertEq(get("source"), "a\\/b"); +assertEq(get("sticky"), false); +assertEq(get("unicode"), false); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/descriptor.js b/js/src/tests/non262/RegExp/descriptor.js new file mode 100644 index 0000000000..cc545b3a6a --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/empty-lookahead.js b/js/src/tests/non262/RegExp/empty-lookahead.js new file mode 100644 index 0000000000..6e2f709e86 --- /dev/null +++ b/js/src/tests/non262/RegExp/empty-lookahead.js @@ -0,0 +1,8 @@ +//bug 473941 +var regexp; + +regexp = /(?=)/; +assertEq(regexp.test('test'), true); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/escape.js b/js/src/tests/non262/RegExp/escape.js new file mode 100644 index 0000000000..bb59b797d3 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/everything.js b/js/src/tests/non262/RegExp/everything.js new file mode 100644 index 0000000000..798eccc829 --- /dev/null +++ b/js/src/tests/non262/RegExp/everything.js @@ -0,0 +1,47 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + Filename: everything.js + Description: 'Tests regular expressions' + + Author: Nick Lerissa + Date: March 24, 1998 +*/ + +var SECTION = 'As described in Netscape doc "Whats new in JavaScript 1.2"'; +var TITLE = 'RegExp'; + +writeHeaderToLog('Executing script: everything.js'); +writeHeaderToLog( SECTION + " "+ TITLE); + + +// 'Sally and Fred are sure to come.'.match(/^[a-z\s]*/i) +new TestCase ( "'Sally and Fred are sure to come'.match(/^[a-z\\s]*/i)", + String(["Sally and Fred are sure to come"]), String('Sally and Fred are sure to come'.match(/^[a-z\s]*/i))); + +// 'test123W+xyz'.match(new RegExp('^[a-z]*[0-9]+[A-Z]?.(123|xyz)$')) +new TestCase ( "'test123W+xyz'.match(new RegExp('^[a-z]*[0-9]+[A-Z]?.(123|xyz)$'))", + String(["test123W+xyz","xyz"]), String('test123W+xyz'.match(new RegExp('^[a-z]*[0-9]+[A-Z]?.(123|xyz)$')))); + +// 'number one 12365 number two 9898'.match(/(\d+)\D+(\d+)/) +new TestCase ( "'number one 12365 number two 9898'.match(/(\d+)\D+(\d+)/)", + String(["12365 number two 9898","12365","9898"]), String('number one 12365 number two 9898'.match(/(\d+)\D+(\d+)/))); + +var simpleSentence = /(\s?[^\!\?\.]+[\!\?\.])+/; +// 'See Spot run.'.match(simpleSentence) +new TestCase ( "'See Spot run.'.match(simpleSentence)", + String(["See Spot run.","See Spot run."]), String('See Spot run.'.match(simpleSentence))); + +// 'I like it. What's up? I said NO!'.match(simpleSentence) +new TestCase ( "'I like it. What's up? I said NO!'.match(simpleSentence)", + String(["I like it. What's up? I said NO!",' I said NO!']), String('I like it. What\'s up? I said NO!'.match(simpleSentence))); + +// 'the quick brown fox jumped over the lazy dogs'.match(/((\w+)\s*)+/) +new TestCase ( "'the quick brown fox jumped over the lazy dogs'.match(/((\\w+)\\s*)+/)", + String(['the quick brown fox jumped over the lazy dogs','dogs','dogs']),String('the quick brown fox jumped over the lazy dogs'.match(/((\w+)\s*)+/))); + +test(); diff --git a/js/src/tests/non262/RegExp/exec-002.js b/js/src/tests/non262/RegExp/exec-002.js new file mode 100644 index 0000000000..d1293e81ec --- /dev/null +++ b/js/src/tests/non262/RegExp/exec-002.js @@ -0,0 +1,186 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + * File Name: RegExp/exec-002.js + * ECMA Section: 15.7.5.3 + * Description: Based on ECMA 2 Draft 7 February 1999 + * + * Test cases provided by rogerl@netscape.com + * + * Author: christine@netscape.com + * Date: 19 February 1999 + */ +var SECTION = "RegExp/exec-002"; +var TITLE = "RegExp.prototype.exec(string)"; + + +/* + * for each test case, verify: + * - type of object returned + * - length of the returned array + * - value of lastIndex + * - value of index + * - value of input + * - value of the array indices + */ + +AddRegExpCases( + /(a|d|q|)x/i, + "bcaDxqy", + 3, + ["Dx", "D"] ); + +AddRegExpCases( + /(a|(e|q))(x|y)/, + "bcaddxqy", + 6, + ["qy","q","q","y"] ); + + +AddRegExpCases( + /a+b+d/, + "aabbeeaabbs", + 0, + null ); + +AddRegExpCases( + /a*b/, + "aaadaabaaa", + 4, + ["aab"] ); + +AddRegExpCases( + /a*b/, + "dddb", + 3, + ["b"] ); + +AddRegExpCases( + /a*b/, + "xxx", + 0, + null ); + +AddRegExpCases( + /x\d\dy/, + "abcx45ysss235", + 3, + ["x45y"] ); + +AddRegExpCases( + /[^abc]def[abc]+/, + "abxdefbb", + 2, + ["xdefbb"] ); + +AddRegExpCases( + /(a*)baa/, + "ccdaaabaxaabaa", + 9, + ["aabaa", "aa"] ); + +AddRegExpCases( + /(a*)baa/, + "aabaa", + 0, + ["aabaa", "aa"] ); + +AddRegExpCases( + /q(a|b)*q/, + "xxqababqyy", + 2, + ["qababq", "b"] ); + +AddRegExpCases( + /(a(.|[^d])c)*/, + "adcaxc", + 0, + ["adcaxc", "axc", "x"] ); + +AddRegExpCases( + /(a*)b\1/, + "abaaaxaabaayy", + 0, + ["aba", "a"] ); + +AddRegExpCases( + /(a*)b\1/, + "abaaaxaabaayy", + 0, + ["aba", "a"] ); + +AddRegExpCases( + /(a*)b\1/, + "cccdaaabaxaabaayy", + 6, + ["aba", "a"] ); + +AddRegExpCases( + /(a*)b\1/, + "cccdaaabqxaabaayy", + 7, + ["b", ""] ); + +AddRegExpCases( + /"(.|[^"\\\\])*"/, + 'xx\"makudonarudo\"yy', + 2, + ["\"makudonarudo\"", "o"] ); + + AddRegExpCases( + /"(.|[^"\\\\])*"/, + "xx\"ma\"yy", + 2, + ["\"ma\"", "a"] ); + + test(); + + function AddRegExpCases( + regexp, pattern, index, matches_array ) { + +// prevent a runtime error + + if ( regexp.exec(pattern) == null || matches_array == null ) { + AddTestCase( + regexp + ".exec(" + pattern +")", + matches_array, + regexp.exec(pattern) ); + + return; + } + AddTestCase( + regexp + ".exec(" + pattern +").length", + matches_array.length, + regexp.exec(pattern).length ); + + AddTestCase( + regexp + ".exec(" + pattern +").index", + index, + regexp.exec(pattern).index ); + + AddTestCase( + regexp + ".exec(" + pattern +").input", + pattern, + regexp.exec(pattern).input ); + + AddTestCase( + regexp + ".exec(" + pattern +").toString()", + matches_array.toString(), + regexp.exec(pattern).toString() ); +/* + var limit = matches_array.length > regexp.exec(pattern).length + ? matches_array.length + : regexp.exec(pattern).length; + + for ( var matches = 0; matches < limit; matches++ ) { + AddTestCase( + regexp + ".exec(" + pattern +")[" + matches +"]", + matches_array[matches], + regexp.exec(pattern)[matches] ); + } +*/ + } diff --git a/js/src/tests/non262/RegExp/exec-lastIndex-ToInteger.js b/js/src/tests/non262/RegExp/exec-lastIndex-ToInteger.js new file mode 100644 index 0000000000..4505362d83 --- /dev/null +++ b/js/src/tests/non262/RegExp/exec-lastIndex-ToInteger.js @@ -0,0 +1,36 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * + * Author: Geoffrey Sneddon <geoffers+mozilla@gmail.com> + */ + +var BUGNUMBER = 646490; +var summary = + "RegExp.prototype.exec doesn't get the lastIndex and ToInteger() it for " + + "non-global regular expressions when it should"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var re = /./, called = 0; +re.lastIndex = {valueOf: function() { called++; return 0; }}; +re.exec("."); +re.lastIndex = {toString: function() { called++; return "0"; }}; +re.exec("."); +re.lastIndex = { + valueOf: function() { called++; return 0; }, + toString: function() { called--; } +}; +re.exec("."); +assertEq(called, 3, "FAIL, got " + called); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/RegExp/exec-lastIndex-negative.js b/js/src/tests/non262/RegExp/exec-lastIndex-negative.js new file mode 100644 index 0000000000..18eb2ab9d9 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/exec.js b/js/src/tests/non262/RegExp/exec.js new file mode 100644 index 0000000000..4284b6e014 --- /dev/null +++ b/js/src/tests/non262/RegExp/exec.js @@ -0,0 +1,240 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var BUGNUMBER = 646490; +var summary = + "RegExp.prototype.exec doesn't get the lastIndex and ToInteger() it for " + + "non-global regular expressions when it should"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function expectThrowTypeError(fun) +{ + try + { + var r = fun(); + throw new Error("didn't throw TypeError, returned " + r); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "didn't throw TypeError, got: " + e); + } +} + +function checkExec(description, regex, args, obj) +{ + var lastIndex = obj.lastIndex; + var index = obj.index; + var input = obj.input; + var indexArray = obj.indexArray; + + var res = regex.exec.apply(regex, args); + + assertEq(Array.isArray(res), true, description + ": not an array"); + assertEq(regex.lastIndex, lastIndex, description + ": wrong lastIndex"); + assertEq(res.index, index, description + ": wrong index"); + assertEq(res.input, input, description + ": wrong input"); + assertEq(res.length, indexArray.length, description + ": wrong length"); + for (var i = 0, sz = indexArray.length; i < sz; i++) + assertEq(res[i], indexArray[i], description + " " + i + ": wrong index value"); +} + +var exec = RegExp.prototype.exec; +var r, res, called, obj; + +/* 1. Let R be this RegExp object. */ +expectThrowTypeError(function() { exec.call(null); }); +expectThrowTypeError(function() { exec.call(""); }); +expectThrowTypeError(function() { exec.call(5); }); +expectThrowTypeError(function() { exec.call({}); }); +expectThrowTypeError(function() { exec.call([]); }); +expectThrowTypeError(function() { exec.call(); }); +expectThrowTypeError(function() { exec.call(true); }); +expectThrowTypeError(function() { exec.call(Object.create(RegExp.prototype)); }); +expectThrowTypeError(function() { exec.call(Object.create(/a/)); }); + + +/* 2. Let S be the value of ToString(string). */ +called = false; +r = /a/; +assertEq(r.lastIndex, 0); + +checkExec("/a/", r, [{ toString: function() { called = true; return 'ba'; } }], + { lastIndex: 0, + index: 1, + input: "ba", + indexArray: ["a"] }); +assertEq(called, true); + +called = false; +try +{ + res = r.exec({ toString: null, valueOf: function() { called = true; throw 17; } }); + throw new Error("didn't throw"); +} +catch (e) +{ + assertEq(e, 17); +} + +assertEq(called, true); + +called = false; +obj = r.lastIndex = { valueOf: function() { assertEq(true, false, "shouldn't have been called"); } }; +try +{ + res = r.exec({ toString: null, valueOf: function() { assertEq(called, false); called = true; throw 17; } }); + throw new Error("didn't throw"); +} +catch (e) +{ + assertEq(e, 17); +} + +assertEq(called, true); +assertEq(r.lastIndex, obj); + +// We don't test lack of an argument because of RegExp statics non-standard +// behaviors overriding what really should happen for lack of an argument, sigh. + + +/* + * 3. Let length be the length of S. + * 4. Let lastIndex be the result of calling the [[Get]] internal method of R with argument "lastIndex". + * 5. Let i be the value of ToInteger(lastIndex). + */ +r = /b/; +r.lastIndex = { valueOf: {}, toString: {} }; +expectThrowTypeError(function() { r.exec("foopy"); }); +r.lastIndex = { valueOf: function() { throw new TypeError(); } }; +expectThrowTypeError(function() { r.exec("foopy"); }); + + +/* + * 6. Let global be the result of calling the [[Get]] internal method of R with argument "global". + * 7. If global is false, then let i = 0. + */ +obj = { valueOf: function() { return 5; } }; +r = /abc/; +r.lastIndex = obj; + +checkExec("/abc/ take one", r, ["abc-------abc"], + { lastIndex: obj, + index: 0, + input: "abc-------abc", + indexArray: ["abc"] }); + +checkExec("/abc/ take two", r, ["abc-------abc"], + { lastIndex: obj, + index: 0, + input: "abc-------abc", + indexArray: ["abc"] }); + + +/* + * 8. Let matchSucceeded be false. + * 9. Repeat, while matchSucceeded is false + * a. If i < 0 or i > length, then + * i. Call the [[Put]] internal method of R with arguments "lastIndex", 0, and true. + * ii. Return null. + * b. Call the [[Match]] internal method of R with arguments S and i. + * c. If [[Match]] returned failure, then + * i. Let i = i+1. + * d. else + * i. Let r be the State result of the call to [[Match]]. + * ii. Set matchSucceeded to true. + * e. Let i = i+1. + */ +r = /abc()?/; +r.lastIndex = -5; +checkExec("/abc()?/ with lastIndex -5", r, ["abc-------abc"], + { lastIndex: -5, + index: 0, + input: "abc-------abc", + indexArray: ["abc", undefined] }); + + +r = /abc/; +r.lastIndex = -17; +res = r.exec("cdefg"); +assertEq(res, null); +assertEq(r.lastIndex, -17); + +r = /abc/g; +r.lastIndex = -42; +res = r.exec("cdefg"); +assertEq(res, null); +assertEq(r.lastIndex, 0); + + +/* + * 10. Let e be r's endIndex value. + * 11. If global is true, + * a. Call the [[Put]] internal method of R with arguments "lastIndex", e, and true. + */ +r = /abc/g; +r.lastIndex = 17; +assertEq(r.exec("sdfs"), null); +assertEq(r.lastIndex, 0); + +r = /abc/g; +r.lastIndex = 2; +checkExec("/abc/g", r, ["00abc"], + { lastIndex: 5, + index: 2, + input: "00abc", + indexArray: ["abc"] }); + + + +r = /a(b)c/g; +r.lastIndex = 2; +checkExec("/a(b)c/g take two", r, ["00abcd"], + { lastIndex: 5, + index: 2, + input: "00abcd", + indexArray: ["abc", "b"] }); + + +/* + * 12. Let n be the length of r's captures array. (This is the same value as + * 15.10.2.1's NCapturingParens.) + * 13. Let A be a new array created as if by the expression new Array() where + * Array is the standard built-in constructor with that name. + * 14. Let matchIndex be the position of the matched substring within the + * complete String S. + * 15. Call the [[DefineOwnProperty]] internal method of A with arguments + * "index", Property Descriptor {[[Value]]: matchIndex, [[Writable]: true, + * [[Enumerable]]: true, [[Configurable]]: true}, and true. + * 16. Call the [[DefineOwnProperty]] internal method of A with arguments + * "input", Property Descriptor {[[Value]]: S, [[Writable]: true, + * [[Enumerable]]: true, [[Configurable]]: true}, and true. + * 17. Call the [[DefineOwnProperty]] internal method of A with arguments + * "length", Property Descriptor {[[Value]]: n + 1}, and true. + * 18. Let matchedSubstr be the matched substring (i.e. the portion of S + * between offset i inclusive and offset e exclusive). + * 19. Call the [[DefineOwnProperty]] internal method of A with arguments "0", + * Property Descriptor {[[Value]]: matchedSubstr, [[Writable]: true, + * [[Enumerable]]: true, [[Configurable]]: true}, and true. + * 20. For each integer i such that I > 0 and I ≤ n + * a. Let captureI be i th element of r's captures array. + * b. Call the [[DefineOwnProperty]] internal method of A with arguments + * ToString(i), Property Descriptor {[[Value]]: captureI, [[Writable]: + * true, [[Enumerable]]: true, [[Configurable]]: true}, and true. + * 21. Return A. + */ +// throughout, above (and in other tests) + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/RegExp/flag-accessors.js b/js/src/tests/non262/RegExp/flag-accessors.js new file mode 100644 index 0000000000..848b916c50 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/flags-param-handling.js b/js/src/tests/non262/RegExp/flags-param-handling.js new file mode 100644 index 0000000000..e47799601a --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/flags.js b/js/src/tests/non262/RegExp/flags.js new file mode 100644 index 0000000000..17435f7922 --- /dev/null +++ b/js/src/tests/non262/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}})), "dgimsuy"); + +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/non262/RegExp/getter-name.js b/js/src/tests/non262/RegExp/getter-name.js new file mode 100644 index 0000000000..d0a413dbc4 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/ignoreCase-multiple.js b/js/src/tests/non262/RegExp/ignoreCase-multiple.js new file mode 100644 index 0000000000..e52cf499b3 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/ignoreCase-non-latin1-to-latin1.js b/js/src/tests/non262/RegExp/ignoreCase-non-latin1-to-latin1.js new file mode 100644 index 0000000000..b534740454 --- /dev/null +++ b/js/src/tests/non262/RegExp/ignoreCase-non-latin1-to-latin1.js @@ -0,0 +1,118 @@ +var BUGNUMBER = 1338779; +var summary = "Non-Latin1 to Latin1 mapping in ignoreCase."; + +assertEq(/(\u039C)/.test("\xB5"), false); +assertEq(/(\u039C)+/.test("\xB5"), false); +assertEq(/(\u039C)/i.test("\xB5"), true); +assertEq(/(\u039C)+/i.test("\xB5"), true); +assertEq(/(\u039C)/u.test("\xB5"), false); +assertEq(/(\u039C)+/u.test("\xB5"), false); +assertEq(/(\u039C)/ui.test("\xB5"), true); +assertEq(/(\u039C)+/ui.test("\xB5"), true); + +assertEq(/(\xB5)/.test("\u039C"), false); +assertEq(/(\xB5)+/.test("\u039C"), false); +assertEq(/(\xB5)/i.test("\u039C"), true); +assertEq(/(\xB5)+/i.test("\u039C"), true); +assertEq(/(\xB5)/u.test("\u039C"), false); +assertEq(/(\xB5)+/u.test("\u039C"), false); +assertEq(/(\xB5)/ui.test("\u039C"), true); +assertEq(/(\xB5)+/ui.test("\u039C"), true); + + +assertEq(/(\u0178)/.test("\xFF"), false); +assertEq(/(\u0178)+/.test("\xFF"), false); +assertEq(/(\u0178)/i.test("\xFF"), true); +assertEq(/(\u0178)+/i.test("\xFF"), true); +assertEq(/(\u0178)/u.test("\xFF"), false); +assertEq(/(\u0178)+/u.test("\xFF"), false); +assertEq(/(\u0178)/ui.test("\xFF"), true); +assertEq(/(\u0178)+/ui.test("\xFF"), true); + +assertEq(/(\xFF)/.test("\u0178"), false); +assertEq(/(\xFF)+/.test("\u0178"), false); +assertEq(/(\xFF)/i.test("\u0178"), true); +assertEq(/(\xFF)+/i.test("\u0178"), true); +assertEq(/(\xFF)/u.test("\u0178"), false); +assertEq(/(\xFF)+/u.test("\u0178"), false); +assertEq(/(\xFF)/ui.test("\u0178"), true); +assertEq(/(\xFF)+/ui.test("\u0178"), true); + + +assertEq(/(\u017F)/.test("\x73"), false); +assertEq(/(\u017F)+/.test("\x73"), false); +assertEq(/(\u017F)/i.test("\x73"), false); +assertEq(/(\u017F)+/i.test("\x73"), false); +assertEq(/(\u017F)/u.test("\x73"), false); +assertEq(/(\u017F)+/u.test("\x73"), false); +assertEq(/(\u017F)/iu.test("\x73"), true); +assertEq(/(\u017F)+/iu.test("\x73"), true); + +assertEq(/(\x73)/.test("\u017F"), false); +assertEq(/(\x73)+/.test("\u017F"), false); +assertEq(/(\x73)/i.test("\u017F"), false); +assertEq(/(\x73)+/i.test("\u017F"), false); +assertEq(/(\x73)/u.test("\u017F"), false); +assertEq(/(\x73)+/u.test("\u017F"), false); +assertEq(/(\x73)/iu.test("\u017F"), true); +assertEq(/(\x73)+/iu.test("\u017F"), true); + + +assertEq(/(\u1E9E)/.test("\xDF"), false); +assertEq(/(\u1E9E)+/.test("\xDF"), false); +assertEq(/(\u1E9E)/i.test("\xDF"), false); +assertEq(/(\u1E9E)+/i.test("\xDF"), false); +assertEq(/(\u1E9E)/u.test("\xDF"), false); +assertEq(/(\u1E9E)+/u.test("\xDF"), false); +assertEq(/(\u1E9E)/iu.test("\xDF"), true); +assertEq(/(\u1E9E)+/iu.test("\xDF"), true); + +assertEq(/(\xDF)/.test("\u1E9E"), false); +assertEq(/(\xDF)+/.test("\u1E9E"), false); +assertEq(/(\xDF)/i.test("\u1E9E"), false); +assertEq(/(\xDF)+/i.test("\u1E9E"), false); +assertEq(/(\xDF)/u.test("\u1E9E"), false); +assertEq(/(\xDF)+/u.test("\u1E9E"), false); +assertEq(/(\xDF)/iu.test("\u1E9E"), true); +assertEq(/(\xDF)+/iu.test("\u1E9E"), true); + + +assertEq(/(\u212A)/.test("\x6B"), false); +assertEq(/(\u212A)+/.test("\x6B"), false); +assertEq(/(\u212A)/i.test("\x6B"), false); +assertEq(/(\u212A)+/i.test("\x6B"), false); +assertEq(/(\u212A)/u.test("\x6B"), false); +assertEq(/(\u212A)+/u.test("\x6B"), false); +assertEq(/(\u212A)/iu.test("\x6B"), true); +assertEq(/(\u212A)+/iu.test("\x6B"), true); + +assertEq(/(\x6B)/.test("\u212A"), false); +assertEq(/(\x6B)+/.test("\u212A"), false); +assertEq(/(\x6B)/i.test("\u212A"), false); +assertEq(/(\x6B)+/i.test("\u212A"), false); +assertEq(/(\x6B)/u.test("\u212A"), false); +assertEq(/(\x6B)+/u.test("\u212A"), false); +assertEq(/(\x6B)/iu.test("\u212A"), true); +assertEq(/(\x6B)+/iu.test("\u212A"), true); + + +assertEq(/(\u212B)/.test("\xE5"), false); +assertEq(/(\u212B)+/.test("\xE5"), false); +assertEq(/(\u212B)/i.test("\xE5"), false); +assertEq(/(\u212B)+/i.test("\xE5"), false); +assertEq(/(\u212B)/u.test("\xE5"), false); +assertEq(/(\u212B)+/u.test("\xE5"), false); +assertEq(/(\u212B)/iu.test("\xE5"), true); +assertEq(/(\u212B)+/iu.test("\xE5"), true); + +assertEq(/(\xE5)/.test("\u212B"), false); +assertEq(/(\xE5)+/.test("\u212B"), false); +assertEq(/(\xE5)/i.test("\u212B"), false); +assertEq(/(\xE5)+/i.test("\u212B"), false); +assertEq(/(\xE5)/u.test("\u212B"), false); +assertEq(/(\xE5)+/u.test("\u212B"), false); +assertEq(/(\xE5)/iu.test("\u212B"), true); +assertEq(/(\xE5)+/iu.test("\u212B"), true); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/instance-property-storage-introspection.js b/js/src/tests/non262/RegExp/instance-property-storage-introspection.js new file mode 100644 index 0000000000..998d25e2c0 --- /dev/null +++ b/js/src/tests/non262/RegExp/instance-property-storage-introspection.js @@ -0,0 +1,128 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var BUGNUMBER = 640072; +var summary = + "Represent /a/.{lastIndex,global,source,multiline,sticky,ignoreCase} with " + + "plain old data properties"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function checkDataProperty(obj, p, expect, msg) +{ + var d = Object.getOwnPropertyDescriptor(obj, p); + + assertEq(d.value, expect.value, msg + ": bad value for " + p); + assertEq(d.writable, expect.writable, msg + ": bad writable for " + p); + assertEq(d.enumerable, expect.enumerable, msg + ": bad enumerable for " + p); + assertEq(d.configurable, expect.configurable, msg + ": bad configurable for " + p); + + // Try redefining the property using its initial values: these should all be + // silent no-ops. + Object.defineProperty(obj, p, { value: expect.value }); + Object.defineProperty(obj, p, { writable: expect.writable }); + Object.defineProperty(obj, p, { enumerable: expect.enumerable }); + Object.defineProperty(obj, p, { configurable: expect.configurable }); + + var d2 = Object.getOwnPropertyDescriptor(obj, p); + assertEq(d.value, d2.value, msg + ": value changed on redefinition of " + p + "?"); + assertEq(d.writable, d2.writable, msg + ": writable changed on redefinition of " + p + "?"); + assertEq(d.enumerable, d2.enumerable, msg + ": enumerable changed on redefinition of " + p + "?"); + assertEq(d.configurable, d2.configurable, msg + ": configurable changed on redefinition of " + p + "?"); +} + + +// Check a bunch of "empty" regular expressions first. + +var choices = [{ msg: "new RegExp()", + get: function() { return new RegExp(); } }, + { msg: "/(?:)/", + get: Function("return /(?:)/;") }]; + +function checkRegExp(r, msg, lastIndex) +{ + var expect; + + expect = { value: lastIndex, enumerable: false, configurable: false, writable: true }; + checkDataProperty(r, "lastIndex", expect, msg); +} + +checkRegExp(new RegExp(), "new RegExp()", 0); +checkRegExp(/(?:)/, "/(?:)/", 0); +checkRegExp(Function("return /(?:)/;")(), 'Function("return /(?:)/;")()', 0); + +for (var i = 0; i < choices.length; i++) +{ + var choice = choices[i]; + var msg = choice.msg; + var r = choice.get(); + + checkRegExp(r, msg, 0); +} + +// Now test less generic regular expressions + +checkRegExp(/a/gim, "/a/gim", 0); + +var r; + +do +{ + r = /abcd/mg; + checkRegExp(r, "/abcd/mg initially", 0); + r.exec("abcdefg"); + checkRegExp(r, "/abcd/mg step 1", 4); + r.exec("abcdabcd"); + checkRegExp(r, "/abcd/mg step 2", 8); + r.exec("abcdabcd"); + checkRegExp(r, "/abcd/mg end", 0); + + r = /cde/ig; + checkRegExp(r, "/cde/ig initially", 0); + var obj = r.lastIndex = { valueOf: function() { return 2; } }; + checkRegExp(r, "/cde/ig after lastIndex", obj); + r.exec("aaacdef"); + checkRegExp(r, "/cde/ig after exec", 6); + Object.defineProperty(r, "lastIndex", { value: 3 }); + checkRegExp(r, "/cde/ig after define 3", 3); + Object.defineProperty(r, "lastIndex", { value: obj }); + checkRegExp(r, "/cde/ig after lastIndex", obj); + + + // Tricky bits of testing: make sure that redefining lastIndex doesn't change + // the slot where the lastIndex property is initially stored, even if + // the redefinition also changes writability. + r = /a/g; + checkRegExp(r, "/a/g initially", 0); + Object.defineProperty(r, "lastIndex", { value: 2 }); + r.exec("aabbbba"); + checkRegExp(r, "/a/g after first exec", 7); + assertEq(r.lastIndex, 7); + r.lastIndex = 2; + checkRegExp(r, "/a/g after assign", 2); + r.exec("aabbbba"); + assertEq(r.lastIndex, 7); // check in reverse order + checkRegExp(r, "/a/g after second exec", 7); + + r = /c/g; + r.lastIndex = 2; + checkRegExp(r, "/c/g initially", 2); + Object.defineProperty(r, "lastIndex", { writable: false }); + assertEq(Object.getOwnPropertyDescriptor(r, "lastIndex").writable, false); + try { r.exec("aabbbba"); } catch (e) { /* swallow error if thrown */ } + assertEq(Object.getOwnPropertyDescriptor(r, "lastIndex").writable, false); +} +while (Math.random() > 17); // fake loop to discourage RegExp object caching + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/non262/RegExp/lastIndex-exec.js b/js/src/tests/non262/RegExp/lastIndex-exec.js new file mode 100644 index 0000000000..f42facbe34 --- /dev/null +++ b/js/src/tests/non262/RegExp/lastIndex-exec.js @@ -0,0 +1,80 @@ +// RegExp.prototype.exec: Test lastIndex changes for ES2017. + +// Test various combinations of: +// - Pattern matches or doesn't match +// - Global and/or sticky flag is set. +// - lastIndex exceeds the input string length +// - lastIndex is +-0 +const testCases = [ + { regExp: /a/, lastIndex: 0, input: "a", result: 0 }, + { regExp: /a/g, lastIndex: 0, input: "a", result: 1 }, + { regExp: /a/y, lastIndex: 0, input: "a", result: 1 }, + + { regExp: /a/, lastIndex: 0, input: "b", result: 0 }, + { regExp: /a/g, lastIndex: 0, input: "b", result: 0 }, + { regExp: /a/y, lastIndex: 0, input: "b", result: 0 }, + + { regExp: /a/, lastIndex: -0, input: "a", result: -0 }, + { regExp: /a/g, lastIndex: -0, input: "a", result: 1 }, + { regExp: /a/y, lastIndex: -0, input: "a", result: 1 }, + + { regExp: /a/, lastIndex: -0, input: "b", result: -0 }, + { regExp: /a/g, lastIndex: -0, input: "b", result: 0 }, + { regExp: /a/y, lastIndex: -0, input: "b", result: 0 }, + + { regExp: /a/, lastIndex: -1, input: "a", result: -1 }, + { regExp: /a/g, lastIndex: -1, input: "a", result: 1 }, + { regExp: /a/y, lastIndex: -1, input: "a", result: 1 }, + + { regExp: /a/, lastIndex: -1, input: "b", result: -1 }, + { regExp: /a/g, lastIndex: -1, input: "b", result: 0 }, + { regExp: /a/y, lastIndex: -1, input: "b", result: 0 }, + + { regExp: /a/, lastIndex: 100, input: "a", result: 100 }, + { regExp: /a/g, lastIndex: 100, input: "a", result: 0 }, + { regExp: /a/y, lastIndex: 100, input: "a", result: 0 }, +]; + +// Basic test. +for (let {regExp, lastIndex, input, result} of testCases) { + let re = new RegExp(regExp); + re.lastIndex = lastIndex; + re.exec(input); + assertEq(re.lastIndex, result); +} + +// Test when lastIndex is non-writable. +for (let {regExp, lastIndex, input} of testCases) { + let re = new RegExp(regExp); + Object.defineProperty(re, "lastIndex", { value: lastIndex, writable: false }); + if (re.global || re.sticky) { + assertThrowsInstanceOf(() => re.exec(input), TypeError); + } else { + re.exec(input); + } + assertEq(re.lastIndex, lastIndex); +} + +// Test when lastIndex is changed to non-writable as a side-effect. +for (let {regExp, lastIndex, input} of testCases) { + let re = new RegExp(regExp); + let called = false; + re.lastIndex = { + valueOf() { + assertEq(called, false); + called = true; + Object.defineProperty(re, "lastIndex", { value: 9000, writable: false }); + return lastIndex; + } + }; + if (re.global || re.sticky) { + assertThrowsInstanceOf(() => re.exec(input), TypeError); + } else { + re.exec(input); + } + assertEq(re.lastIndex, 9000); + assertEq(called, true); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/lastIndex-match-or-replace.js b/js/src/tests/non262/RegExp/lastIndex-match-or-replace.js new file mode 100644 index 0000000000..8d7703c459 --- /dev/null +++ b/js/src/tests/non262/RegExp/lastIndex-match-or-replace.js @@ -0,0 +1,123 @@ +// RegExp.prototype[Symbol.match, Symbol.replace]: Test lastIndex changes for ES2017. + +// RegExp-like class to test the RegExp method slow paths. +class DuckRegExp extends RegExp { + constructor(pattern, flags) { + return Object.create(DuckRegExp.prototype, { + regExp: { + value: new RegExp(pattern, flags) + }, + lastIndex: { + value: 0, writable: true, enumerable: false, configurable: false + } + }); + } + + exec(...args) { + this.regExp.lastIndex = this.lastIndex; + try { + return this.regExp.exec(...args); + } finally { + if (this.global || this.sticky) + this.lastIndex = this.regExp.lastIndex; + } + } + + get source() { return this.regExp.source; } + + get flags() { return this.regExp.flags; } + get global() { return this.regExp.global; } + get ignoreCase() { return this.regExp.ignoreCase; } + get multiline() { return this.regExp.multiline; } + get sticky() { return this.regExp.sticky; } + get unicode() { return this.regExp.unicode; } +} + +// Test various combinations of: +// - Pattern matches or doesn't match +// - Global and/or sticky flag is set. +// - lastIndex exceeds the input string length +// - lastIndex is +-0 +const testCases = [ + { regExp: /a/, lastIndex: 0, input: "a", result: 0 }, + { regExp: /a/g, lastIndex: 0, input: "a", result: 0 }, + { regExp: /a/y, lastIndex: 0, input: "a", result: 1 }, + + { regExp: /a/, lastIndex: 0, input: "b", result: 0 }, + { regExp: /a/g, lastIndex: 0, input: "b", result: 0 }, + { regExp: /a/y, lastIndex: 0, input: "b", result: 0 }, + + { regExp: /a/, lastIndex: -0, input: "a", result: -0 }, + { regExp: /a/g, lastIndex: -0, input: "a", result: 0 }, + { regExp: /a/y, lastIndex: -0, input: "a", result: 1 }, + + { regExp: /a/, lastIndex: -0, input: "b", result: -0 }, + { regExp: /a/g, lastIndex: -0, input: "b", result: 0 }, + { regExp: /a/y, lastIndex: -0, input: "b", result: 0 }, + + { regExp: /a/, lastIndex: -1, input: "a", result: -1 }, + { regExp: /a/g, lastIndex: -1, input: "a", result: 0 }, + { regExp: /a/y, lastIndex: -1, input: "a", result: 1 }, + + { regExp: /a/, lastIndex: -1, input: "b", result: -1 }, + { regExp: /a/g, lastIndex: -1, input: "b", result: 0 }, + { regExp: /a/y, lastIndex: -1, input: "b", result: 0 }, + + { regExp: /a/, lastIndex: 100, input: "a", result: 100 }, + { regExp: /a/g, lastIndex: 100, input: "a", result: 0 }, + { regExp: /a/y, lastIndex: 100, input: "a", result: 0 }, +]; + +for (let method of [RegExp.prototype[Symbol.match], RegExp.prototype[Symbol.replace]]) { + for (let Constructor of [RegExp, DuckRegExp]) { + // Basic test. + for (let {regExp, lastIndex, input, result} of testCases) { + let re = new Constructor(regExp); + re.lastIndex = lastIndex; + Reflect.apply(method, re, [input]); + assertEq(re.lastIndex, result); + } + + // Test when lastIndex is non-writable. + for (let {regExp, lastIndex, input} of testCases) { + let re = new Constructor(regExp); + Object.defineProperty(re, "lastIndex", { value: lastIndex, writable: false }); + if (re.global || re.sticky) { + assertThrowsInstanceOf(() => Reflect.apply(method, re, [input]), TypeError); + } else { + Reflect.apply(method, re, [input]); + } + assertEq(re.lastIndex, lastIndex); + } + + // Test when lastIndex is changed to non-writable as a side-effect. + for (let {regExp, lastIndex, input, result} of testCases) { + let re = new Constructor(regExp); + let called = false; + re.lastIndex = { + valueOf() { + assertEq(called, false); + called = true; + Object.defineProperty(re, "lastIndex", { value: 9000, writable: false }); + return lastIndex; + } + }; + if (re.sticky) { + assertThrowsInstanceOf(() => Reflect.apply(method, re, [input]), TypeError); + assertEq(called, true); + assertEq(re.lastIndex, 9000); + } else if (re.global) { + Reflect.apply(method, re, [input]); + assertEq(called, false); + assertEq(re.lastIndex, result); + } else { + Reflect.apply(method, re, [input]); + assertEq(called, true); + assertEq(re.lastIndex, 9000); + } + } + } +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/lastIndex-nonwritable.js b/js/src/tests/non262/RegExp/lastIndex-nonwritable.js new file mode 100644 index 0000000000..3c867f9538 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/lastIndex-search.js b/js/src/tests/non262/RegExp/lastIndex-search.js new file mode 100644 index 0000000000..5953b3a885 --- /dev/null +++ b/js/src/tests/non262/RegExp/lastIndex-search.js @@ -0,0 +1,118 @@ +// RegExp.prototype[Symbol.search]: Test lastIndex changes for ES2017. + +// RegExp-like class to test the RegExp method slow paths. +class DuckRegExp extends RegExp { + constructor(pattern, flags) { + return Object.create(DuckRegExp.prototype, { + regExp: { + value: new RegExp(pattern, flags) + }, + lastIndex: { + value: 0, writable: true, enumerable: false, configurable: false + } + }); + } + + exec(...args) { + this.regExp.lastIndex = this.lastIndex; + try { + return this.regExp.exec(...args); + } finally { + if (this.global || this.sticky) + this.lastIndex = this.regExp.lastIndex; + } + } + + get source() { return this.regExp.source; } + + get global() { return this.regExp.global; } + get ignoreCase() { return this.regExp.ignoreCase; } + get multiline() { return this.regExp.multiline; } + get sticky() { return this.regExp.sticky; } + get unicode() { return this.regExp.unicode; } +} + +// Test various combinations of: +// - Pattern matches or doesn't match +// - Global and/or sticky flag is set. +// - lastIndex exceeds the input string length +// - lastIndex is +-0 +const testCasesNotPositiveZero = [ + { regExp: /a/, lastIndex: -1, input: "a" }, + { regExp: /a/g, lastIndex: -1, input: "a" }, + { regExp: /a/y, lastIndex: -1, input: "a" }, + + { regExp: /a/, lastIndex: 100, input: "a" }, + { regExp: /a/g, lastIndex: 100, input: "a" }, + { regExp: /a/y, lastIndex: 100, input: "a" }, + + { regExp: /a/, lastIndex: -1, input: "b" }, + { regExp: /a/g, lastIndex: -1, input: "b" }, + { regExp: /a/y, lastIndex: -1, input: "b" }, + + { regExp: /a/, lastIndex: -0, input: "a" }, + { regExp: /a/g, lastIndex: -0, input: "a" }, + { regExp: /a/y, lastIndex: -0, input: "a" }, + + { regExp: /a/, lastIndex: -0, input: "b" }, + { regExp: /a/g, lastIndex: -0, input: "b" }, + { regExp: /a/y, lastIndex: -0, input: "b" }, +]; + +const testCasesPositiveZero = [ + { regExp: /a/, lastIndex: 0, input: "a" }, + { regExp: /a/g, lastIndex: 0, input: "a" }, + { regExp: /a/y, lastIndex: 0, input: "a" }, + + { regExp: /a/, lastIndex: 0, input: "b" }, + { regExp: /a/g, lastIndex: 0, input: "b" }, + { regExp: /a/y, lastIndex: 0, input: "b" }, +]; + +const testCases = [...testCasesNotPositiveZero, ...testCasesPositiveZero]; + +for (let Constructor of [RegExp, DuckRegExp]) { + // Basic test. + for (let {regExp, lastIndex, input} of testCases) { + let re = new Constructor(regExp); + re.lastIndex = lastIndex; + re[Symbol.search](input); + assertEq(re.lastIndex, lastIndex); + } + + // Test when lastIndex is non-writable and not positive zero. + for (let {regExp, lastIndex, input} of testCasesNotPositiveZero) { + let re = new Constructor(regExp); + Object.defineProperty(re, "lastIndex", { value: lastIndex, writable: false }); + assertThrowsInstanceOf(() => re[Symbol.search](input), TypeError); + assertEq(re.lastIndex, lastIndex); + } + + // Test when lastIndex is non-writable and positive zero. + for (let {regExp, lastIndex, input} of testCasesPositiveZero) { + let re = new Constructor(regExp); + Object.defineProperty(re, "lastIndex", { value: lastIndex, writable: false }); + if (re.global || re.sticky) { + assertThrowsInstanceOf(() => re[Symbol.search](input), TypeError); + } else { + re[Symbol.search](input); + } + assertEq(re.lastIndex, lastIndex); + } + + // Test lastIndex isn't converted to a number. + for (let {regExp, lastIndex, input} of testCases) { + let re = new RegExp(regExp); + let badIndex = { + valueOf() { + assertEq(false, true); + } + }; + re.lastIndex = badIndex; + re[Symbol.search](input); + assertEq(re.lastIndex, badIndex); + } +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/match-local-tolength-recompilation.js b/js/src/tests/non262/RegExp/match-local-tolength-recompilation.js new file mode 100644 index 0000000000..9a992f81f4 --- /dev/null +++ b/js/src/tests/non262/RegExp/match-local-tolength-recompilation.js @@ -0,0 +1,75 @@ +// Side-effects when calling ToLength(regExp.lastIndex) in +// RegExp.prototype[@@match] for non-global RegExp can recompile the RegExp. + +for (var flag of ["", "y"]) { + var regExp = new RegExp("a", flag); + + regExp.lastIndex = { + valueOf() { + regExp.compile("b"); + return 0; + } + }; + + var result = regExp[Symbol.match]("b"); + assertEq(result !== null, true); +} + +// Recompilation modifies flag: +// Case 1: Adds global flag, validate by checking lastIndex. +var regExp = new RegExp("a", ""); +regExp.lastIndex = { + valueOf() { + // |regExp| is now in global mode, RegExpBuiltinExec should update the + // lastIndex property to reflect last match. + regExp.compile("a", "g"); + return 0; + } +}; +regExp[Symbol.match]("a"); +assertEq(regExp.lastIndex, 1); + +// Case 2: Removes sticky flag with match, validate by checking lastIndex. +var regExp = new RegExp("a", "y"); +regExp.lastIndex = { + valueOf() { + // |regExp| is no longer sticky, RegExpBuiltinExec shouldn't modify the + // lastIndex property. + regExp.compile("a", ""); + regExp.lastIndex = 9000; + return 0; + } +}; +regExp[Symbol.match]("a"); +assertEq(regExp.lastIndex, 9000); + +// Case 3.a: Removes sticky flag without match, validate by checking lastIndex. +var regExp = new RegExp("a", "y"); +regExp.lastIndex = { + valueOf() { + // |regExp| is no longer sticky, RegExpBuiltinExec shouldn't modify the + // lastIndex property. + regExp.compile("b", ""); + regExp.lastIndex = 9001; + return 0; + } +}; +regExp[Symbol.match]("a"); +assertEq(regExp.lastIndex, 9001); + +// Case 3.b: Removes sticky flag without match, validate by checking lastIndex. +var regExp = new RegExp("a", "y"); +regExp.lastIndex = { + valueOf() { + // |regExp| is no longer sticky, RegExpBuiltinExec shouldn't modify the + // lastIndex property. + regExp.compile("b", ""); + regExp.lastIndex = 9002; + return 10000; + } +}; +regExp[Symbol.match]("a"); +assertEq(regExp.lastIndex, 9002); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/match-this.js b/js/src/tests/non262/RegExp/match-this.js new file mode 100644 index 0000000000..ee05462f26 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/match-trace.js b/js/src/tests/non262/RegExp/match-trace.js new file mode 100644 index 0000000000..507d3f661a --- /dev/null +++ b/js/src/tests/non262/RegExp/match-trace.js @@ -0,0 +1,142 @@ +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 flags() { + log += "get:flags,"; + var flags = ""; + if (global) flags += "g"; + if (unicode) flags += "u"; + return flags; + }, + 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"; + 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:flags," + + "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:flags," + + "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:flags," + + "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:flags," + + "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:flags," + + "get:exec,call:exec,"); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/match.js b/js/src/tests/non262/RegExp/match.js new file mode 100644 index 0000000000..06308b2d67 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/multiline-001.js b/js/src/tests/non262/RegExp/multiline-001.js new file mode 100644 index 0000000000..43614d91e7 --- /dev/null +++ b/js/src/tests/non262/RegExp/multiline-001.js @@ -0,0 +1,67 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + * File Name: RegExp/multiline-001.js + * ECMA Section: + * Description: Based on ECMA 2 Draft 7 February 1999 + * + * Date: 19 February 1999 + */ + +var SECTION = "RegExp/multiline-001"; +var TITLE = "RegExp: multiline flag"; +var BUGNUMBER="343901"; + +printBugNumber(BUGNUMBER); + +var woodpeckers = "ivory-billed\ndowny\nhairy\nacorn\nyellow-bellied sapsucker\n" + + "northern flicker\npileated\n"; + +AddRegExpCases( /.*[y]$/m, woodpeckers, woodpeckers.indexOf("downy"), ["downy"] ); + +AddRegExpCases( /.*[d]$/m, woodpeckers, woodpeckers.indexOf("ivory-billed"), ["ivory-billed"] ); + +test(); + + +function AddRegExpCases +( regexp, pattern, index, matches_array ) { + + // prevent a runtime error + + if ( regexp.exec(pattern) == null || matches_array == null ) { + AddTestCase( + regexp + ".exec(" + pattern +")", + matches_array, + regexp.exec(pattern) ); + + return; + } + + AddTestCase( + regexp.toString() + ".exec(" + pattern +").length", + matches_array.length, + regexp.exec(pattern).length ); + + AddTestCase( + regexp.toString() + ".exec(" + pattern +").index", + index, + regexp.exec(pattern).index ); + + AddTestCase( + regexp + ".exec(" + pattern +").input", + pattern, + regexp.exec(pattern).input ); + + + for ( var matches = 0; matches < matches_array.length; matches++ ) { + AddTestCase( + regexp + ".exec(" + pattern +")[" + matches +"]", + matches_array[matches], + regexp.exec(pattern)[matches] ); + } +} diff --git a/js/src/tests/non262/RegExp/octal-001.js b/js/src/tests/non262/RegExp/octal-001.js new file mode 100644 index 0000000000..cde12d807d --- /dev/null +++ b/js/src/tests/non262/RegExp/octal-001.js @@ -0,0 +1,77 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + * File Name: RegExp/octal-001.js + * ECMA Section: 15.7.1 + * Description: Based on ECMA 2 Draft 7 February 1999 + * Simple test cases for matching OctalEscapeSequences. + * Author: christine@netscape.com + * Date: 19 February 1999 + */ +var SECTION = "RegExp/octal-001.js"; +var TITLE = "RegExp patterns that contain OctalEscapeSequences"; +var BUGNUMBER="http://scopus/bugsplat/show_bug.cgi?id=346196"; + +printBugNumber(BUGNUMBER); + + +// backreference +AddRegExpCases( + /(.)\1/, + "/(.)\\1/", + "HI!!", + "HI!", + 2, + ["!!", "!"] ); + +test(); + +function AddRegExpCases( + regexp, str_regexp, pattern, str_pattern, index, matches_array ) { + + // prevent a runtime error + + if ( regexp.exec(pattern) == null || matches_array == null ) { + AddTestCase( + regexp + ".exec(" + str_pattern +")", + matches_array, + regexp.exec(pattern) ); + + return; + } + AddTestCase( + str_regexp + ".exec(" + str_pattern +").length", + matches_array.length, + regexp.exec(pattern).length ); + + AddTestCase( + str_regexp + ".exec(" + str_pattern +").index", + index, + regexp.exec(pattern).index ); + + AddTestCase( + str_regexp + ".exec(" + str_pattern +").input", + pattern, + regexp.exec(pattern).input ); + + AddTestCase( + str_regexp + ".exec(" + str_pattern +").toString()", + matches_array.toString(), + regexp.exec(pattern).toString() ); +/* + var limit = matches_array.length > regexp.exec(pattern).length + ? matches_array.length + : regexp.exec(pattern).length; + + for ( var matches = 0; matches < limit; matches++ ) { + AddTestCase( + str_regexp + ".exec(" + str_pattern +")[" + matches +"]", + matches_array[matches], + regexp.exec(pattern)[matches] ); + } +*/ +} diff --git a/js/src/tests/non262/RegExp/octal-002.js b/js/src/tests/non262/RegExp/octal-002.js new file mode 100644 index 0000000000..6761d4ae6d --- /dev/null +++ b/js/src/tests/non262/RegExp/octal-002.js @@ -0,0 +1,92 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + * File Name: RegExp/octal-002.js + * ECMA Section: 15.7.1 + * Description: Based on ECMA 2 Draft 7 February 1999 + * Simple test cases for matching OctalEscapeSequences. + * Author: christine@netscape.com + * Date: 19 February 1999 + */ +var SECTION = "RegExp/octal-002.js"; +var TITLE = "RegExp patterns that contain OctalEscapeSequences"; +var BUGNUMBER="http://scopus/bugsplat/show_bug.cgi?id=346189"; + +printBugNumber(BUGNUMBER); + +// backreference +AddRegExpCases( + /(.)(.)(.)(.)(.)(.)(.)(.)\8/, + "/(.)(.)(.)(.)(.)(.)(.)(.)\\8", + "aabbccaaabbbccc", + "aabbccaaabbbccc", + 0, + ["aabbccaaa", "a", "a", "b", "b", "c", "c", "a", "a"] ); + +AddRegExpCases( + /(.)(.)(.)(.)(.)(.)(.)(.)(.)\9/, + "/(.)(.)(.)(.)(.)(.)(.)(.)\\9", + "aabbccaabbcc", + "aabbccaabbcc", + 0, + ["aabbccaabb", "a", "a", "b", "b", "c", "c", "a", "a", "b"] ); + +AddRegExpCases( + /(.)(.)(.)(.)(.)(.)(.)(.)(.)\8/, + "/(.)(.)(.)(.)(.)(.)(.)(.)(.)\\8", + "aabbccaababcc", + "aabbccaababcc", + 0, + ["aabbccaaba", "a", "a", "b", "b", "c", "c", "a", "a", "b"] ); + +test(); + +function AddRegExpCases( + regexp, str_regexp, pattern, str_pattern, index, matches_array ) { + + // prevent a runtime error + + if ( regexp.exec(pattern) == null || matches_array == null ) { + AddTestCase( + regexp + ".exec(" + str_pattern +")", + matches_array, + regexp.exec(pattern) ); + + return; + } + AddTestCase( + str_regexp + ".exec(" + str_pattern +").length", + matches_array.length, + regexp.exec(pattern).length ); + + AddTestCase( + str_regexp + ".exec(" + str_pattern +").index", + index, + regexp.exec(pattern).index ); + + AddTestCase( + str_regexp + ".exec(" + str_pattern +").input", + pattern, + regexp.exec(pattern).input ); + + AddTestCase( + str_regexp + ".exec(" + str_pattern +").toString()", + matches_array.toString(), + regexp.exec(pattern).toString() ); +/* + var limit = matches_array.length > regexp.exec(pattern).length + ? matches_array.length + : regexp.exec(pattern).length; + + for ( var matches = 0; matches < limit; matches++ ) { + AddTestCase( + str_regexp + ".exec(" + str_pattern +")[" + matches +"]", + matches_array[matches], + regexp.exec(pattern)[matches] ); + } +*/ +} diff --git a/js/src/tests/non262/RegExp/octal-003.js b/js/src/tests/non262/RegExp/octal-003.js new file mode 100644 index 0000000000..58052b2c25 --- /dev/null +++ b/js/src/tests/non262/RegExp/octal-003.js @@ -0,0 +1,86 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + * File Name: RegExp/octal-003.js + * ECMA Section: 15.7.1 + * Description: Based on ECMA 2 Draft 7 February 1999 + * Simple test cases for matching OctalEscapeSequences. + * Author: christine@netscape.com + * Date: 19 February 1999 + * + * Revised: 02 August 2002 + * Author: pschwartau@netscape.com + * + * WHY: the original test expected the regexp /.\011/ + * to match 'a' + String.fromCharCode(0) + '11' + * + * This is incorrect: the string is a 4-character string consisting of + * the characters <'a'>, <nul>, <'1'>, <'1'>. By contrast, the \011 in the + * regexp should be parsed as a single token: it is the octal escape sequence + * for the horizontal tab character '\t' === '\u0009' === '\x09' === '\011'. + * + * So the regexp consists of 2 characters: <any-character>, <'\t'>. + * There is no match between the regexp and the string. + * + * See the testcase non262/RegExp/octal-002.js for an elaboration. + * + */ +var SECTION = "RegExp/octal-003.js"; +var TITLE = "RegExp patterns that contain OctalEscapeSequences"; +var BUGNUMBER="http://scopus/bugsplat/show_bug.cgi?id=346132"; + +printBugNumber(BUGNUMBER); + +AddRegExpCases( /.\011/, "/\\011/", "a" + String.fromCharCode(0) + "11", "a\\011", 0, null ); + +test(); + +function AddRegExpCases( + regexp, str_regexp, pattern, str_pattern, index, matches_array ) { + + // prevent a runtime error + + if ( regexp.exec(pattern) == null || matches_array == null ) { + AddTestCase( + regexp + ".exec(" + str_pattern +")", + matches_array, + regexp.exec(pattern) ); + + return; + } + AddTestCase( + str_regexp + ".exec(" + str_pattern +").length", + matches_array.length, + regexp.exec(pattern).length ); + + AddTestCase( + str_regexp + ".exec(" + str_pattern +").index", + index, + regexp.exec(pattern).index ); + + AddTestCase( + str_regexp + ".exec(" + str_pattern +").input", + escape(pattern), + escape(regexp.exec(pattern).input) ); + + AddTestCase( + str_regexp + ".exec(" + str_pattern +").toString()", + matches_array.toString(), + escape(regexp.exec(pattern).toString()) ); + + var limit = matches_array.length > regexp.exec(pattern).length + ? matches_array.length + : regexp.exec(pattern).length; + + for ( var matches = 0; matches < limit; matches++ ) { + AddTestCase( + str_regexp + ".exec(" + str_pattern +")[" + matches +"]", + matches_array[matches], + escape(regexp.exec(pattern)[matches]) ); + } + +} diff --git a/js/src/tests/non262/RegExp/oom-in-construction.js b/js/src/tests/non262/RegExp/oom-in-construction.js new file mode 100644 index 0000000000..f09cca81b1 --- /dev/null +++ b/js/src/tests/non262/RegExp/oom-in-construction.js @@ -0,0 +1,17 @@ +// |reftest| skip-if(!this.hasOwnProperty("oomTest")) +var BUGNUMBER = 1471371; +var summary = 'Handle OOM in RegExp'; + +printBugNumber(BUGNUMBER); +printStatus(summary); + +oomTest(function () { + for (var i = 0; i < 10; ++i) { + try { + RegExp("", "gimuyz"); + } catch { } + } +}); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/perlstress-001.js b/js/src/tests/non262/RegExp/perlstress-001.js new file mode 100644 index 0000000000..c073a8f733 --- /dev/null +++ b/js/src/tests/non262/RegExp/perlstress-001.js @@ -0,0 +1,3194 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 2002-07-07 + * SUMMARY: Testing JS RegExp engine against Perl 5 RegExp engine. + * Adjust cnLBOUND, cnUBOUND below to restrict which sections are tested. + * + * This test was created by running various patterns and strings through the + * Perl 5 RegExp engine. We saved the results below to test the JS engine. + * + * NOTE: ECMA/JS and Perl do differ on certain points. We have either commented + * out such sections altogether, or modified them to fit what we expect from JS. + * + * EXAMPLES: + * + * - In JS, regexp captures (/(a) etc./) must hold |undefined| if not used. + * See http://bugzilla.mozilla.org/show_bug.cgi?id=123437. + * By contrast, in Perl, unmatched captures hold the empty string. + * We have modified such sections accordingly. Example: + + pattern = /^([^a-z])|(\^)$/; + string = '.'; + actualmatch = string.match(pattern); + //expectedmatch = Array('.', '.', ''); <<<--- Perl + expectedmatch = Array('.', '.', undefined); <<<--- JS + addThis(); + + + * - In JS, you can't refer to a capture before it's encountered & completed + * + * - Perl supports ] & ^] inside a [], ECMA does not + * + * - ECMA does support (?: (?= and (?! operators, but doesn't support (?< etc. + * + * - ECMA doesn't support (?imsx or (?-imsx + * + * - ECMA doesn't support (?(condition) + * + * - Perl has \Z has end-of-line, ECMA doesn't + * + * - In ECMA, ^ matches only the empty string before the first character + * + * - In ECMA, $ matches only the empty string at end of input (unless multiline) + * + * - ECMA spec says that each atom in a range must be a single character + * + * - ECMA doesn't support \A + * + * - ECMA doesn't have rules for [: + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 85721; +var summary = 'Testing regular expression edge cases'; +var cnSingleSpace = ' '; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); +var cnLBOUND = 1; +var cnUBOUND = 1000; + + +status = inSection(1); +pattern = /abc/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(2); +pattern = /abc/; +string = 'xabcy'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(3); +pattern = /abc/; +string = 'ababc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(4); +pattern = /ab*c/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(5); +pattern = /ab*bc/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(6); +pattern = /ab*bc/; +string = 'abbc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abbc'); +addThis(); + +status = inSection(7); +pattern = /ab*bc/; +string = 'abbbbc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abbbbc'); +addThis(); + +status = inSection(8); +pattern = /.{1}/; +string = 'abbbbc'; +actualmatch = string.match(pattern); +expectedmatch = Array('a'); +addThis(); + +status = inSection(9); +pattern = /.{3,4}/; +string = 'abbbbc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abbb'); +addThis(); + +status = inSection(10); +pattern = /ab{0,}bc/; +string = 'abbbbc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abbbbc'); +addThis(); + +status = inSection(11); +pattern = /ab+bc/; +string = 'abbc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abbc'); +addThis(); + +status = inSection(12); +pattern = /ab+bc/; +string = 'abbbbc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abbbbc'); +addThis(); + +status = inSection(13); +pattern = /ab{1,}bc/; +string = 'abbbbc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abbbbc'); +addThis(); + +status = inSection(14); +pattern = /ab{1,3}bc/; +string = 'abbbbc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abbbbc'); +addThis(); + +status = inSection(15); +pattern = /ab{3,4}bc/; +string = 'abbbbc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abbbbc'); +addThis(); + +status = inSection(16); +pattern = /ab?bc/; +string = 'abbc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abbc'); +addThis(); + +status = inSection(17); +pattern = /ab?bc/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(18); +pattern = /ab{0,1}bc/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(19); +pattern = /ab?c/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(20); +pattern = /ab{0,1}c/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(21); +pattern = /^abc$/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(22); +pattern = /^abc/; +string = 'abcc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(23); +pattern = /abc$/; +string = 'aabc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(24); +pattern = /^/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array(''); +addThis(); + +status = inSection(25); +pattern = /$/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array(''); +addThis(); + +status = inSection(26); +pattern = /a.c/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(27); +pattern = /a.c/; +string = 'axc'; +actualmatch = string.match(pattern); +expectedmatch = Array('axc'); +addThis(); + +status = inSection(28); +pattern = /a.*c/; +string = 'axyzc'; +actualmatch = string.match(pattern); +expectedmatch = Array('axyzc'); +addThis(); + +status = inSection(29); +pattern = /a[bc]d/; +string = 'abd'; +actualmatch = string.match(pattern); +expectedmatch = Array('abd'); +addThis(); + +status = inSection(30); +pattern = /a[b-d]e/; +string = 'ace'; +actualmatch = string.match(pattern); +expectedmatch = Array('ace'); +addThis(); + +status = inSection(31); +pattern = /a[b-d]/; +string = 'aac'; +actualmatch = string.match(pattern); +expectedmatch = Array('ac'); +addThis(); + +status = inSection(32); +pattern = /a[-b]/; +string = 'a-'; +actualmatch = string.match(pattern); +expectedmatch = Array('a-'); +addThis(); + +status = inSection(33); +pattern = /a[b-]/; +string = 'a-'; +actualmatch = string.match(pattern); +expectedmatch = Array('a-'); +addThis(); + +status = inSection(34); +pattern = /a]/; +string = 'a]'; +actualmatch = string.match(pattern); +expectedmatch = Array('a]'); +addThis(); + +/* Perl supports ] & ^] inside a [], ECMA does not + pattern = /a[]]b/; + status = inSection(35); + string = 'a]b'; + actualmatch = string.match(pattern); + expectedmatch = Array('a]b'); + addThis(); +*/ + +status = inSection(36); +pattern = /a[^bc]d/; +string = 'aed'; +actualmatch = string.match(pattern); +expectedmatch = Array('aed'); +addThis(); + +status = inSection(37); +pattern = /a[^-b]c/; +string = 'adc'; +actualmatch = string.match(pattern); +expectedmatch = Array('adc'); +addThis(); + +/* Perl supports ] & ^] inside a [], ECMA does not + status = inSection(38); + pattern = /a[^]b]c/; + string = 'adc'; + actualmatch = string.match(pattern); + expectedmatch = Array('adc'); + addThis(); +*/ + +status = inSection(39); +pattern = /\ba\b/; +string = 'a-'; +actualmatch = string.match(pattern); +expectedmatch = Array('a'); +addThis(); + +status = inSection(40); +pattern = /\ba\b/; +string = '-a'; +actualmatch = string.match(pattern); +expectedmatch = Array('a'); +addThis(); + +status = inSection(41); +pattern = /\ba\b/; +string = '-a-'; +actualmatch = string.match(pattern); +expectedmatch = Array('a'); +addThis(); + +status = inSection(42); +pattern = /\By\b/; +string = 'xy'; +actualmatch = string.match(pattern); +expectedmatch = Array('y'); +addThis(); + +status = inSection(43); +pattern = /\by\B/; +string = 'yz'; +actualmatch = string.match(pattern); +expectedmatch = Array('y'); +addThis(); + +status = inSection(44); +pattern = /\By\B/; +string = 'xyz'; +actualmatch = string.match(pattern); +expectedmatch = Array('y'); +addThis(); + +status = inSection(45); +pattern = /\w/; +string = 'a'; +actualmatch = string.match(pattern); +expectedmatch = Array('a'); +addThis(); + +status = inSection(46); +pattern = /\W/; +string = '-'; +actualmatch = string.match(pattern); +expectedmatch = Array('-'); +addThis(); + +status = inSection(47); +pattern = /a\Sb/; +string = 'a-b'; +actualmatch = string.match(pattern); +expectedmatch = Array('a-b'); +addThis(); + +status = inSection(48); +pattern = /\d/; +string = '1'; +actualmatch = string.match(pattern); +expectedmatch = Array('1'); +addThis(); + +status = inSection(49); +pattern = /\D/; +string = '-'; +actualmatch = string.match(pattern); +expectedmatch = Array('-'); +addThis(); + +status = inSection(50); +pattern = /[\w]/; +string = 'a'; +actualmatch = string.match(pattern); +expectedmatch = Array('a'); +addThis(); + +status = inSection(51); +pattern = /[\W]/; +string = '-'; +actualmatch = string.match(pattern); +expectedmatch = Array('-'); +addThis(); + +status = inSection(52); +pattern = /a[\S]b/; +string = 'a-b'; +actualmatch = string.match(pattern); +expectedmatch = Array('a-b'); +addThis(); + +status = inSection(53); +pattern = /[\d]/; +string = '1'; +actualmatch = string.match(pattern); +expectedmatch = Array('1'); +addThis(); + +status = inSection(54); +pattern = /[\D]/; +string = '-'; +actualmatch = string.match(pattern); +expectedmatch = Array('-'); +addThis(); + +status = inSection(55); +pattern = /ab|cd/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('ab'); +addThis(); + +status = inSection(56); +pattern = /ab|cd/; +string = 'abcd'; +actualmatch = string.match(pattern); +expectedmatch = Array('ab'); +addThis(); + +status = inSection(57); +pattern = /()ef/; +string = 'def'; +actualmatch = string.match(pattern); +expectedmatch = Array('ef', ''); +addThis(); + +status = inSection(58); +pattern = /a\(b/; +string = 'a(b'; +actualmatch = string.match(pattern); +expectedmatch = Array('a(b'); +addThis(); + +status = inSection(59); +pattern = /a\(*b/; +string = 'ab'; +actualmatch = string.match(pattern); +expectedmatch = Array('ab'); +addThis(); + +status = inSection(60); +pattern = /a\(*b/; +string = 'a((b'; +actualmatch = string.match(pattern); +expectedmatch = Array('a((b'); +addThis(); + +status = inSection(61); +pattern = /a\\b/; +string = 'a\\b'; +actualmatch = string.match(pattern); +expectedmatch = Array('a\\b'); +addThis(); + +status = inSection(62); +pattern = /((a))/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('a', 'a', 'a'); +addThis(); + +status = inSection(63); +pattern = /(a)b(c)/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc', 'a', 'c'); +addThis(); + +status = inSection(64); +pattern = /a+b+c/; +string = 'aabbabc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(65); +pattern = /a{1,}b{1,}c/; +string = 'aabbabc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(66); +pattern = /a.+?c/; +string = 'abcabc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc'); +addThis(); + +status = inSection(67); +pattern = /(a+|b)*/; +string = 'ab'; +actualmatch = string.match(pattern); +expectedmatch = Array('ab', 'b'); +addThis(); + +status = inSection(68); +pattern = /(a+|b){0,}/; +string = 'ab'; +actualmatch = string.match(pattern); +expectedmatch = Array('ab', 'b'); +addThis(); + +status = inSection(69); +pattern = /(a+|b)+/; +string = 'ab'; +actualmatch = string.match(pattern); +expectedmatch = Array('ab', 'b'); +addThis(); + +status = inSection(70); +pattern = /(a+|b){1,}/; +string = 'ab'; +actualmatch = string.match(pattern); +expectedmatch = Array('ab', 'b'); +addThis(); + +status = inSection(71); +pattern = /(a+|b)?/; +string = 'ab'; +actualmatch = string.match(pattern); +expectedmatch = Array('a', 'a'); +addThis(); + +status = inSection(72); +pattern = /(a+|b){0,1}/; +string = 'ab'; +actualmatch = string.match(pattern); +expectedmatch = Array('a', 'a'); +addThis(); + +status = inSection(73); +pattern = /[^ab]*/; +string = 'cde'; +actualmatch = string.match(pattern); +expectedmatch = Array('cde'); +addThis(); + +status = inSection(74); +pattern = /([abc])*d/; +string = 'abbbcd'; +actualmatch = string.match(pattern); +expectedmatch = Array('abbbcd', 'c'); +addThis(); + +status = inSection(75); +pattern = /([abc])*bcd/; +string = 'abcd'; +actualmatch = string.match(pattern); +expectedmatch = Array('abcd', 'a'); +addThis(); + +status = inSection(76); +pattern = /a|b|c|d|e/; +string = 'e'; +actualmatch = string.match(pattern); +expectedmatch = Array('e'); +addThis(); + +status = inSection(77); +pattern = /(a|b|c|d|e)f/; +string = 'ef'; +actualmatch = string.match(pattern); +expectedmatch = Array('ef', 'e'); +addThis(); + +status = inSection(78); +pattern = /abcd*efg/; +string = 'abcdefg'; +actualmatch = string.match(pattern); +expectedmatch = Array('abcdefg'); +addThis(); + +status = inSection(79); +pattern = /ab*/; +string = 'xabyabbbz'; +actualmatch = string.match(pattern); +expectedmatch = Array('ab'); +addThis(); + +status = inSection(80); +pattern = /ab*/; +string = 'xayabbbz'; +actualmatch = string.match(pattern); +expectedmatch = Array('a'); +addThis(); + +status = inSection(81); +pattern = /(ab|cd)e/; +string = 'abcde'; +actualmatch = string.match(pattern); +expectedmatch = Array('cde', 'cd'); +addThis(); + +status = inSection(82); +pattern = /[abhgefdc]ij/; +string = 'hij'; +actualmatch = string.match(pattern); +expectedmatch = Array('hij'); +addThis(); + +status = inSection(83); +pattern = /(abc|)ef/; +string = 'abcdef'; +actualmatch = string.match(pattern); +expectedmatch = Array('ef', ''); +addThis(); + +status = inSection(84); +pattern = /(a|b)c*d/; +string = 'abcd'; +actualmatch = string.match(pattern); +expectedmatch = Array('bcd', 'b'); +addThis(); + +status = inSection(85); +pattern = /(ab|ab*)bc/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc', 'a'); +addThis(); + +status = inSection(86); +pattern = /a([bc]*)c*/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc', 'bc'); +addThis(); + +status = inSection(87); +pattern = /a([bc]*)(c*d)/; +string = 'abcd'; +actualmatch = string.match(pattern); +expectedmatch = Array('abcd', 'bc', 'd'); +addThis(); + +status = inSection(88); +pattern = /a([bc]+)(c*d)/; +string = 'abcd'; +actualmatch = string.match(pattern); +expectedmatch = Array('abcd', 'bc', 'd'); +addThis(); + +status = inSection(89); +pattern = /a([bc]*)(c+d)/; +string = 'abcd'; +actualmatch = string.match(pattern); +expectedmatch = Array('abcd', 'b', 'cd'); +addThis(); + +status = inSection(90); +pattern = /a[bcd]*dcdcde/; +string = 'adcdcde'; +actualmatch = string.match(pattern); +expectedmatch = Array('adcdcde'); +addThis(); + +status = inSection(91); +pattern = /(ab|a)b*c/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc', 'ab'); +addThis(); + +status = inSection(92); +pattern = /((a)(b)c)(d)/; +string = 'abcd'; +actualmatch = string.match(pattern); +expectedmatch = Array('abcd', 'abc', 'a', 'b', 'd'); +addThis(); + +status = inSection(93); +pattern = /[a-zA-Z_][a-zA-Z0-9_]*/; +string = 'alpha'; +actualmatch = string.match(pattern); +expectedmatch = Array('alpha'); +addThis(); + +status = inSection(94); +pattern = /^a(bc+|b[eh])g|.h$/; +string = 'abh'; +actualmatch = string.match(pattern); +expectedmatch = Array('bh', undefined); +addThis(); + +status = inSection(95); +pattern = /(bc+d$|ef*g.|h?i(j|k))/; +string = 'effgz'; +actualmatch = string.match(pattern); +expectedmatch = Array('effgz', 'effgz', undefined); +addThis(); + +status = inSection(96); +pattern = /(bc+d$|ef*g.|h?i(j|k))/; +string = 'ij'; +actualmatch = string.match(pattern); +expectedmatch = Array('ij', 'ij', 'j'); +addThis(); + +status = inSection(97); +pattern = /(bc+d$|ef*g.|h?i(j|k))/; +string = 'reffgz'; +actualmatch = string.match(pattern); +expectedmatch = Array('effgz', 'effgz', undefined); +addThis(); + +status = inSection(98); +pattern = /((((((((((a))))))))))/; +string = 'a'; +actualmatch = string.match(pattern); +expectedmatch = Array('a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'); +addThis(); + +status = inSection(99); +pattern = /((((((((((a))))))))))\10/; +string = 'aa'; +actualmatch = string.match(pattern); +expectedmatch = Array('aa', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'); +addThis(); + +status = inSection(100); +pattern = /((((((((((a))))))))))/; +string = 'a!'; +actualmatch = string.match(pattern); +expectedmatch = Array('a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'); +addThis(); + +status = inSection(101); +pattern = /(((((((((a)))))))))/; +string = 'a'; +actualmatch = string.match(pattern); +expectedmatch = Array('a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'); +addThis(); + +status = inSection(102); +pattern = /(.*)c(.*)/; +string = 'abcde'; +actualmatch = string.match(pattern); +expectedmatch = Array('abcde', 'ab', 'de'); +addThis(); + +status = inSection(103); +pattern = /abcd/; +string = 'abcd'; +actualmatch = string.match(pattern); +expectedmatch = Array('abcd'); +addThis(); + +status = inSection(104); +pattern = /a(bc)d/; +string = 'abcd'; +actualmatch = string.match(pattern); +expectedmatch = Array('abcd', 'bc'); +addThis(); + +status = inSection(105); +pattern = /a[-]?c/; +string = 'ac'; +actualmatch = string.match(pattern); +expectedmatch = Array('ac'); +addThis(); + +status = inSection(106); +pattern = /(abc)\1/; +string = 'abcabc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abcabc', 'abc'); +addThis(); + +status = inSection(107); +pattern = /([a-c]*)\1/; +string = 'abcabc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abcabc', 'abc'); +addThis(); + +status = inSection(108); +pattern = /(a)|\1/; +string = 'a'; +actualmatch = string.match(pattern); +expectedmatch = Array('a', 'a'); +addThis(); + +status = inSection(109); +pattern = /(([a-c])b*?\2)*/; +string = 'ababbbcbc'; +actualmatch = string.match(pattern); +expectedmatch = Array('ababb', 'bb', 'b'); +addThis(); + +status = inSection(110); +pattern = /(([a-c])b*?\2){3}/; +string = 'ababbbcbc'; +actualmatch = string.match(pattern); +expectedmatch = Array('ababbbcbc', 'cbc', 'c'); +addThis(); + +/* Can't refer to a capture before it's encountered & completed + status = inSection(111); + pattern = /((\3|b)\2(a)x)+/; + string = 'aaaxabaxbaaxbbax'; + actualmatch = string.match(pattern); + expectedmatch = Array('bbax', 'bbax', 'b', 'a'); + addThis(); + + status = inSection(112); + pattern = /((\3|b)\2(a)){2,}/; + string = 'bbaababbabaaaaabbaaaabba'; + actualmatch = string.match(pattern); + expectedmatch = Array('bbaaaabba', 'bba', 'b', 'a'); + addThis(); +*/ + +status = inSection(113); +pattern = /abc/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(114); +pattern = /abc/i; +string = 'XABCY'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(115); +pattern = /abc/i; +string = 'ABABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(116); +pattern = /ab*c/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(117); +pattern = /ab*bc/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(118); +pattern = /ab*bc/i; +string = 'ABBC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABBC'); +addThis(); + +status = inSection(119); +pattern = /ab*?bc/i; +string = 'ABBBBC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABBBBC'); +addThis(); + +status = inSection(120); +pattern = /ab{0,}?bc/i; +string = 'ABBBBC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABBBBC'); +addThis(); + +status = inSection(121); +pattern = /ab+?bc/i; +string = 'ABBC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABBC'); +addThis(); + +status = inSection(122); +pattern = /ab+bc/i; +string = 'ABBBBC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABBBBC'); +addThis(); + +status = inSection(123); +pattern = /ab{1,}?bc/i; +string = 'ABBBBC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABBBBC'); +addThis(); + +status = inSection(124); +pattern = /ab{1,3}?bc/i; +string = 'ABBBBC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABBBBC'); +addThis(); + +status = inSection(125); +pattern = /ab{3,4}?bc/i; +string = 'ABBBBC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABBBBC'); +addThis(); + +status = inSection(126); +pattern = /ab??bc/i; +string = 'ABBC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABBC'); +addThis(); + +status = inSection(127); +pattern = /ab??bc/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(128); +pattern = /ab{0,1}?bc/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(129); +pattern = /ab??c/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(130); +pattern = /ab{0,1}?c/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(131); +pattern = /^abc$/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(132); +pattern = /^abc/i; +string = 'ABCC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(133); +pattern = /abc$/i; +string = 'AABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(134); +pattern = /^/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array(''); +addThis(); + +status = inSection(135); +pattern = /$/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array(''); +addThis(); + +status = inSection(136); +pattern = /a.c/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(137); +pattern = /a.c/i; +string = 'AXC'; +actualmatch = string.match(pattern); +expectedmatch = Array('AXC'); +addThis(); + +status = inSection(138); +pattern = /a.*?c/i; +string = 'AXYZC'; +actualmatch = string.match(pattern); +expectedmatch = Array('AXYZC'); +addThis(); + +status = inSection(139); +pattern = /a[bc]d/i; +string = 'ABD'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABD'); +addThis(); + +status = inSection(140); +pattern = /a[b-d]e/i; +string = 'ACE'; +actualmatch = string.match(pattern); +expectedmatch = Array('ACE'); +addThis(); + +status = inSection(141); +pattern = /a[b-d]/i; +string = 'AAC'; +actualmatch = string.match(pattern); +expectedmatch = Array('AC'); +addThis(); + +status = inSection(142); +pattern = /a[-b]/i; +string = 'A-'; +actualmatch = string.match(pattern); +expectedmatch = Array('A-'); +addThis(); + +status = inSection(143); +pattern = /a[b-]/i; +string = 'A-'; +actualmatch = string.match(pattern); +expectedmatch = Array('A-'); +addThis(); + +status = inSection(144); +pattern = /a]/i; +string = 'A]'; +actualmatch = string.match(pattern); +expectedmatch = Array('A]'); +addThis(); + +/* Perl supports ] & ^] inside a [], ECMA does not + status = inSection(145); + pattern = /a[]]b/i; + string = 'A]B'; + actualmatch = string.match(pattern); + expectedmatch = Array('A]B'); + addThis(); +*/ + +status = inSection(146); +pattern = /a[^bc]d/i; +string = 'AED'; +actualmatch = string.match(pattern); +expectedmatch = Array('AED'); +addThis(); + +status = inSection(147); +pattern = /a[^-b]c/i; +string = 'ADC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ADC'); +addThis(); + +/* Perl supports ] & ^] inside a [], ECMA does not + status = inSection(148); + pattern = /a[^]b]c/i; + string = 'ADC'; + actualmatch = string.match(pattern); + expectedmatch = Array('ADC'); + addThis(); +*/ + +status = inSection(149); +pattern = /ab|cd/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('AB'); +addThis(); + +status = inSection(150); +pattern = /ab|cd/i; +string = 'ABCD'; +actualmatch = string.match(pattern); +expectedmatch = Array('AB'); +addThis(); + +status = inSection(151); +pattern = /()ef/i; +string = 'DEF'; +actualmatch = string.match(pattern); +expectedmatch = Array('EF', ''); +addThis(); + +status = inSection(152); +pattern = /a\(b/i; +string = 'A(B'; +actualmatch = string.match(pattern); +expectedmatch = Array('A(B'); +addThis(); + +status = inSection(153); +pattern = /a\(*b/i; +string = 'AB'; +actualmatch = string.match(pattern); +expectedmatch = Array('AB'); +addThis(); + +status = inSection(154); +pattern = /a\(*b/i; +string = 'A((B'; +actualmatch = string.match(pattern); +expectedmatch = Array('A((B'); +addThis(); + +status = inSection(155); +pattern = /a\\b/i; +string = 'A\\B'; +actualmatch = string.match(pattern); +expectedmatch = Array('A\\B'); +addThis(); + +status = inSection(156); +pattern = /((a))/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('A', 'A', 'A'); +addThis(); + +status = inSection(157); +pattern = /(a)b(c)/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC', 'A', 'C'); +addThis(); + +status = inSection(158); +pattern = /a+b+c/i; +string = 'AABBABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(159); +pattern = /a{1,}b{1,}c/i; +string = 'AABBABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(160); +pattern = /a.+?c/i; +string = 'ABCABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(161); +pattern = /a.*?c/i; +string = 'ABCABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(162); +pattern = /a.{0,5}?c/i; +string = 'ABCABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC'); +addThis(); + +status = inSection(163); +pattern = /(a+|b)*/i; +string = 'AB'; +actualmatch = string.match(pattern); +expectedmatch = Array('AB', 'B'); +addThis(); + +status = inSection(164); +pattern = /(a+|b){0,}/i; +string = 'AB'; +actualmatch = string.match(pattern); +expectedmatch = Array('AB', 'B'); +addThis(); + +status = inSection(165); +pattern = /(a+|b)+/i; +string = 'AB'; +actualmatch = string.match(pattern); +expectedmatch = Array('AB', 'B'); +addThis(); + +status = inSection(166); +pattern = /(a+|b){1,}/i; +string = 'AB'; +actualmatch = string.match(pattern); +expectedmatch = Array('AB', 'B'); +addThis(); + +status = inSection(167); +pattern = /(a+|b)?/i; +string = 'AB'; +actualmatch = string.match(pattern); +expectedmatch = Array('A', 'A'); +addThis(); + +status = inSection(168); +pattern = /(a+|b){0,1}/i; +string = 'AB'; +actualmatch = string.match(pattern); +expectedmatch = Array('A', 'A'); +addThis(); + +status = inSection(169); +pattern = /(a+|b){0,1}?/i; +string = 'AB'; +actualmatch = string.match(pattern); +expectedmatch = Array('', undefined); +addThis(); + +status = inSection(170); +pattern = /[^ab]*/i; +string = 'CDE'; +actualmatch = string.match(pattern); +expectedmatch = Array('CDE'); +addThis(); + +status = inSection(171); +pattern = /([abc])*d/i; +string = 'ABBBCD'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABBBCD', 'C'); +addThis(); + +status = inSection(172); +pattern = /([abc])*bcd/i; +string = 'ABCD'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABCD', 'A'); +addThis(); + +status = inSection(173); +pattern = /a|b|c|d|e/i; +string = 'E'; +actualmatch = string.match(pattern); +expectedmatch = Array('E'); +addThis(); + +status = inSection(174); +pattern = /(a|b|c|d|e)f/i; +string = 'EF'; +actualmatch = string.match(pattern); +expectedmatch = Array('EF', 'E'); +addThis(); + +status = inSection(175); +pattern = /abcd*efg/i; +string = 'ABCDEFG'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABCDEFG'); +addThis(); + +status = inSection(176); +pattern = /ab*/i; +string = 'XABYABBBZ'; +actualmatch = string.match(pattern); +expectedmatch = Array('AB'); +addThis(); + +status = inSection(177); +pattern = /ab*/i; +string = 'XAYABBBZ'; +actualmatch = string.match(pattern); +expectedmatch = Array('A'); +addThis(); + +status = inSection(178); +pattern = /(ab|cd)e/i; +string = 'ABCDE'; +actualmatch = string.match(pattern); +expectedmatch = Array('CDE', 'CD'); +addThis(); + +status = inSection(179); +pattern = /[abhgefdc]ij/i; +string = 'HIJ'; +actualmatch = string.match(pattern); +expectedmatch = Array('HIJ'); +addThis(); + +status = inSection(180); +pattern = /(abc|)ef/i; +string = 'ABCDEF'; +actualmatch = string.match(pattern); +expectedmatch = Array('EF', ''); +addThis(); + +status = inSection(181); +pattern = /(a|b)c*d/i; +string = 'ABCD'; +actualmatch = string.match(pattern); +expectedmatch = Array('BCD', 'B'); +addThis(); + +status = inSection(182); +pattern = /(ab|ab*)bc/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC', 'A'); +addThis(); + +status = inSection(183); +pattern = /a([bc]*)c*/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC', 'BC'); +addThis(); + +status = inSection(184); +pattern = /a([bc]*)(c*d)/i; +string = 'ABCD'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABCD', 'BC', 'D'); +addThis(); + +status = inSection(185); +pattern = /a([bc]+)(c*d)/i; +string = 'ABCD'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABCD', 'BC', 'D'); +addThis(); + +status = inSection(186); +pattern = /a([bc]*)(c+d)/i; +string = 'ABCD'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABCD', 'B', 'CD'); +addThis(); + +status = inSection(187); +pattern = /a[bcd]*dcdcde/i; +string = 'ADCDCDE'; +actualmatch = string.match(pattern); +expectedmatch = Array('ADCDCDE'); +addThis(); + +status = inSection(188); +pattern = /(ab|a)b*c/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABC', 'AB'); +addThis(); + +status = inSection(189); +pattern = /((a)(b)c)(d)/i; +string = 'ABCD'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABCD', 'ABC', 'A', 'B', 'D'); +addThis(); + +status = inSection(190); +pattern = /[a-zA-Z_][a-zA-Z0-9_]*/i; +string = 'ALPHA'; +actualmatch = string.match(pattern); +expectedmatch = Array('ALPHA'); +addThis(); + +status = inSection(191); +pattern = /^a(bc+|b[eh])g|.h$/i; +string = 'ABH'; +actualmatch = string.match(pattern); +expectedmatch = Array('BH', undefined); +addThis(); + +status = inSection(192); +pattern = /(bc+d$|ef*g.|h?i(j|k))/i; +string = 'EFFGZ'; +actualmatch = string.match(pattern); +expectedmatch = Array('EFFGZ', 'EFFGZ', undefined); +addThis(); + +status = inSection(193); +pattern = /(bc+d$|ef*g.|h?i(j|k))/i; +string = 'IJ'; +actualmatch = string.match(pattern); +expectedmatch = Array('IJ', 'IJ', 'J'); +addThis(); + +status = inSection(194); +pattern = /(bc+d$|ef*g.|h?i(j|k))/i; +string = 'REFFGZ'; +actualmatch = string.match(pattern); +expectedmatch = Array('EFFGZ', 'EFFGZ', undefined); +addThis(); + +status = inSection(195); +pattern = /((((((((((a))))))))))/i; +string = 'A'; +actualmatch = string.match(pattern); +expectedmatch = Array('A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'); +addThis(); + +status = inSection(196); +pattern = /((((((((((a))))))))))\10/i; +string = 'AA'; +actualmatch = string.match(pattern); +expectedmatch = Array('AA', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'); +addThis(); + +status = inSection(197); +pattern = /((((((((((a))))))))))/i; +string = 'A!'; +actualmatch = string.match(pattern); +expectedmatch = Array('A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'); +addThis(); + +status = inSection(198); +pattern = /(((((((((a)))))))))/i; +string = 'A'; +actualmatch = string.match(pattern); +expectedmatch = Array('A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'); +addThis(); + +status = inSection(199); +pattern = /(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))/i; +string = 'A'; +actualmatch = string.match(pattern); +expectedmatch = Array('A', 'A'); +addThis(); + +status = inSection(200); +pattern = /(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))/i; +string = 'C'; +actualmatch = string.match(pattern); +expectedmatch = Array('C', 'C'); +addThis(); + +status = inSection(201); +pattern = /(.*)c(.*)/i; +string = 'ABCDE'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABCDE', 'AB', 'DE'); +addThis(); + +status = inSection(202); +pattern = /abcd/i; +string = 'ABCD'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABCD'); +addThis(); + +status = inSection(203); +pattern = /a(bc)d/i; +string = 'ABCD'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABCD', 'BC'); +addThis(); + +status = inSection(204); +pattern = /a[-]?c/i; +string = 'AC'; +actualmatch = string.match(pattern); +expectedmatch = Array('AC'); +addThis(); + +status = inSection(205); +pattern = /(abc)\1/i; +string = 'ABCABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABCABC', 'ABC'); +addThis(); + +status = inSection(206); +pattern = /([a-c]*)\1/i; +string = 'ABCABC'; +actualmatch = string.match(pattern); +expectedmatch = Array('ABCABC', 'ABC'); +addThis(); + +status = inSection(207); +pattern = /a(?!b)./; +string = 'abad'; +actualmatch = string.match(pattern); +expectedmatch = Array('ad'); +addThis(); + +status = inSection(208); +pattern = /a(?=d)./; +string = 'abad'; +actualmatch = string.match(pattern); +expectedmatch = Array('ad'); +addThis(); + +status = inSection(209); +pattern = /a(?=c|d)./; +string = 'abad'; +actualmatch = string.match(pattern); +expectedmatch = Array('ad'); +addThis(); + +status = inSection(210); +pattern = /a(?:b|c|d)(.)/; +string = 'ace'; +actualmatch = string.match(pattern); +expectedmatch = Array('ace', 'e'); +addThis(); + +status = inSection(211); +pattern = /a(?:b|c|d)*(.)/; +string = 'ace'; +actualmatch = string.match(pattern); +expectedmatch = Array('ace', 'e'); +addThis(); + +status = inSection(212); +pattern = /a(?:b|c|d)+?(.)/; +string = 'ace'; +actualmatch = string.match(pattern); +expectedmatch = Array('ace', 'e'); +addThis(); + +status = inSection(213); +pattern = /a(?:b|c|d)+?(.)/; +string = 'acdbcdbe'; +actualmatch = string.match(pattern); +expectedmatch = Array('acd', 'd'); +addThis(); + +status = inSection(214); +pattern = /a(?:b|c|d)+(.)/; +string = 'acdbcdbe'; +actualmatch = string.match(pattern); +expectedmatch = Array('acdbcdbe', 'e'); +addThis(); + +status = inSection(215); +pattern = /a(?:b|c|d){2}(.)/; +string = 'acdbcdbe'; +actualmatch = string.match(pattern); +expectedmatch = Array('acdb', 'b'); +addThis(); + +status = inSection(216); +pattern = /a(?:b|c|d){4,5}(.)/; +string = 'acdbcdbe'; +actualmatch = string.match(pattern); +expectedmatch = Array('acdbcdb', 'b'); +addThis(); + +status = inSection(217); +pattern = /a(?:b|c|d){4,5}?(.)/; +string = 'acdbcdbe'; +actualmatch = string.match(pattern); +expectedmatch = Array('acdbcd', 'd'); +addThis(); + +// MODIFIED - ECMA has different rules for paren contents +status = inSection(218); +pattern = /((foo)|(bar))*/; +string = 'foobar'; +actualmatch = string.match(pattern); +//expectedmatch = Array('foobar', 'bar', 'foo', 'bar'); +expectedmatch = Array('foobar', 'bar', undefined, 'bar'); +addThis(); + +status = inSection(219); +pattern = /a(?:b|c|d){6,7}(.)/; +string = 'acdbcdbe'; +actualmatch = string.match(pattern); +expectedmatch = Array('acdbcdbe', 'e'); +addThis(); + +status = inSection(220); +pattern = /a(?:b|c|d){6,7}?(.)/; +string = 'acdbcdbe'; +actualmatch = string.match(pattern); +expectedmatch = Array('acdbcdbe', 'e'); +addThis(); + +status = inSection(221); +pattern = /a(?:b|c|d){5,6}(.)/; +string = 'acdbcdbe'; +actualmatch = string.match(pattern); +expectedmatch = Array('acdbcdbe', 'e'); +addThis(); + +status = inSection(222); +pattern = /a(?:b|c|d){5,6}?(.)/; +string = 'acdbcdbe'; +actualmatch = string.match(pattern); +expectedmatch = Array('acdbcdb', 'b'); +addThis(); + +status = inSection(223); +pattern = /a(?:b|c|d){5,7}(.)/; +string = 'acdbcdbe'; +actualmatch = string.match(pattern); +expectedmatch = Array('acdbcdbe', 'e'); +addThis(); + +status = inSection(224); +pattern = /a(?:b|c|d){5,7}?(.)/; +string = 'acdbcdbe'; +actualmatch = string.match(pattern); +expectedmatch = Array('acdbcdb', 'b'); +addThis(); + +status = inSection(225); +pattern = /a(?:b|(c|e){1,2}?|d)+?(.)/; +string = 'ace'; +actualmatch = string.match(pattern); +expectedmatch = Array('ace', 'c', 'e'); +addThis(); + +status = inSection(226); +pattern = /^(.+)?B/; +string = 'AB'; +actualmatch = string.match(pattern); +expectedmatch = Array('AB', 'A'); +addThis(); + +/* MODIFIED - ECMA has different rules for paren contents */ +status = inSection(227); +pattern = /^([^a-z])|(\^)$/; +string = '.'; +actualmatch = string.match(pattern); +//expectedmatch = Array('.', '.', ''); +expectedmatch = Array('.', '.', undefined); +addThis(); + +status = inSection(228); +pattern = /^[<>]&/; +string = '<&OUT'; +actualmatch = string.match(pattern); +expectedmatch = Array('<&'); +addThis(); + +/* Can't refer to a capture before it's encountered & completed + status = inSection(229); + pattern = /^(a\1?){4}$/; + string = 'aaaaaaaaaa'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaaaaaaaaa', 'aaaa'); + addThis(); + + status = inSection(230); + pattern = /^(a(?(1)\1)){4}$/; + string = 'aaaaaaaaaa'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaaaaaaaaa', 'aaaa'); + addThis(); +*/ + +status = inSection(231); +pattern = /((a{4})+)/; +string = 'aaaaaaaaa'; +actualmatch = string.match(pattern); +expectedmatch = Array('aaaaaaaa', 'aaaaaaaa', 'aaaa'); +addThis(); + +status = inSection(232); +pattern = /(((aa){2})+)/; +string = 'aaaaaaaaaa'; +actualmatch = string.match(pattern); +expectedmatch = Array('aaaaaaaa', 'aaaaaaaa', 'aaaa', 'aa'); +addThis(); + +status = inSection(233); +pattern = /(((a{2}){2})+)/; +string = 'aaaaaaaaaa'; +actualmatch = string.match(pattern); +expectedmatch = Array('aaaaaaaa', 'aaaaaaaa', 'aaaa', 'aa'); +addThis(); + +status = inSection(234); +pattern = /(?:(f)(o)(o)|(b)(a)(r))*/; +string = 'foobar'; +actualmatch = string.match(pattern); +//expectedmatch = Array('foobar', 'f', 'o', 'o', 'b', 'a', 'r'); +expectedmatch = Array('foobar', undefined, undefined, undefined, 'b', 'a', 'r'); +addThis(); + +/* ECMA supports (?: (?= and (?! but doesn't support (?< etc. + status = inSection(235); + pattern = /(?<=a)b/; + string = 'ab'; + actualmatch = string.match(pattern); + expectedmatch = Array('b'); + addThis(); + + status = inSection(236); + pattern = /(?<!c)b/; + string = 'ab'; + actualmatch = string.match(pattern); + expectedmatch = Array('b'); + addThis(); + + status = inSection(237); + pattern = /(?<!c)b/; + string = 'b'; + actualmatch = string.match(pattern); + expectedmatch = Array('b'); + addThis(); + + status = inSection(238); + pattern = /(?<!c)b/; + string = 'b'; + actualmatch = string.match(pattern); + expectedmatch = Array('b'); + addThis(); +*/ + +status = inSection(239); +pattern = /(?:..)*a/; +string = 'aba'; +actualmatch = string.match(pattern); +expectedmatch = Array('aba'); +addThis(); + +status = inSection(240); +pattern = /(?:..)*?a/; +string = 'aba'; +actualmatch = string.match(pattern); +expectedmatch = Array('a'); +addThis(); + +/* + * MODIFIED - ECMA has different rules for paren contents. Note + * this regexp has two non-capturing parens, and one capturing + * + * The issue: shouldn't the match be ['ab', undefined]? Because the + * '\1' matches the undefined value of the second iteration of the '*' + * (in which the 'b' part of the '|' matches). But Perl wants ['ab','b']. + * + * Answer: waldemar@netscape.com: + * + * The correct answer is ['ab', undefined]. Perl doesn't match + * ECMAScript here, and I'd say that Perl is wrong in this case. + */ +status = inSection(241); +pattern = /^(?:b|a(?=(.)))*\1/; +string = 'abc'; +actualmatch = string.match(pattern); +//expectedmatch = Array('ab', 'b'); +expectedmatch = Array('ab', undefined); +addThis(); + +status = inSection(242); +pattern = /^(){3,5}/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('', ''); +addThis(); + +status = inSection(243); +pattern = /^(a+)*ax/; +string = 'aax'; +actualmatch = string.match(pattern); +expectedmatch = Array('aax', 'a'); +addThis(); + +status = inSection(244); +pattern = /^((a|b)+)*ax/; +string = 'aax'; +actualmatch = string.match(pattern); +expectedmatch = Array('aax', 'a', 'a'); +addThis(); + +status = inSection(245); +pattern = /^((a|bc)+)*ax/; +string = 'aax'; +actualmatch = string.match(pattern); +expectedmatch = Array('aax', 'a', 'a'); +addThis(); + +/* MODIFIED - ECMA has different rules for paren contents */ +status = inSection(246); +pattern = /(a|x)*ab/; +string = 'cab'; +actualmatch = string.match(pattern); +//expectedmatch = Array('ab', ''); +expectedmatch = Array('ab', undefined); +addThis(); + +status = inSection(247); +pattern = /(a)*ab/; +string = 'cab'; +actualmatch = string.match(pattern); +expectedmatch = Array('ab', undefined); +addThis(); + +/* ECMA doesn't support (?imsx or (?-imsx + status = inSection(248); + pattern = /(?:(?i)a)b/; + string = 'ab'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab'); + addThis(); + + status = inSection(249); + pattern = /((?i)a)b/; + string = 'ab'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab', 'a'); + addThis(); + + status = inSection(250); + pattern = /(?:(?i)a)b/; + string = 'Ab'; + actualmatch = string.match(pattern); + expectedmatch = Array('Ab'); + addThis(); + + status = inSection(251); + pattern = /((?i)a)b/; + string = 'Ab'; + actualmatch = string.match(pattern); + expectedmatch = Array('Ab', 'A'); + addThis(); + + status = inSection(252); + pattern = /(?i:a)b/; + string = 'ab'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab'); + addThis(); + + status = inSection(253); + pattern = /((?i:a))b/; + string = 'ab'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab', 'a'); + addThis(); + + status = inSection(254); + pattern = /(?i:a)b/; + string = 'Ab'; + actualmatch = string.match(pattern); + expectedmatch = Array('Ab'); + addThis(); + + status = inSection(255); + pattern = /((?i:a))b/; + string = 'Ab'; + actualmatch = string.match(pattern); + expectedmatch = Array('Ab', 'A'); + addThis(); + + status = inSection(256); + pattern = /(?:(?-i)a)b/i; + string = 'ab'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab'); + addThis(); + + status = inSection(257); + pattern = /((?-i)a)b/i; + string = 'ab'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab', 'a'); + addThis(); + + status = inSection(258); + pattern = /(?:(?-i)a)b/i; + string = 'aB'; + actualmatch = string.match(pattern); + expectedmatch = Array('aB'); + addThis(); + + status = inSection(259); + pattern = /((?-i)a)b/i; + string = 'aB'; + actualmatch = string.match(pattern); + expectedmatch = Array('aB', 'a'); + addThis(); + + status = inSection(260); + pattern = /(?:(?-i)a)b/i; + string = 'aB'; + actualmatch = string.match(pattern); + expectedmatch = Array('aB'); + addThis(); + + status = inSection(261); + pattern = /((?-i)a)b/i; + string = 'aB'; + actualmatch = string.match(pattern); + expectedmatch = Array('aB', 'a'); + addThis(); + + status = inSection(262); + pattern = /(?-i:a)b/i; + string = 'ab'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab'); + addThis(); + + status = inSection(263); + pattern = /((?-i:a))b/i; + string = 'ab'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab', 'a'); + addThis(); + + status = inSection(264); + pattern = /(?-i:a)b/i; + string = 'aB'; + actualmatch = string.match(pattern); + expectedmatch = Array('aB'); + addThis(); + + status = inSection(265); + pattern = /((?-i:a))b/i; + string = 'aB'; + actualmatch = string.match(pattern); + expectedmatch = Array('aB', 'a'); + addThis(); + + status = inSection(266); + pattern = /(?-i:a)b/i; + string = 'aB'; + actualmatch = string.match(pattern); + expectedmatch = Array('aB'); + addThis(); + + status = inSection(267); + pattern = /((?-i:a))b/i; + string = 'aB'; + actualmatch = string.match(pattern); + expectedmatch = Array('aB', 'a'); + addThis(); + + status = inSection(268); + pattern = /((?s-i:a.))b/i; + string = 'a\nB'; + actualmatch = string.match(pattern); + expectedmatch = Array('a\nB', 'a\n'); + addThis(); +*/ + +status = inSection(269); +pattern = /(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))/; +string = 'cabbbb'; +actualmatch = string.match(pattern); +expectedmatch = Array('cabbbb'); +addThis(); + +status = inSection(270); +pattern = /(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))/; +string = 'caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'; +actualmatch = string.match(pattern); +expectedmatch = Array('caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); +addThis(); + +status = inSection(271); +pattern = /(ab)\d\1/i; +string = 'Ab4ab'; +actualmatch = string.match(pattern); +expectedmatch = Array('Ab4ab', 'Ab'); +addThis(); + +status = inSection(272); +pattern = /(ab)\d\1/i; +string = 'ab4Ab'; +actualmatch = string.match(pattern); +expectedmatch = Array('ab4Ab', 'ab'); +addThis(); + +status = inSection(273); +pattern = /foo\w*\d{4}baz/; +string = 'foobar1234baz'; +actualmatch = string.match(pattern); +expectedmatch = Array('foobar1234baz'); +addThis(); + +status = inSection(274); +pattern = /x(~~)*(?:(?:F)?)?/; +string = 'x~~'; +actualmatch = string.match(pattern); +expectedmatch = Array('x~~', '~~'); +addThis(); + +/* Perl supports (?# but JS doesn't + status = inSection(275); + pattern = /^a(?#xxx){3}c/; + string = 'aaac'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaac'); + addThis(); +*/ + +/* ECMA doesn't support (?< etc + status = inSection(276); + pattern = /(?<![cd])[ab]/; + string = 'dbaacb'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); + + status = inSection(277); + pattern = /(?<!(c|d))[ab]/; + string = 'dbaacb'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); + + status = inSection(278); + pattern = /(?<!cd)[ab]/; + string = 'cdaccb'; + actualmatch = string.match(pattern); + expectedmatch = Array('b'); + addThis(); + + status = inSection(279); + pattern = /((?s)^a(.))((?m)^b$)/; + string = 'a\nb\nc\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('a\nb', 'a\n', '\n', 'b'); + addThis(); + + status = inSection(280); + pattern = /((?m)^b$)/; + string = 'a\nb\nc\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('b', 'b'); + addThis(); + + status = inSection(281); + pattern = /(?m)^b/; + string = 'a\nb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('b'); + addThis(); + + status = inSection(282); + pattern = /(?m)^(b)/; + string = 'a\nb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('b', 'b'); + addThis(); + + status = inSection(283); + pattern = /((?m)^b)/; + string = 'a\nb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('b', 'b'); + addThis(); + + status = inSection(284); + pattern = /\n((?m)^b)/; + string = 'a\nb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('\nb', 'b'); + addThis(); + + status = inSection(285); + pattern = /((?s).)c(?!.)/; + string = 'a\nb\nc\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('\nc', '\n'); + addThis(); + + status = inSection(286); + pattern = /((?s).)c(?!.)/; + string = 'a\nb\nc\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('\nc', '\n'); + addThis(); + + status = inSection(287); + pattern = /((?s)b.)c(?!.)/; + string = 'a\nb\nc\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('b\nc', 'b\n'); + addThis(); + + status = inSection(288); + pattern = /((?s)b.)c(?!.)/; + string = 'a\nb\nc\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('b\nc', 'b\n'); + addThis(); + + status = inSection(289); + pattern = /((?m)^b)/; + string = 'a\nb\nc\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('b', 'b'); + addThis(); +*/ + +/* ECMA doesn't support (?(condition) + status = inSection(290); + pattern = /(?(1)b|a)/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); + + status = inSection(291); + pattern = /(x)?(?(1)b|a)/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); + + status = inSection(292); + pattern = /()?(?(1)b|a)/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); + + status = inSection(293); + pattern = /()?(?(1)a|b)/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); + + status = inSection(294); + pattern = /^(\()?blah(?(1)(\)))$/; + string = '(blah)'; + actualmatch = string.match(pattern); + expectedmatch = Array('(blah)', '(', ')'); + addThis(); + + status = inSection(295); + pattern = /^(\()?blah(?(1)(\)))$/; + string = 'blah'; + actualmatch = string.match(pattern); + expectedmatch = Array('blah'); + addThis(); + + status = inSection(296); + pattern = /^(\(+)?blah(?(1)(\)))$/; + string = '(blah)'; + actualmatch = string.match(pattern); + expectedmatch = Array('(blah)', '(', ')'); + addThis(); + + status = inSection(297); + pattern = /^(\(+)?blah(?(1)(\)))$/; + string = 'blah'; + actualmatch = string.match(pattern); + expectedmatch = Array('blah'); + addThis(); + + status = inSection(298); + pattern = /(?(?!a)b|a)/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); + + status = inSection(299); + pattern = /(?(?=a)a|b)/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); +*/ + +status = inSection(300); +pattern = /(?=(a+?))(\1ab)/; +string = 'aaab'; +actualmatch = string.match(pattern); +expectedmatch = Array('aab', 'a', 'aab'); +addThis(); + +status = inSection(301); +pattern = /(\w+:)+/; +string = 'one:'; +actualmatch = string.match(pattern); +expectedmatch = Array('one:', 'one:'); +addThis(); + +/* ECMA doesn't support (?< etc + status = inSection(302); + pattern = /$(?<=^(a))/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = Array('', 'a'); + addThis(); +*/ + +status = inSection(303); +pattern = /(?=(a+?))(\1ab)/; +string = 'aaab'; +actualmatch = string.match(pattern); +expectedmatch = Array('aab', 'a', 'aab'); +addThis(); + +/* MODIFIED - ECMA has different rules for paren contents */ +status = inSection(304); +pattern = /([\w:]+::)?(\w+)$/; +string = 'abcd'; +actualmatch = string.match(pattern); +//expectedmatch = Array('abcd', '', 'abcd'); +expectedmatch = Array('abcd', undefined, 'abcd'); +addThis(); + +status = inSection(305); +pattern = /([\w:]+::)?(\w+)$/; +string = 'xy:z:::abcd'; +actualmatch = string.match(pattern); +expectedmatch = Array('xy:z:::abcd', 'xy:z:::', 'abcd'); +addThis(); + +status = inSection(306); +pattern = /^[^bcd]*(c+)/; +string = 'aexycd'; +actualmatch = string.match(pattern); +expectedmatch = Array('aexyc', 'c'); +addThis(); + +status = inSection(307); +pattern = /(a*)b+/; +string = 'caab'; +actualmatch = string.match(pattern); +expectedmatch = Array('aab', 'aa'); +addThis(); + +/* MODIFIED - ECMA has different rules for paren contents */ +status = inSection(308); +pattern = /([\w:]+::)?(\w+)$/; +string = 'abcd'; +actualmatch = string.match(pattern); +//expectedmatch = Array('abcd', '', 'abcd'); +expectedmatch = Array('abcd', undefined, 'abcd'); +addThis(); + +status = inSection(309); +pattern = /([\w:]+::)?(\w+)$/; +string = 'xy:z:::abcd'; +actualmatch = string.match(pattern); +expectedmatch = Array('xy:z:::abcd', 'xy:z:::', 'abcd'); +addThis(); + +status = inSection(310); +pattern = /^[^bcd]*(c+)/; +string = 'aexycd'; +actualmatch = string.match(pattern); +expectedmatch = Array('aexyc', 'c'); +addThis(); + +/* ECMA doesn't support (?> + status = inSection(311); + pattern = /(?>a+)b/; + string = 'aaab'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaab'); + addThis(); +*/ + +status = inSection(312); +pattern = /([[:]+)/; + string = 'a:[b]:'; + actualmatch = string.match(pattern); + expectedmatch = Array(':[', ':['); + addThis(); + + status = inSection(313); + pattern = /([[=]+)/; + string = 'a=[b]='; + actualmatch = string.match(pattern); + expectedmatch = Array('=[', '=['); + addThis(); + + status = inSection(314); + pattern = /([[.]+)/; + string = 'a.[b].'; + actualmatch = string.match(pattern); + expectedmatch = Array('.[', '.['); + addThis(); + +/* ECMA doesn't have rules for [: + status = inSection(315); + pattern = /[a[:]b[:c]/; + string = 'abc'; + actualmatch = string.match(pattern); + expectedmatch = Array('abc'); + addThis(); +*/ + +/* ECMA doesn't support (?> + status = inSection(316); + pattern = /((?>a+)b)/; + string = 'aaab'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaab', 'aaab'); + addThis(); + + status = inSection(317); + pattern = /(?>(a+))b/; + string = 'aaab'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaab', 'aaa'); + addThis(); + + status = inSection(318); + pattern = /((?>[^()]+)|\([^()]*\))+/; + string = '((abc(ade)ufh()()x'; + actualmatch = string.match(pattern); + expectedmatch = Array('abc(ade)ufh()()x', 'x'); + addThis(); +*/ + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(319); + pattern = /\Z/; + string = 'a\nb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); + + status = inSection(320); + pattern = /\z/; + string = 'a\nb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); +*/ + + status = inSection(321); + pattern = /$/; + string = 'a\nb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(322); + pattern = /\Z/; + string = 'b\na\n'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); + + status = inSection(323); + pattern = /\z/; + string = 'b\na\n'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); +*/ + + status = inSection(324); + pattern = /$/; + string = 'b\na\n'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(325); + pattern = /\Z/; + string = 'b\na'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); + + status = inSection(326); + pattern = /\z/; + string = 'b\na'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); +*/ + + status = inSection(327); + pattern = /$/; + string = 'b\na'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(328); + pattern = /\Z/m; + string = 'a\nb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); + + status = inSection(329); + pattern = /\z/m; + string = 'a\nb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); +*/ + + status = inSection(330); + pattern = /$/m; + string = 'a\nb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(331); + pattern = /\Z/m; + string = 'b\na\n'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); + + status = inSection(332); + pattern = /\z/m; + string = 'b\na\n'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); +*/ + + status = inSection(333); + pattern = /$/m; + string = 'b\na\n'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(334); + pattern = /\Z/m; + string = 'b\na'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); + + status = inSection(335); + pattern = /\z/m; + string = 'b\na'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); +*/ + + status = inSection(336); + pattern = /$/m; + string = 'b\na'; + actualmatch = string.match(pattern); + expectedmatch = Array(''); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(337); + pattern = /a\Z/; + string = 'b\na\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); +*/ + +/* $ only matches end of input unless multiline + status = inSection(338); + pattern = /a$/; + string = 'b\na\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); +*/ + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(339); + pattern = /a\Z/; + string = 'b\na'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); + + status = inSection(340); + pattern = /a\z/; + string = 'b\na'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); +*/ + + status = inSection(341); + pattern = /a$/; + string = 'b\na'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); + + status = inSection(342); + pattern = /a$/m; + string = 'a\nb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(343); + pattern = /a\Z/m; + string = 'b\na\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); +*/ + + status = inSection(344); + pattern = /a$/m; + string = 'b\na\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(345); + pattern = /a\Z/m; + string = 'b\na'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); + + status = inSection(346); + pattern = /a\z/m; + string = 'b\na'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); +*/ + + status = inSection(347); + pattern = /a$/m; + string = 'b\na'; + actualmatch = string.match(pattern); + expectedmatch = Array('a'); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(348); + pattern = /aa\Z/; + string = 'b\naa\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('aa'); + addThis(); +*/ + +/* $ only matches end of input unless multiline + status = inSection(349); + pattern = /aa$/; + string = 'b\naa\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('aa'); + addThis(); +*/ + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(350); + pattern = /aa\Z/; + string = 'b\naa'; + actualmatch = string.match(pattern); + expectedmatch = Array('aa'); + addThis(); + + status = inSection(351); + pattern = /aa\z/; + string = 'b\naa'; + actualmatch = string.match(pattern); + expectedmatch = Array('aa'); + addThis(); +*/ + + status = inSection(352); + pattern = /aa$/; + string = 'b\naa'; + actualmatch = string.match(pattern); + expectedmatch = Array('aa'); + addThis(); + + status = inSection(353); + pattern = /aa$/m; + string = 'aa\nb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('aa'); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(354); + pattern = /aa\Z/m; + string = 'b\naa\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('aa'); + addThis(); +*/ + + status = inSection(355); + pattern = /aa$/m; + string = 'b\naa\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('aa'); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(356); + pattern = /aa\Z/m; + string = 'b\naa'; + actualmatch = string.match(pattern); + expectedmatch = Array('aa'); + addThis(); + + status = inSection(357); + pattern = /aa\z/m; + string = 'b\naa'; + actualmatch = string.match(pattern); + expectedmatch = Array('aa'); + addThis(); +*/ + + status = inSection(358); + pattern = /aa$/m; + string = 'b\naa'; + actualmatch = string.match(pattern); + expectedmatch = Array('aa'); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(359); + pattern = /ab\Z/; + string = 'b\nab\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab'); + addThis(); +*/ + +/* $ only matches end of input unless multiline + status = inSection(360); + pattern = /ab$/; + string = 'b\nab\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab'); + addThis(); +*/ + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(361); + pattern = /ab\Z/; + string = 'b\nab'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab'); + addThis(); + + status = inSection(362); + pattern = /ab\z/; + string = 'b\nab'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab'); + addThis(); +*/ + + status = inSection(363); + pattern = /ab$/; + string = 'b\nab'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab'); + addThis(); + + status = inSection(364); + pattern = /ab$/m; + string = 'ab\nb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab'); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(365); + pattern = /ab\Z/m; + string = 'b\nab\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab'); + addThis(); +*/ + + status = inSection(366); + pattern = /ab$/m; + string = 'b\nab\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab'); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(367); + pattern = /ab\Z/m; + string = 'b\nab'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab'); + addThis(); + + status = inSection(368); + pattern = /ab\z/m; + string = 'b\nab'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab'); + addThis(); +*/ + + status = inSection(369); + pattern = /ab$/m; + string = 'b\nab'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab'); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(370); + pattern = /abb\Z/; + string = 'b\nabb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('abb'); + addThis(); +*/ + +/* $ only matches end of input unless multiline + status = inSection(371); + pattern = /abb$/; + string = 'b\nabb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('abb'); + addThis(); +*/ + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(372); + pattern = /abb\Z/; + string = 'b\nabb'; + actualmatch = string.match(pattern); + expectedmatch = Array('abb'); + addThis(); + + status = inSection(373); + pattern = /abb\z/; + string = 'b\nabb'; + actualmatch = string.match(pattern); + expectedmatch = Array('abb'); + addThis(); +*/ + + status = inSection(374); + pattern = /abb$/; + string = 'b\nabb'; + actualmatch = string.match(pattern); + expectedmatch = Array('abb'); + addThis(); + + status = inSection(375); + pattern = /abb$/m; + string = 'abb\nb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('abb'); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(376); + pattern = /abb\Z/m; + string = 'b\nabb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('abb'); + addThis(); +*/ + + status = inSection(377); + pattern = /abb$/m; + string = 'b\nabb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('abb'); + addThis(); + +/* Perl has \Z has end-of-line, ECMA doesn't + status = inSection(378); + pattern = /abb\Z/m; + string = 'b\nabb'; + actualmatch = string.match(pattern); + expectedmatch = Array('abb'); + addThis(); + + status = inSection(379); + pattern = /abb\z/m; + string = 'b\nabb'; + actualmatch = string.match(pattern); + expectedmatch = Array('abb'); + addThis(); +*/ + + status = inSection(380); + pattern = /abb$/m; + string = 'b\nabb'; + actualmatch = string.match(pattern); + expectedmatch = Array('abb'); + addThis(); + + status = inSection(381); + pattern = /(^|x)(c)/; + string = 'ca'; + actualmatch = string.match(pattern); + expectedmatch = Array('c', '', 'c'); + addThis(); + + status = inSection(382); + pattern = /foo.bart/; + string = 'foo.bart'; + actualmatch = string.match(pattern); + expectedmatch = Array('foo.bart'); + addThis(); + + status = inSection(383); + pattern = /^d[x][x][x]/m; + string = 'abcd\ndxxx'; + actualmatch = string.match(pattern); + expectedmatch = Array('dxxx'); + addThis(); + + status = inSection(384); + pattern = /tt+$/; + string = 'xxxtt'; + actualmatch = string.match(pattern); + expectedmatch = Array('tt'); + addThis(); + +/* ECMA spec says that each atom in a range must be a single character + status = inSection(385); + pattern = /([a-\d]+)/; + string = 'za-9z'; + actualmatch = string.match(pattern); + expectedmatch = Array('9', '9'); + addThis(); + + status = inSection(386); + pattern = /([\d-z]+)/; + string = 'a0-za'; + actualmatch = string.match(pattern); + expectedmatch = Array('0-z', '0-z'); + addThis(); +*/ + +/* ECMA doesn't support [: + status = inSection(387); + pattern = /([a-[:digit:]]+)/; + string = 'za-9z'; + actualmatch = string.match(pattern); + expectedmatch = Array('a-9', 'a-9'); + addThis(); + + status = inSection(388); + pattern = /([[:digit:]-z]+)/; + string = '=0-z='; + actualmatch = string.match(pattern); + expectedmatch = Array('0-z', '0-z'); + addThis(); + + status = inSection(389); + pattern = /([[:digit:]-[:alpha:]]+)/; + string = '=0-z='; + actualmatch = string.match(pattern); + expectedmatch = Array('0-z', '0-z'); + addThis(); +*/ + + status = inSection(390); + pattern = /(\d+\.\d+)/; + string = '3.1415926'; + actualmatch = string.match(pattern); + expectedmatch = Array('3.1415926', '3.1415926'); + addThis(); + + status = inSection(391); + pattern = /\.c(pp|xx|c)?$/i; + string = 'IO.c'; + actualmatch = string.match(pattern); + expectedmatch = Array('.c', undefined); + addThis(); + + status = inSection(392); + pattern = /(\.c(pp|xx|c)?$)/i; + string = 'IO.c'; + actualmatch = string.match(pattern); + expectedmatch = Array('.c', '.c', undefined); + addThis(); + + status = inSection(393); + pattern = /(^|a)b/; + string = 'ab'; + actualmatch = string.match(pattern); + expectedmatch = Array('ab', 'a'); + addThis(); + + status = inSection(394); + pattern = /^([ab]*?)(b)?(c)$/; + string = 'abac'; + actualmatch = string.match(pattern); + expectedmatch = Array('abac', 'aba', undefined, 'c'); + addThis(); + + status = inSection(395); + pattern = /^(?:.,){2}c/i; + string = 'a,b,c'; + actualmatch = string.match(pattern); + expectedmatch = Array('a,b,c'); + addThis(); + + status = inSection(396); + pattern = /^(.,){2}c/i; + string = 'a,b,c'; + actualmatch = string.match(pattern); + expectedmatch = Array('a,b,c', 'b,'); + addThis(); + + status = inSection(397); + pattern = /^(?:[^,]*,){2}c/; + string = 'a,b,c'; + actualmatch = string.match(pattern); + expectedmatch = Array('a,b,c'); + addThis(); + + status = inSection(398); + pattern = /^([^,]*,){2}c/; + string = 'a,b,c'; + actualmatch = string.match(pattern); + expectedmatch = Array('a,b,c', 'b,'); + addThis(); + + status = inSection(399); + pattern = /^([^,]*,){3}d/; + string = 'aaa,b,c,d'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaa,b,c,d', 'c,'); + addThis(); + + status = inSection(400); + pattern = /^([^,]*,){3,}d/; + string = 'aaa,b,c,d'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaa,b,c,d', 'c,'); + addThis(); + + status = inSection(401); + pattern = /^([^,]*,){0,3}d/; + string = 'aaa,b,c,d'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaa,b,c,d', 'c,'); + addThis(); + + status = inSection(402); + pattern = /^([^,]{1,3},){3}d/i; + string = 'aaa,b,c,d'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaa,b,c,d', 'c,'); + addThis(); + + status = inSection(403); + pattern = /^([^,]{1,3},){3,}d/; + string = 'aaa,b,c,d'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaa,b,c,d', 'c,'); + addThis(); + + status = inSection(404); + pattern = /^([^,]{1,3},){0,3}d/; + string = 'aaa,b,c,d'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaa,b,c,d', 'c,'); + addThis(); + + status = inSection(405); + pattern = /^([^,]{1,},){3}d/; + string = 'aaa,b,c,d'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaa,b,c,d', 'c,'); + addThis(); + + status = inSection(406); + pattern = /^([^,]{1,},){3,}d/; + string = 'aaa,b,c,d'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaa,b,c,d', 'c,'); + addThis(); + + status = inSection(407); + pattern = /^([^,]{1,},){0,3}d/; + string = 'aaa,b,c,d'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaa,b,c,d', 'c,'); + addThis(); + + status = inSection(408); + pattern = /^([^,]{0,3},){3}d/i; + string = 'aaa,b,c,d'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaa,b,c,d', 'c,'); + addThis(); + + status = inSection(409); + pattern = /^([^,]{0,3},){3,}d/; + string = 'aaa,b,c,d'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaa,b,c,d', 'c,'); + addThis(); + + status = inSection(410); + pattern = /^([^,]{0,3},){0,3}d/; + string = 'aaa,b,c,d'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaa,b,c,d', 'c,'); + addThis(); + +/* ECMA doesn't support \A + status = inSection(411); + pattern = /(?!\A)x/m; + string = 'a\nxb\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('\n'); + addThis(); +*/ + + status = inSection(412); + pattern = /^(a(b)?)+$/; + string = 'aba'; + actualmatch = string.match(pattern); + expectedmatch = Array('aba', 'a', undefined); + addThis(); + + status = inSection(413); + pattern = /^(aa(bb)?)+$/; + string = 'aabbaa'; + actualmatch = string.match(pattern); + expectedmatch = Array('aabbaa', 'aa', undefined); + addThis(); + + status = inSection(414); + pattern = /^.{9}abc.*\n/m; + string = '123\nabcabcabcabc\n'; + actualmatch = string.match(pattern); + expectedmatch = Array('abcabcabcabc\n'); + addThis(); + + status = inSection(415); + pattern = /^(a)?a$/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = Array('a', undefined); + addThis(); + + status = inSection(416); + pattern = /^(a\1?)(a\1?)(a\2?)(a\3?)$/; + string = 'aaaaaa'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaaaaa', 'a', 'aa', 'a', 'aa'); + addThis(); + +/* Can't refer to a capture before it's encountered & completed + status = inSection(417); + pattern = /^(a\1?){4}$/; + string = 'aaaaaa'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaaaaa', 'aaa'); + addThis(); +*/ + + status = inSection(418); + pattern = /^(0+)?(?:x(1))?/; + string = 'x1'; + actualmatch = string.match(pattern); + expectedmatch = Array('x1', undefined, '1'); + addThis(); + + status = inSection(419); + pattern = /^([0-9a-fA-F]+)(?:x([0-9a-fA-F]+)?)(?:x([0-9a-fA-F]+))?/; + string = '012cxx0190'; + actualmatch = string.match(pattern); + expectedmatch = Array('012cxx0190', '012c', undefined, '0190'); + addThis(); + + status = inSection(420); + pattern = /^(b+?|a){1,2}c/; + string = 'bbbac'; + actualmatch = string.match(pattern); + expectedmatch = Array('bbbac', 'a'); + addThis(); + + status = inSection(421); + pattern = /^(b+?|a){1,2}c/; + string = 'bbbbac'; + actualmatch = string.match(pattern); + expectedmatch = Array('bbbbac', 'a'); + addThis(); + + status = inSection(422); + pattern = /((?:aaaa|bbbb)cccc)?/; + string = 'aaaacccc'; + actualmatch = string.match(pattern); + expectedmatch = Array('aaaacccc', 'aaaacccc'); + addThis(); + + status = inSection(423); + pattern = /((?:aaaa|bbbb)cccc)?/; + string = 'bbbbcccc'; + actualmatch = string.match(pattern); + expectedmatch = Array('bbbbcccc', 'bbbbcccc'); + addThis(); + + + + +//----------------------------------------------------------------------------- + test(); +//----------------------------------------------------------------------------- + + + + function addThis() + { + if(omitCurrentSection()) + return; + + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; + } + + + function omitCurrentSection() + { + try + { + // current section number is in global status variable + var n = status.match(/(\d+)/)[1]; + return ((n < cnLBOUND) || (n > cnUBOUND)); + } + catch(e) + { + return false; + } + } + + + function test() + { + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); + } diff --git a/js/src/tests/non262/RegExp/perlstress-002.js b/js/src/tests/non262/RegExp/perlstress-002.js new file mode 100644 index 0000000000..288cd9ed8b --- /dev/null +++ b/js/src/tests/non262/RegExp/perlstress-002.js @@ -0,0 +1,1806 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 2002-07-07 + * SUMMARY: Testing JS RegExp engine against Perl 5 RegExp engine. + * Adjust cnLBOUND, cnUBOUND below to restrict which sections are tested. + * + * This test was created by running various patterns and strings through the + * Perl 5 RegExp engine. We saved the results below to test the JS engine. + * + * Each of the examples below is a negative test; that is, each produces a + * null match in Perl. Thus we set |expectedmatch| = |null| in each section. + * + * NOTE: ECMA/JS and Perl do differ on certain points. We have either commented + * out such sections altogether, or modified them to fit what we expect from JS. + * + * EXAMPLES: + * + * - ECMA does support (?: (?= and (?! operators, but doesn't support (?< etc. + * + * - ECMA doesn't support (?(condition) + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 85721; +var summary = 'Testing regular expression edge cases'; +var cnSingleSpace = ' '; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); +var cnLBOUND = 0; +var cnUBOUND = 1000; + + +status = inSection(1); +pattern = /abc/; +string = 'xbc'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(2); +pattern = /abc/; +string = 'axc'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(3); +pattern = /abc/; +string = 'abx'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(4); +pattern = /ab+bc/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(5); +pattern = /ab+bc/; +string = 'abq'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(6); +pattern = /ab{1,}bc/; +string = 'abq'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(7); +pattern = /ab{4,5}bc/; +string = 'abbbbc'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(8); +pattern = /ab?bc/; +string = 'abbbbc'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(9); +pattern = /^abc$/; +string = 'abcc'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(10); +pattern = /^abc$/; +string = 'aabc'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(11); +pattern = /abc$/; +string = 'aabcd'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(12); +pattern = /a.*c/; +string = 'axyzd'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(13); +pattern = /a[bc]d/; +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(14); +pattern = /a[b-d]e/; +string = 'abd'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(15); +pattern = /a[^bc]d/; +string = 'abd'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(16); +pattern = /a[^-b]c/; +string = 'a-c'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(17); +pattern = /a[^]b]c/; +string = 'a]c'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(18); +pattern = /\by\b/; +string = 'xy'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(19); +pattern = /\by\b/; +string = 'yz'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(20); +pattern = /\by\b/; +string = 'xyz'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(21); +pattern = /\Ba\B/; +string = 'a-'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(22); +pattern = /\Ba\B/; +string = '-a'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(23); +pattern = /\Ba\B/; +string = '-a-'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(24); +pattern = /\w/; +string = '-'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(25); +pattern = /\W/; +string = 'a'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(26); +pattern = /a\sb/; +string = 'a-b'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(27); +pattern = /\d/; +string = '-'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(28); +pattern = /\D/; +string = '1'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(29); +pattern = /[\w]/; +string = '-'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(30); +pattern = /[\W]/; +string = 'a'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(31); +pattern = /a[\s]b/; +string = 'a-b'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(32); +pattern = /[\d]/; +string = '-'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(33); +pattern = /[\D]/; +string = '1'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(34); +pattern = /$b/; +string = 'b'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(35); +pattern = /^(ab|cd)e/; +string = 'abcde'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(36); +pattern = /a[bcd]+dcdcde/; +string = 'adcdcde'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(37); +pattern = /(bc+d$|ef*g.|h?i(j|k))/; +string = 'effg'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(38); +pattern = /(bc+d$|ef*g.|h?i(j|k))/; +string = 'bcdd'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(39); +pattern = /[k]/; +string = 'ab'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +// MODIFIED - ECMA has different rules for paren contents. +status = inSection(40); +pattern = /(a)|\1/; +string = 'x'; +actualmatch = string.match(pattern); +//expectedmatch = null; +expectedmatch = Array("", undefined); +addThis(); + +// MODIFIED - ECMA has different rules for paren contents. +status = inSection(41); +pattern = /((\3|b)\2(a)x)+/; +string = 'aaxabxbaxbbx'; +actualmatch = string.match(pattern); +//expectedmatch = null; +expectedmatch = Array("ax", "ax", "", "a"); +addThis(); + +status = inSection(42); +pattern = /abc/i; +string = 'XBC'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(43); +pattern = /abc/i; +string = 'AXC'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(44); +pattern = /abc/i; +string = 'ABX'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(45); +pattern = /ab+bc/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(46); +pattern = /ab+bc/i; +string = 'ABQ'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(47); +pattern = /ab{1,}bc/i; +string = 'ABQ'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(48); +pattern = /ab{4,5}?bc/i; +string = 'ABBBBC'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(49); +pattern = /ab??bc/i; +string = 'ABBBBC'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(50); +pattern = /^abc$/i; +string = 'ABCC'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(51); +pattern = /^abc$/i; +string = 'AABC'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(52); +pattern = /a.*c/i; +string = 'AXYZD'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(53); +pattern = /a[bc]d/i; +string = 'ABC'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(54); +pattern = /a[b-d]e/i; +string = 'ABD'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(55); +pattern = /a[^bc]d/i; +string = 'ABD'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(56); +pattern = /a[^-b]c/i; +string = 'A-C'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(57); +pattern = /a[^]b]c/i; +string = 'A]C'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(58); +pattern = /$b/i; +string = 'B'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(59); +pattern = /^(ab|cd)e/i; +string = 'ABCDE'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(60); +pattern = /a[bcd]+dcdcde/i; +string = 'ADCDCDE'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(61); +pattern = /(bc+d$|ef*g.|h?i(j|k))/i; +string = 'EFFG'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(62); +pattern = /(bc+d$|ef*g.|h?i(j|k))/i; +string = 'BCDD'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(63); +pattern = /[k]/i; +string = 'AB'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(64); +pattern = /^(a\1?){4}$/; +string = 'aaaaaaaaa'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(65); +pattern = /^(a\1?){4}$/; +string = 'aaaaaaaaaaa'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +/* ECMA doesn't support (?( + status = inSection(66); + pattern = /^(a(?(1)\1)){4}$/; + string = 'aaaaaaaaa'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(67); + pattern = /^(a(?(1)\1)){4}$/; + string = 'aaaaaaaaaaa'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); +*/ + +/* ECMA doesn't support (?< + status = inSection(68); + pattern = /(?<=a)b/; + string = 'cb'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(69); + pattern = /(?<=a)b/; + string = 'b'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(70); + pattern = /(?<!c)b/; + string = 'cb'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); +*/ + +/* ECMA doesn't support (?(condition) + status = inSection(71); + pattern = /(?:(?i)a)b/; + string = 'aB'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(72); + pattern = /((?i)a)b/; + string = 'aB'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(73); + pattern = /(?i:a)b/; + string = 'aB'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(74); + pattern = /((?i:a))b/; + string = 'aB'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(75); + pattern = /(?:(?-i)a)b/i; + string = 'Ab'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(76); + pattern = /((?-i)a)b/i; + string = 'Ab'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(77); + pattern = /(?:(?-i)a)b/i; + string = 'AB'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(78); + pattern = /((?-i)a)b/i; + string = 'AB'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(79); + pattern = /(?-i:a)b/i; + string = 'Ab'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(80); + pattern = /((?-i:a))b/i; + string = 'Ab'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(81); + pattern = /(?-i:a)b/i; + string = 'AB'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(82); + pattern = /((?-i:a))b/i; + string = 'AB'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(83); + pattern = /((?-i:a.))b/i; + string = 'a\nB'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(84); + pattern = /((?s-i:a.))b/i; + string = 'B\nB'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); +*/ + +/* ECMA doesn't support (?< + status = inSection(85); + pattern = /(?<![cd])b/; + string = 'dbcb'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(86); + pattern = /(?<!(c|d))b/; + string = 'dbcb'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); +*/ + +status = inSection(87); +pattern = /^(?:a?b?)*$/; +string = 'a--'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(88); +pattern = /^b/; +string = 'a\nb\nc\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(89); +pattern = /()^b/; +string = 'a\nb\nc\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +/* ECMA doesn't support (?( + status = inSection(90); + pattern = /(?(1)a|b)/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(91); + pattern = /(x)?(?(1)a|b)/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(92); + pattern = /()(?(1)b|a)/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(93); + pattern = /^(\()?blah(?(1)(\)))$/; + string = 'blah)'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(94); + pattern = /^(\()?blah(?(1)(\)))$/; + string = '(blah'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(95); + pattern = /^(\(+)?blah(?(1)(\)))$/; + string = 'blah)'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(96); + pattern = /^(\(+)?blah(?(1)(\)))$/; + string = '(blah'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(97); + pattern = /(?(?{0})a|b)/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(98); + pattern = /(?(?{1})b|a)/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(99); + pattern = /(?(?!a)a|b)/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); + + status = inSection(100); + pattern = /(?(?=a)b|a)/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); +*/ + +status = inSection(101); +pattern = /^(?=(a+?))\1ab/; +string = 'aaab'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(102); +pattern = /^(?=(a+?))\1ab/; +string = 'aaab'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(103); +pattern = /([\w:]+::)?(\w+)$/; +string = 'abcd:'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(104); +pattern = /([\w:]+::)?(\w+)$/; +string = 'abcd:'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(105); +pattern = /(>a+)ab/; +string = 'aaab'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(106); +pattern = /a\Z/; +string = 'a\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(107); +pattern = /a\z/; +string = 'a\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(108); +pattern = /a$/; +string = 'a\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(109); +pattern = /a\z/; +string = 'b\na\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(110); +pattern = /a\z/m; +string = 'a\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(111); +pattern = /a\z/m; +string = 'b\na\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(112); +pattern = /aa\Z/; +string = 'aa\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(113); +pattern = /aa\z/; +string = 'aa\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(114); +pattern = /aa$/; +string = 'aa\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(115); +pattern = /aa\z/; +string = 'b\naa\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(116); +pattern = /aa\z/m; +string = 'aa\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(117); +pattern = /aa\z/m; +string = 'b\naa\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(118); +pattern = /aa\Z/; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(119); +pattern = /aa\z/; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(120); +pattern = /aa$/; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(121); +pattern = /aa\Z/; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(122); +pattern = /aa\z/; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(123); +pattern = /aa$/; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(124); +pattern = /aa\Z/; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(125); +pattern = /aa\z/; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(126); +pattern = /aa$/; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(127); +pattern = /aa\Z/m; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(128); +pattern = /aa\z/m; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(129); +pattern = /aa$/m; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(130); +pattern = /aa\Z/m; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(131); +pattern = /aa\z/m; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(132); +pattern = /aa$/m; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(133); +pattern = /aa\Z/m; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(134); +pattern = /aa\z/m; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(135); +pattern = /aa$/m; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(136); +pattern = /aa\Z/; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(137); +pattern = /aa\z/; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(138); +pattern = /aa$/; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(139); +pattern = /aa\Z/; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(140); +pattern = /aa\z/; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(141); +pattern = /aa$/; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(142); +pattern = /aa\Z/; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(143); +pattern = /aa\z/; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(144); +pattern = /aa$/; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(145); +pattern = /aa\Z/m; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(146); +pattern = /aa\z/m; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(147); +pattern = /aa$/m; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(148); +pattern = /aa\Z/m; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(149); +pattern = /aa\z/m; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(150); +pattern = /aa$/m; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(151); +pattern = /aa\Z/m; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(152); +pattern = /aa\z/m; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(153); +pattern = /aa$/m; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(154); +pattern = /ab\Z/; +string = 'ab\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(155); +pattern = /ab\z/; +string = 'ab\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(156); +pattern = /ab$/; +string = 'ab\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(157); +pattern = /ab\z/; +string = 'b\nab\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(158); +pattern = /ab\z/m; +string = 'ab\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(159); +pattern = /ab\z/m; +string = 'b\nab\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(160); +pattern = /ab\Z/; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(161); +pattern = /ab\z/; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(162); +pattern = /ab$/; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(163); +pattern = /ab\Z/; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(164); +pattern = /ab\z/; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(165); +pattern = /ab$/; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(166); +pattern = /ab\Z/; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(167); +pattern = /ab\z/; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(168); +pattern = /ab$/; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(169); +pattern = /ab\Z/m; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(170); +pattern = /ab\z/m; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(171); +pattern = /ab$/m; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(172); +pattern = /ab\Z/m; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(173); +pattern = /ab\z/m; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(174); +pattern = /ab$/m; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(175); +pattern = /ab\Z/m; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(176); +pattern = /ab\z/m; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(177); +pattern = /ab$/m; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(178); +pattern = /ab\Z/; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(179); +pattern = /ab\z/; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(180); +pattern = /ab$/; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(181); +pattern = /ab\Z/; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(182); +pattern = /ab\z/; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(183); +pattern = /ab$/; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(184); +pattern = /ab\Z/; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(185); +pattern = /ab\z/; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(186); +pattern = /ab$/; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(187); +pattern = /ab\Z/m; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(188); +pattern = /ab\z/m; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(189); +pattern = /ab$/m; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(190); +pattern = /ab\Z/m; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(191); +pattern = /ab\z/m; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(192); +pattern = /ab$/m; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(193); +pattern = /ab\Z/m; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(194); +pattern = /ab\z/m; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(195); +pattern = /ab$/m; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(196); +pattern = /abb\Z/; +string = 'abb\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(197); +pattern = /abb\z/; +string = 'abb\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(198); +pattern = /abb$/; +string = 'abb\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(199); +pattern = /abb\z/; +string = 'b\nabb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(200); +pattern = /abb\z/m; +string = 'abb\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(201); +pattern = /abb\z/m; +string = 'b\nabb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(202); +pattern = /abb\Z/; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(203); +pattern = /abb\z/; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(204); +pattern = /abb$/; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(205); +pattern = /abb\Z/; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(206); +pattern = /abb\z/; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(207); +pattern = /abb$/; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(208); +pattern = /abb\Z/; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(209); +pattern = /abb\z/; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(210); +pattern = /abb$/; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(211); +pattern = /abb\Z/m; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(212); +pattern = /abb\z/m; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(213); +pattern = /abb$/m; +string = 'ac\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(214); +pattern = /abb\Z/m; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(215); +pattern = /abb\z/m; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(216); +pattern = /abb$/m; +string = 'b\nac\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(217); +pattern = /abb\Z/m; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(218); +pattern = /abb\z/m; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(219); +pattern = /abb$/m; +string = 'b\nac'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(220); +pattern = /abb\Z/; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(221); +pattern = /abb\z/; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(222); +pattern = /abb$/; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(223); +pattern = /abb\Z/; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(224); +pattern = /abb\z/; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(225); +pattern = /abb$/; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(226); +pattern = /abb\Z/; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(227); +pattern = /abb\z/; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(228); +pattern = /abb$/; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(229); +pattern = /abb\Z/m; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(230); +pattern = /abb\z/m; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(231); +pattern = /abb$/m; +string = 'ca\nb\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(232); +pattern = /abb\Z/m; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(233); +pattern = /abb\z/m; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(234); +pattern = /abb$/m; +string = 'b\nca\n'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(235); +pattern = /abb\Z/m; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(236); +pattern = /abb\z/m; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(237); +pattern = /abb$/m; +string = 'b\nca'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(238); +pattern = /a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/; +string = 'x'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(239); +pattern = /\GX.*X/; +string = 'aaaXbX'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(240); +pattern = /\.c(pp|xx|c)?$/i; +string = 'Changes'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(241); +pattern = /^([a-z]:)/; +string = 'C:/'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(242); +pattern = /(\w)?(abc)\1b/; +string = 'abcab'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +/* ECMA doesn't support (?( + status = inSection(243); + pattern = /^(a)?(?(1)a|b)+$/; + string = 'a'; + actualmatch = string.match(pattern); + expectedmatch = null; + addThis(); +*/ + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function addThis() +{ + if(omitCurrentSection()) + return; + + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function omitCurrentSection() +{ + try + { + // current section number is in global status variable + var n = status.match(/(\d+)/)[1]; + return ((n < cnLBOUND) || (n > cnUBOUND)); + } + catch(e) + { + return false; + } +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/properties-001.js b/js/src/tests/non262/RegExp/properties-001.js new file mode 100644 index 0000000000..b9cb65e959 --- /dev/null +++ b/js/src/tests/non262/RegExp/properties-001.js @@ -0,0 +1,87 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + * File Name: RegExp/properties-001.js + * ECMA Section: 15.7.6.js + * Description: Based on ECMA 2 Draft 7 February 1999 + * + * Author: christine@netscape.com + * Date: 19 February 1999 + */ +var SECTION = "RegExp/properties-001.js"; +var TITLE = "Properties of RegExp Instances"; + +AddRegExpCases( new RegExp, "(?:)", false, false, false, 0 ); +AddRegExpCases( /.*/, ".*", false, false, false, 0 ); +AddRegExpCases( /[\d]{5}/g, "[\\d]{5}", true, false, false, 0 ); +AddRegExpCases( /[\S]?$/i, "[\\S]?$", false, true, false, 0 ); +AddRegExpCases( /^([a-z]*)[^\w\s\f\n\r]+/m, "^([a-z]*)[^\\w\\s\\f\\n\\r]+", false, false, true, 0 ); +AddRegExpCases( /[\D]{1,5}[\ -][\d]/gi, "[\\D]{1,5}[\\ -][\\d]", true, true, false, 0 ); +AddRegExpCases( /[a-zA-Z0-9]*/gm, "[a-zA-Z0-9]*", true, false, true, 0 ); +AddRegExpCases( /x|y|z/gim, "x|y|z", true, true, true, 0 ); + +AddRegExpCases( /\u0051/im, "\\u0051", false, true, true, 0 ); +AddRegExpCases( /\x45/gm, "\\x45", true, false, true, 0 ); +AddRegExpCases( /\097/gi, "\\097", true, true, false, 0 ); + +test(); + +function AddRegExpCases( re, s, g, i, m, l ) { + + AddTestCase( re + ".test == RegExp.prototype.test", + true, + re.test == RegExp.prototype.test ); + + AddTestCase( re + ".toString == RegExp.prototype.toString", + true, + re.toString == RegExp.prototype.toString ); + + AddTestCase( re + ".contructor == RegExp.prototype.constructor", + true, + re.constructor == RegExp.prototype.constructor ); + + AddTestCase( re + ".compile == RegExp.prototype.compile", + true, + re.compile == RegExp.prototype.compile ); + + AddTestCase( re + ".exec == RegExp.prototype.exec", + true, + re.exec == RegExp.prototype.exec ); + + // properties + + AddTestCase( re + ".source", + s, + re.source ); + +/* + * http://bugzilla.mozilla.org/show_bug.cgi?id=225550 changed + * the behavior of toString() and toSource() on empty regexps. + * So branch if |s| is the empty string - + */ + var S = s? s : '(?:)'; + + AddTestCase( re + ".toString()", + "/" + S +"/" + (g?"g":"") + (i?"i":"") +(m?"m":""), + re.toString() ); + + AddTestCase( re + ".global", + g, + re.global ); + + AddTestCase( re + ".ignoreCase", + i, + re.ignoreCase ); + + AddTestCase( re + ".multiline", + m, + re.multiline); + + AddTestCase( re + ".lastIndex", + l, + re.lastIndex ); +} diff --git a/js/src/tests/non262/RegExp/properties-002.js b/js/src/tests/non262/RegExp/properties-002.js new file mode 100644 index 0000000000..596dce522e --- /dev/null +++ b/js/src/tests/non262/RegExp/properties-002.js @@ -0,0 +1,128 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + * File Name: RegExp/properties-002.js + * ECMA Section: 15.7.6.js + * Description: Based on ECMA 2 Draft 7 February 1999 + * + * Author: christine@netscape.com + * Date: 19 February 1999 + */ +//----------------------------------------------------------------------------- +var SECTION = "RegExp/properties-002.js"; +var TITLE = "Properties of RegExp Instances"; +var BUGNUMBER ="124339"; + +printBugNumber(BUGNUMBER); + +re_1 = /\cA?/g; +re_1.lastIndex = Math.pow(2,31); +AddRegExpCases( re_1, "\\cA?", true, false, false, Math.pow(2,31) ); + +re_2 = /\w*/i; +re_2.lastIndex = Math.pow(2,32) -1; +AddRegExpCases( re_2, "\\w*", false, true, false, Math.pow(2,32)-1 ); + +re_3 = /\*{0,80}/m; +re_3.lastIndex = Math.pow(2,31) -1; +AddRegExpCases( re_3, "\\*{0,80}", false, false, true, Math.pow(2,31) -1 ); + +re_4 = /^./gim; +re_4.lastIndex = Math.pow(2,30) -1; +AddRegExpCases( re_4, "^.", true, true, true, Math.pow(2,30) -1 ); + +re_5 = /\B/; +re_5.lastIndex = Math.pow(2,30); +AddRegExpCases( re_5, "\\B", false, false, false, Math.pow(2,30) ); + +/* + * Brendan: "need to test cases Math.pow(2,32) and greater to see + * whether they round-trip." Reason: thanks to the work done in + * http://bugzilla.mozilla.org/show_bug.cgi?id=124339, lastIndex + * is now stored as a double instead of a uint32_t (unsigned integer). + * + * Note 2^32 -1 is the upper bound for uint32's, but doubles can go + * all the way up to Number.MAX_VALUE. So that's why we need cases + * between those two numbers. + * + */ +re_6 = /\B/; +re_6.lastIndex = Math.pow(2,32); +AddRegExpCases( re_6, "\\B", false, false, false, Math.pow(2,32) ); + +re_7 = /\B/; +re_7.lastIndex = Math.pow(2,32) + 1; +AddRegExpCases( re_7, "\\B", false, false, false, Math.pow(2,32) + 1 ); + +re_8 = /\B/; +re_8.lastIndex = Math.pow(2,32) * 2; +AddRegExpCases( re_8, "\\B", false, false, false, Math.pow(2,32) * 2 ); + +re_9 = /\B/; +re_9.lastIndex = Math.pow(2,40); +AddRegExpCases( re_9, "\\B", false, false, false, Math.pow(2,40) ); + +re_10 = /\B/; +re_10.lastIndex = Number.MAX_VALUE; +AddRegExpCases( re_10, "\\B", false, false, false, Number.MAX_VALUE ); + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function AddRegExpCases( re, s, g, i, m, l ){ + + AddTestCase( re + ".test == RegExp.prototype.test", + true, + re.test == RegExp.prototype.test ); + + AddTestCase( re + ".toString == RegExp.prototype.toString", + true, + re.toString == RegExp.prototype.toString ); + + AddTestCase( re + ".contructor == RegExp.prototype.constructor", + true, + re.constructor == RegExp.prototype.constructor ); + + AddTestCase( re + ".compile == RegExp.prototype.compile", + true, + re.compile == RegExp.prototype.compile ); + + AddTestCase( re + ".exec == RegExp.prototype.exec", + true, + re.exec == RegExp.prototype.exec ); + + // properties + + AddTestCase( re + ".source", + s, + re.source ); + + AddTestCase( re + ".toString()", + "/" + s +"/" + (g?"g":"") + (i?"i":"") +(m?"m":""), + re.toString() ); + + AddTestCase( re + ".global", + g, + re.global ); + + AddTestCase( re + ".ignoreCase", + i, + re.ignoreCase ); + + AddTestCase( re + ".multiline", + m, + re.multiline); + + AddTestCase( re + ".lastIndex", + l, + re.lastIndex ); +} diff --git a/js/src/tests/non262/RegExp/prototype-different-global.js b/js/src/tests/non262/RegExp/prototype-different-global.js new file mode 100644 index 0000000000..34fc5ee8a1 --- /dev/null +++ b/js/src/tests/non262/RegExp/prototype-different-global.js @@ -0,0 +1,28 @@ +function test(otherGlobal) { + var otherRegExp = otherGlobal.RegExp; + + for (let name of ["global", "ignoreCase", "multiline", "sticky", "unicode", "source"]) { + let getter = Object.getOwnPropertyDescriptor(RegExp.prototype, name).get; + assertEq(typeof getter, "function"); + + // Note: TypeError gets reported from wrong global if cross-compartment, + // so we test both cases. + let ex; + try { + getter.call(otherRegExp.prototype); + } catch (e) { + ex = e; + } + assertEq(ex instanceof TypeError || ex instanceof otherGlobal.TypeError, true); + } + + let flagsGetter = Object.getOwnPropertyDescriptor(RegExp.prototype, "flags").get; + assertEq(flagsGetter.call(otherRegExp.prototype), ""); + + assertEq(RegExp.prototype.toString.call(otherRegExp.prototype), "/(?:)/"); +} +test(newGlobal()); +test(newGlobal({newCompartment: true})); + +if (typeof reportCompare === "function") + reportCompare(0, 0); diff --git a/js/src/tests/non262/RegExp/prototype.js b/js/src/tests/non262/RegExp/prototype.js new file mode 100644 index 0000000000..d23336fcd5 --- /dev/null +++ b/js/src/tests/non262/RegExp/prototype.js @@ -0,0 +1,37 @@ +const t = RegExp.prototype; + +let properties = "toString,compile,exec,test," + + "flags,dotAll,global,hasIndices,ignoreCase,multiline,source,sticky,unicode," + + "constructor," + + "Symbol(Symbol.match),Symbol(Symbol.replace),Symbol(Symbol.search),Symbol(Symbol.split)"; +if (Object.prototype.toSource) { + properties = "toSource," + properties; +} +if (Symbol.matchAll) { + properties += ",Symbol(Symbol.matchAll)"; +} +assertEqArray(Reflect.ownKeys(t).map(String).sort(), properties.split(",").sort()); + + +// Invoking getters on the prototype should not throw +function getter(name) { + return Object.getOwnPropertyDescriptor(t, name).get.call(t); +} + +assertEq(getter("flags"), ""); +assertEq(getter("global"), undefined); +assertEq(getter("ignoreCase"), undefined); +assertEq(getter("multiline"), undefined); +assertEq(getter("source"), "(?:)"); +assertEq(getter("sticky"), undefined); +assertEq(getter("unicode"), undefined); + +assertEq(t.toString(), "/(?:)/"); + +// The methods don't work with the prototype +assertThrowsInstanceOf(() => t.compile("b", "i"), TypeError); +assertThrowsInstanceOf(() => t.test("x"), TypeError); +assertThrowsInstanceOf(() => t.exec("x"), TypeError); + +if (typeof reportCompare === "function") + reportCompare(0, 0); diff --git a/js/src/tests/non262/RegExp/regexp-enumerate-001.js b/js/src/tests/non262/RegExp/regexp-enumerate-001.js new file mode 100644 index 0000000000..a12bd4589a --- /dev/null +++ b/js/src/tests/non262/RegExp/regexp-enumerate-001.js @@ -0,0 +1,79 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + File Name: regexp-enumerate-001.js + ECMA V2 Section: + Description: Regression Test. + + If instance Native Object have properties that are enumerable, + JavaScript enumerated through the properties twice. This only + happened if objects had been instantiated, but their properties + had not been enumerated. ie, the object inherited properties + from its prototype that are enumerated. + + In the core JavaScript, this is only a problem with RegExp + objects, since the inherited properties of most core JavaScript + objects are not enumerated. + + Author: christine@netscape.com, pschwartau@netscape.com + Date: 12 November 1997 + Modified: 14 July 2002 + Reason: See http://bugzilla.mozilla.org/show_bug.cgi?id=155291 + ECMA-262 Ed.3 Sections 15.10.7.1 through 15.10.7.5 + RegExp properties should be DontEnum + * + */ +// onerror = err; + +var SECTION = "regexp-enumerate-001"; +var TITLE = "Regression Test for Enumerating Properties"; + +var BUGNUMBER="339403"; + +printBugNumber(BUGNUMBER); +writeHeaderToLog( SECTION + " "+ TITLE); + +/* + * This test expects RegExp instances to have four enumerated properties: + * source, global, ignoreCase, and lastIndex + * + * 99.01.25: now they also have a multiLine instance property. + * + */ + + +var r = new RegExp(); + +var e = new Array(); + +var t = new TestRegExp(); + +for ( p in r ) { e[e.length] = { property:p, value:r[p] }; t.addProperty( p, r[p]) }; + +new TestCase( "r = new RegExp(); e = new Array(); "+ + "for ( p in r ) { e[e.length] = { property:p, value:r[p] }; e.length", + 0, + e.length ); + +test(); + +function TestRegExp() { + this.addProperty = addProperty; +} +function addProperty(name, value) { + var pass = false; + + if ( eval("this."+name) != void 0 ) { + pass = true; + } else { + eval( "this."+ name+" = "+ false ); + } + + new TestCase( "Property: " + name +" already enumerated?", + false, + pass ); +} diff --git a/js/src/tests/non262/RegExp/regexp-space-character-class.js b/js/src/tests/non262/RegExp/regexp-space-character-class.js new file mode 100644 index 0000000000..a429b54bbd --- /dev/null +++ b/js/src/tests/non262/RegExp/regexp-space-character-class.js @@ -0,0 +1,27 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this +* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var gTestfile = 'regexp-space-character-class.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 514808; +var summary = 'Correct space character class in regexes'; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ +printBugNumber(BUGNUMBER); +printStatus (summary); + +// NOTE: White space and line terminators are now tested in +// non262/RegExp/character-class-escape-s.js. + +var non_space_chars = [ "\u200b", "\u200c", "\u200d" ]; + +reportCompare(non_space_chars.some(function(ch){ return /\s/.test(ch); }), false, summary); +} diff --git a/js/src/tests/non262/RegExp/regress-001.js b/js/src/tests/non262/RegExp/regress-001.js new file mode 100644 index 0000000000..163a7a366b --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-001.js @@ -0,0 +1,44 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + * File Name: RegExp/regress-001.js + * ECMA Section: N/A + * Description: Regression test case: + * JS regexp anchoring on empty match bug + * http://bugzilla.mozilla.org/show_bug.cgi?id=2157 + * + * Author: christine@netscape.com + * Date: 19 February 1999 + */ +var SECTION = "RegExp/hex-001.js"; +var TITLE = "JS regexp anchoring on empty match bug"; +var BUGNUMBER = "2157"; + +printBugNumber(BUGNUMBER); + +AddRegExpCases( /a||b/.exec(''), + "/a||b/.exec('')", + 1, + [''] ); + +test(); + +function AddRegExpCases( regexp, str_regexp, length, matches_array ) { + + AddTestCase( + "( " + str_regexp + " ).length", + regexp.length, + regexp.length ); + + + for ( var matches = 0; matches < matches_array.length; matches++ ) { + AddTestCase( + "( " + str_regexp + " )[" + matches +"]", + matches_array[matches], + regexp[matches] ); + } +} diff --git a/js/src/tests/non262/RegExp/regress-100199.js b/js/src/tests/non262/RegExp/regress-100199.js new file mode 100644 index 0000000000..c43665a9a7 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-100199.js @@ -0,0 +1,271 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 17 September 2001 + * + * SUMMARY: Regression test for Bugzilla bug 100199 + * See http://bugzilla.mozilla.org/show_bug.cgi?id=100199 + * + * The empty character class [] is a valid RegExp construct: the condition + * that a given character belong to a set containing no characters. As such, + * it can never be met and is always FALSE. Similarly, [^] is a condition + * that matches any given character and is always TRUE. + * + * Neither one of these conditions should cause syntax errors in a RegExp. + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 100199; +var summary = '[], [^] are valid RegExp conditions. Should not cause errors -'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +pattern = /[]/; +string = 'abc'; +status = inSection(1); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = ''; +status = inSection(2); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = '['; +status = inSection(3); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = '/'; +status = inSection(4); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = '['; +status = inSection(5); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = ']'; +status = inSection(6); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = '[]'; +status = inSection(7); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = '[ ]'; +status = inSection(8); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = ']['; +status = inSection(9); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + + +pattern = /a[]/; +string = 'abc'; +status = inSection(10); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = ''; +status = inSection(11); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = 'a['; +status = inSection(12); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = 'a[]'; +status = inSection(13); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = '['; +status = inSection(14); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = ']'; +status = inSection(15); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = '[]'; +status = inSection(16); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = '[ ]'; +status = inSection(17); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +string = ']['; +status = inSection(18); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + + +pattern = /[^]/; +string = 'abc'; +status = inSection(19); +actualmatch = string.match(pattern); +expectedmatch = Array('a'); +addThis(); + +string = ''; +status = inSection(20); +actualmatch = string.match(pattern); +expectedmatch = null; //there are no characters to test against the condition +addThis(); + +string = '\/'; +status = inSection(21); +actualmatch = string.match(pattern); +expectedmatch = Array('/'); +addThis(); + +string = '\['; +status = inSection(22); +actualmatch = string.match(pattern); +expectedmatch = Array('['); +addThis(); + +string = '['; +status = inSection(23); +actualmatch = string.match(pattern); +expectedmatch = Array('['); +addThis(); + +string = ']'; +status = inSection(24); +actualmatch = string.match(pattern); +expectedmatch = Array(']'); +addThis(); + +string = '[]'; +status = inSection(25); +actualmatch = string.match(pattern); +expectedmatch = Array('['); +addThis(); + +string = '[ ]'; +status = inSection(26); +actualmatch = string.match(pattern); +expectedmatch = Array('['); +addThis(); + +string = ']['; +status = inSection(27); +actualmatch = string.match(pattern); +expectedmatch = Array(']'); +addThis(); + + +pattern = /a[^]/; +string = 'abc'; +status = inSection(28); +actualmatch = string.match(pattern); +expectedmatch = Array('ab'); +addThis(); + +string = ''; +status = inSection(29); +actualmatch = string.match(pattern); +expectedmatch = null; //there are no characters to test against the condition +addThis(); + +string = 'a['; +status = inSection(30); +actualmatch = string.match(pattern); +expectedmatch = Array('a['); +addThis(); + +string = 'a]'; +status = inSection(31); +actualmatch = string.match(pattern); +expectedmatch = Array('a]'); +addThis(); + +string = 'a[]'; +status = inSection(32); +actualmatch = string.match(pattern); +expectedmatch = Array('a['); +addThis(); + +string = 'a[ ]'; +status = inSection(33); +actualmatch = string.match(pattern); +expectedmatch = Array('a['); +addThis(); + +string = 'a]['; +status = inSection(34); +actualmatch = string.match(pattern); +expectedmatch = Array('a]'); +addThis(); + + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-105972.js b/js/src/tests/non262/RegExp/regress-105972.js new file mode 100644 index 0000000000..ab6d46ba47 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-105972.js @@ -0,0 +1,121 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 22 October 2001 + * + * SUMMARY: Regression test for Bugzilla bug 105972: + * "/^.*?$/ will not match anything" + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=105972 + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 105972; +var summary = 'Regression test for Bugzilla bug 105972'; +var cnEmptyString = ''; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +/* + * The bug: this match was coming up null in Rhino and SpiderMonkey. + * It should match the whole string. The reason: + * + * The * operator is greedy, but *? is non-greedy: it will stop + * at the simplest match it can find. But the pattern here asks us + * to match till the end of the string. So the simplest match must + * go all the way out to the end, and *? has no choice but to do it. + */ +status = inSection(1); +pattern = /^.*?$/; +string = 'Hello World'; +actualmatch = string.match(pattern); +expectedmatch = Array(string); +addThis(); + + +/* + * Leave off the '$' condition - here we expect the empty string. + * Unlike the above pattern, we don't have to match till the end of + * the string, so the non-greedy operator *? doesn't try to... + */ +status = inSection(2); +pattern = /^.*?/; +string = 'Hello World'; +actualmatch = string.match(pattern); +expectedmatch = Array(cnEmptyString); +addThis(); + + +/* + * Try '$' combined with an 'or' operator. + * + * The operator *? will consume the string from left to right, + * attempting to satisfy the condition (:|$). When it hits ':', + * the match will stop because the operator *? is non-greedy. + * + * The submatch $1 = (:|$) will contain the ':' + */ +status = inSection(3); +pattern = /^.*?(:|$)/; +string = 'Hello: World'; +actualmatch = string.match(pattern); +expectedmatch = Array('Hello:', ':'); +addThis(); + + +/* + * Again, '$' combined with an 'or' operator. + * + * The operator * will consume the string from left to right, + * attempting to satisfy the condition (:|$). When it hits ':', + * the match will not stop since * is greedy. The match will + * continue until it hits $, the end-of-string boundary. + * + * The submatch $1 = (:|$) will contain the empty string + * conceived to exist at the end-of-string boundary. + */ +status = inSection(4); +pattern = /^.*(:|$)/; +string = 'Hello: World'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, cnEmptyString); +addThis(); + + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-119909.js b/js/src/tests/non262/RegExp/regress-119909.js new file mode 100644 index 0000000000..21a8e7750d --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-119909.js @@ -0,0 +1,55 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 14 Jan 2002 + * SUMMARY: Shouldn't crash on regexps with many nested parentheses + * See http://bugzilla.mozilla.org/show_bug.cgi?id=119909 + * + */ +//----------------------------------------------------------------------------- +var BUGNUMBER = 119909; +var summary = "Shouldn't crash on regexps with many nested parentheses"; +var NO_BACKREFS = false; +var DO_BACKREFS = true; + + +//-------------------------------------------------- +test(); +//-------------------------------------------------- + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus(summary); + + testThis(500, NO_BACKREFS, 'hello', 'goodbye'); + testThis(500, DO_BACKREFS, 'hello', 'goodbye'); + + reportCompare('No Crash', 'No Crash', ''); +} + + +/* + * Creates a regexp pattern like (((((((((hello))))))))) + * and tests str.search(), str.match(), str.replace() + */ +function testThis(numParens, doBackRefs, strOriginal, strReplace) +{ + var openParen = doBackRefs? '(' : '(?:'; + var closeParen = ')'; + var pattern = ''; + + for (var i=0; i<numParens; i++) {pattern += openParen;} + pattern += strOriginal; + for (i=0; i<numParens; i++) {pattern += closeParen;} + var re = new RegExp(pattern); + + var res = strOriginal.search(re); + res = strOriginal.match(re); + res = strOriginal.replace(re, strReplace); +} diff --git a/js/src/tests/non262/RegExp/regress-122076.js b/js/src/tests/non262/RegExp/regress-122076.js new file mode 100644 index 0000000000..d4b16dbd9b --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-122076.js @@ -0,0 +1,76 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 12 Feb 2002 + * SUMMARY: Don't crash on invalid regexp literals / \\/ / + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=122076 + * The function checkURL() below sometimes caused a compile-time error: + * + * SyntaxError: unterminated parenthetical (: + * + * However, sometimes it would cause a crash instead. The presence of + * other functions below is merely fodder to help provoke the crash. + * The constant |STRESS| is number of times we'll try to crash on this. + * + */ +//----------------------------------------------------------------------------- +var BUGNUMBER = 122076; +var summary = "Don't crash on invalid regexp literals / \\/ /"; +var STRESS = 10; +var sEval = ''; + +printBugNumber(BUGNUMBER); +printStatus(summary); + + +sEval += 'function checkDate()' +sEval += '{' +sEval += 'return (this.value.search(/^[012]?\d\/[0123]?\d\/[0]\d$/) != -1);' +sEval += '}' + +sEval += 'function checkDNSName()' +sEval += '{' +sEval += ' return (this.value.search(/^([\w\-]+\.)+([\w\-]{2,3})$/) != -1);' +sEval += '}' + +sEval += 'function checkEmail()' +sEval += '{' +sEval += ' return (this.value.search(/^([\w\-]+\.)*[\w\-]+@([\w\-]+\.)+([\w\-]{2,3})$/) != -1);' +sEval += '}' + +sEval += 'function checkHostOrIP()' +sEval += '{' +sEval += ' if (this.value.search(/^([\w\-]+\.)+([\w\-]{2,3})$/) == -1)' +sEval += ' return (this.value.search(/^[1-2]?\d{1,2}\.[1-2]?\d{1,2}\.[1-2]?\d{1,2}\.[1-2]?\d{1,2}$/) != -1);' +sEval += ' else' +sEval += ' return true;' +sEval += '}' + +sEval += 'function checkIPAddress()' +sEval += '{' +sEval += ' return (this.value.search(/^[1-2]?\d{1,2}\.[1-2]?\d{1,2}\.[1-2]?\d{1,2}\.[1-2]?\d{1,2}$/) != -1);' +sEval += '}' + +sEval += 'function checkURL()' +sEval += '{' +sEval += ' return (this.value.search(/^(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,4}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\/\*\$+@&#;`~=%!]*)(\.\w{2,})?)*\/?)$/) != -1);' +sEval += '}' + + +for (var i=0; i<STRESS; i++) +{ + try + { + eval(sEval); + } + catch(e) + { + } +} + +reportCompare('No Crash', 'No Crash', ''); diff --git a/js/src/tests/non262/RegExp/regress-123437.js b/js/src/tests/non262/RegExp/regress-123437.js new file mode 100644 index 0000000000..3a07584064 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-123437.js @@ -0,0 +1,76 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 04 Feb 2002 + * SUMMARY: regexp backreferences must hold |undefined| if not used + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=123437 (SpiderMonkey) + * See http://bugzilla.mozilla.org/show_bug.cgi?id=123439 (Rhino) + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 123437; +var summary = 'regexp backreferences must hold |undefined| if not used'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +pattern = /(a)?a/; +string = 'a'; +status = inSection(1); +actualmatch = string.match(pattern); +expectedmatch = Array('a', undefined); +addThis(); + +pattern = /a|(b)/; +string = 'a'; +status = inSection(2); +actualmatch = string.match(pattern); +expectedmatch = Array('a', undefined); +addThis(); + +pattern = /(a)?(a)/; +string = 'a'; +status = inSection(3); +actualmatch = string.match(pattern); +expectedmatch = Array('a', undefined, 'a'); +addThis(); + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-165353.js b/js/src/tests/non262/RegExp/regress-165353.js new file mode 100644 index 0000000000..e95f1514b3 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-165353.js @@ -0,0 +1,86 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 31 August 2002 + * SUMMARY: RegExp conformance test + * See http://bugzilla.mozilla.org/show_bug.cgi?id=165353 + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 165353; +var summary = 'RegExp conformance test'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +pattern = /^([a-z]+)*[a-z]$/; +status = inSection(1); +string = 'a'; +actualmatch = string.match(pattern); +expectedmatch = Array('a', undefined); +addThis(); + +status = inSection(2); +string = 'ab'; +actualmatch = string.match(pattern); +expectedmatch = Array('ab', 'a'); +addThis(); + +status = inSection(3); +string = 'abc'; +actualmatch = string.match(pattern); +expectedmatch = Array('abc', 'ab'); +addThis(); + + +string = 'www.netscape.com'; +status = inSection(4); +pattern = /^(([a-z]+)*[a-z]\.)+[a-z]{2,}$/; +actualmatch = string.match(pattern); +expectedmatch = Array('www.netscape.com', 'netscape.', 'netscap'); +addThis(); + +// add one more capturing parens to the previous regexp - +status = inSection(5); +pattern = /^(([a-z]+)*([a-z])\.)+[a-z]{2,}$/; +actualmatch = string.match(pattern); +expectedmatch = Array('www.netscape.com', 'netscape.', 'netscap', 'e'); +addThis(); + + + +//------------------------------------------------------------------------------------------------- +test(); +//------------------------------------------------------------------------------------------------- + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-169497.js b/js/src/tests/non262/RegExp/regress-169497.js new file mode 100644 index 0000000000..d4c7b668fa --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-169497.js @@ -0,0 +1,69 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 31 August 2002 + * SUMMARY: RegExp conformance test + * See http://bugzilla.mozilla.org/show_bug.cgi?id=169497 + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 169497; +var summary = 'RegExp conformance test'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var sBody = ''; +var sHTML = ''; +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + +sBody += '<body onXXX="alert(event.type);">\n'; +sBody += '<p>Kibology for all<\/p>\n'; +sBody += '<p>All for Kibology<\/p>\n'; +sBody += '<\/body>'; + +sHTML += '<html>\n'; +sHTML += sBody; +sHTML += '\n<\/html>'; + +status = inSection(1); +string = sHTML; +pattern = /<body.*>((.*\n?)*?)<\/body>/i; +actualmatch = string.match(pattern); +expectedmatch = Array(sBody, '\n<p>Kibology for all</p>\n<p>All for Kibology</p>\n', '<p>All for Kibology</p>\n'); +addThis(); + + + +//------------------------------------------------------------------------------------------------- +test(); +//------------------------------------------------------------------------------------------------- + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-169534.js b/js/src/tests/non262/RegExp/regress-169534.js new file mode 100644 index 0000000000..df011f2d32 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-169534.js @@ -0,0 +1,58 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 20 Sep 2002 + * SUMMARY: RegExp conformance test + * See http://bugzilla.mozilla.org/show_bug.cgi?id=169534 + * + */ +//----------------------------------------------------------------------------- +var UBound = 0; +var BUGNUMBER = 169534; +var summary = 'RegExp conformance test'; +var status = ''; +var statusitems = []; +var actual = ''; +var actualvalues = []; +var expect= ''; +var expectedvalues = []; + + +status = inSection(1); +var re = /(\|)([\w\x81-\xff ]*)(\|)([\/a-z][\w:\/\.]*\.[a-z]{3,4})(\|)/ig; +var str = "To sign up click |here|https://www.xxxx.org/subscribe.htm|"; +actual = str.replace(re, '<a href="$4">$2</a>'); +expect = 'To sign up click <a href="https://www.xxxx.org/subscribe.htm">here</a>'; +addThis(); + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function addThis() +{ + statusitems[UBound] = status; + actualvalues[UBound] = actual; + expectedvalues[UBound] = expect; + UBound++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus(summary); + + for (var i=0; i<UBound; i++) + { + reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]); + } +} diff --git a/js/src/tests/non262/RegExp/regress-187133.js b/js/src/tests/non262/RegExp/regress-187133.js new file mode 100644 index 0000000000..3a939fc7bd --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-187133.js @@ -0,0 +1,106 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 06 January 2003 + * SUMMARY: RegExp conformance test + * See http://bugzilla.mozilla.org/show_bug.cgi?id=187133 + * + * The tests here employ the regular expression construct: + * + * (?!pattern) + * + * This is a "zero-width lookahead negative assertion". + * From the Perl documentation: + * + * For example, /foo(?!bar)/ matches any occurrence + * of 'foo' that isn't followed by 'bar'. + * + * It is "zero-width" means that it does not consume any characters and that + * the parens are non-capturing. A non-null match array in the example above + * will have only have length 1, not 2. + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 187133; +var summary = 'RegExp conformance test'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +pattern = /(\.(?!com|org)|\/)/; +status = inSection(1); +string = 'ah.info'; +actualmatch = string.match(pattern); +expectedmatch = ['.', '.']; +addThis(); + +status = inSection(2); +string = 'ah/info'; +actualmatch = string.match(pattern); +expectedmatch = ['/', '/']; +addThis(); + +status = inSection(3); +string = 'ah.com'; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + + +pattern = /(?!a|b)|c/; +status = inSection(4); +string = ''; +actualmatch = string.match(pattern); +expectedmatch = ['']; +addThis(); + +status = inSection(5); +string = 'bc'; +actualmatch = string.match(pattern); +expectedmatch = ['']; +addThis(); + +status = inSection(6); +string = 'd'; +actualmatch = string.match(pattern); +expectedmatch = ['']; +addThis(); + + + + +//------------------------------------------------------------------------------------------------- +test(); +//------------------------------------------------------------------------------------------------- + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-188206.js b/js/src/tests/non262/RegExp/regress-188206.js new file mode 100644 index 0000000000..0ca4d46610 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-188206.js @@ -0,0 +1,182 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 21 January 2003 + * SUMMARY: Invalid use of regexp quantifiers should generate SyntaxErrors + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=188206 + * and http://bugzilla.mozilla.org/show_bug.cgi?id=85721#c48 etc. + * and http://bugzilla.mozilla.org/show_bug.cgi?id=190685 + * and http://bugzilla.mozilla.org/show_bug.cgi?id=197451 + */ +//----------------------------------------------------------------------------- +var UBound = 0; +var BUGNUMBER = 188206; +var summary = 'Invalid use of regexp quantifiers should generate SyntaxErrors'; +var TEST_PASSED = 'SyntaxError'; +var TEST_FAILED = 'Generated an error, but NOT a SyntaxError!'; +var TEST_FAILED_BADLY = 'Did not generate ANY error!!!'; +var CHECK_PASSED = 'Should not generate an error'; +var CHECK_FAILED = 'Generated an error!'; +var status = ''; +var statusitems = []; +var actual = ''; +var actualvalues = []; +var expect= ''; +var expectedvalues = []; + + +/* + * All the following are invalid uses of regexp quantifiers and + * should generate SyntaxErrors. That's what we're testing for. + * + * To allow the test to compile and run, we have to hide the errors + * inside eval strings, and check they are caught at run-time - + * + */ +status = inSection(1); +testThis(' /a**/ '); + +status = inSection(2); +testThis(' /a***/ '); + +status = inSection(3); +testThis(' /a++/ '); + +status = inSection(4); +testThis(' /a+++/ '); + +/* + * The ? quantifier, unlike * or +, may appear twice in succession. + * Thus we need at least three in a row to provoke a SyntaxError - + */ + +status = inSection(5); +testThis(' /a???/ '); + +status = inSection(6); +testThis(' /a????/ '); + + +/* + * Now do some weird things on the left side of the regexps - + */ +status = inSection(9); +testThis(' /+a/ '); + +status = inSection(10); +testThis(' /++a/ '); + +status = inSection(11); +testThis(' /?a/ '); + +status = inSection(12); +testThis(' /??a/ '); + + +/* + * Misusing the {DecmalDigits} quantifier - according to BOTH ECMA and Perl. + * + * Just as with the * and + quantifiers above, can't have two {DecmalDigits} + * quantifiers in succession - it's a SyntaxError. + */ +status = inSection(28); +testThis(' /x{1}{1}/ '); + +status = inSection(29); +testThis(' /x{1,}{1}/ '); + +status = inSection(30); +testThis(' /x{1,2}{1}/ '); + +status = inSection(31); +testThis(' /x{1}{1,}/ '); + +status = inSection(32); +testThis(' /x{1,}{1,}/ '); + +status = inSection(33); +testThis(' /x{1,2}{1,}/ '); + +status = inSection(34); +testThis(' /x{1}{1,2}/ '); + +status = inSection(35); +testThis(' /x{1,}{1,2}/ '); + +status = inSection(36); +testThis(' /x{1,2}{1,2}/ '); + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +/* + * Invalid syntax should generate a SyntaxError + */ +function testThis(sInvalidSyntax) +{ + expect = TEST_PASSED; + actual = TEST_FAILED_BADLY; + + try + { + eval(sInvalidSyntax); + } + catch(e) + { + if (e instanceof SyntaxError) + actual = TEST_PASSED; + else + actual = TEST_FAILED; + } + + statusitems[UBound] = status; + expectedvalues[UBound] = expect; + actualvalues[UBound] = actual; + UBound++; +} + + +/* + * Allowed syntax shouldn't generate any errors + */ +function checkThis(sAllowedSyntax) +{ + expect = CHECK_PASSED; + actual = CHECK_PASSED; + + try + { + eval(sAllowedSyntax); + } + catch(e) + { + actual = CHECK_FAILED; + } + + statusitems[UBound] = status; + expectedvalues[UBound] = expect; + actualvalues[UBound] = actual; + UBound++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus(summary); + + for (var i=0; i<UBound; i++) + { + reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]); + } +} diff --git a/js/src/tests/non262/RegExp/regress-191479.js b/js/src/tests/non262/RegExp/regress-191479.js new file mode 100644 index 0000000000..ca12f71877 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-191479.js @@ -0,0 +1,162 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 31 January 2003 + * SUMMARY: Testing regular expressions of form /(x|y){n,}/ + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=191479 + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 191479; +var summary = 'Testing regular expressions of form /(x|y){n,}/'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +status = inSection(1); +string = '12 3 45'; +pattern = /(\d|\d\s){2,}/; +actualmatch = string.match(pattern); +expectedmatch = Array('12', '2'); +addThis(); + +status = inSection(2); +string = '12 3 45'; +pattern = /(\d|\d\s){4,}/; +actualmatch = string.match(pattern); +expectedmatch = Array(string, '5'); +addThis(); + +status = inSection(3); +string = '12 3 45'; +pattern = /(\d|\d\s)+/; +actualmatch = string.match(pattern); +expectedmatch = Array('12', '2'); +addThis(); + +status = inSection(4); +string = '12 3 45'; +pattern = /(\d\s?){4,}/; +actualmatch = string.match(pattern); +expectedmatch = Array(string, '5'); +addThis(); + +/* + * Let's reverse the operands in Sections 1-3 above - + */ +status = inSection(5); +string = '12 3 45'; +pattern = /(\d\s|\d){2,}/; +actualmatch = string.match(pattern); +expectedmatch = Array(string, '5'); +addThis(); + +status = inSection(6); +string = '12 3 45'; +pattern = /(\d\s|\d){4,}/; +actualmatch = string.match(pattern); +expectedmatch = Array(string, '5'); +addThis(); + +status = inSection(7); +string = '12 3 45'; +pattern = /(\d\s|\d)+/; +actualmatch = string.match(pattern); +expectedmatch = Array(string, '5'); +addThis(); + + +/* + * Let's take all 7 sections above and make each quantifer non-greedy. + * + * This is done by appending ? to it. It doesn't change the meaning of + * the quantifier, but makes it non-greedy, which affects the results - + */ +status = inSection(8); +string = '12 3 45'; +pattern = /(\d|\d\s){2,}?/; +actualmatch = string.match(pattern); +expectedmatch = Array('12', '2'); +addThis(); + +status = inSection(9); +string = '12 3 45'; +pattern = /(\d|\d\s){4,}?/; +actualmatch = string.match(pattern); +expectedmatch = Array('12 3 4', '4'); +addThis(); + +status = inSection(10); +string = '12 3 45'; +pattern = /(\d|\d\s)+?/; +actualmatch = string.match(pattern); +expectedmatch = Array('1', '1'); +addThis(); + +status = inSection(11); +string = '12 3 45'; +pattern = /(\d\s?){4,}?/; +actualmatch = string.match(pattern); +expectedmatch = Array('12 3 4', '4'); +addThis(); + +status = inSection(12); +string = '12 3 45'; +pattern = /(\d\s|\d){2,}?/; +actualmatch = string.match(pattern); +expectedmatch = Array('12 ', '2 '); +addThis(); + +status = inSection(13); +string = '12 3 45'; +pattern = /(\d\s|\d){4,}?/; +actualmatch = string.match(pattern); +expectedmatch = Array('12 3 4', '4'); +addThis(); + +status = inSection(14); +string = '12 3 45'; +pattern = /(\d\s|\d)+?/; +actualmatch = string.match(pattern); +expectedmatch = Array('1', '1'); +addThis(); + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-202564.js b/js/src/tests/non262/RegExp/regress-202564.js new file mode 100644 index 0000000000..824ce21f03 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-202564.js @@ -0,0 +1,65 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 18 April 2003 + * SUMMARY: Testing regexp with many backreferences + * See http://bugzilla.mozilla.org/show_bug.cgi?id=202564 + * + * Note that in Section 1 below, we expect the 1st and 4th backreferences + * to hold |undefined| instead of the empty strings one gets in Perl and IE6. + * This is because per ECMA, regexp backreferences must hold |undefined| + * if not used. See http://bugzilla.mozilla.org/show_bug.cgi?id=123437. + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 202564; +var summary = 'Testing regexp with many backreferences'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +status = inSection(1); +string = 'Seattle, WA to Buckley, WA'; +pattern = /(?:(.+), )?(.+), (..) to (?:(.+), )?(.+), (..)/; +actualmatch = string.match(pattern); +expectedmatch = Array(string, undefined, "Seattle", "WA", undefined, "Buckley", "WA"); +addThis(); + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-209919.js b/js/src/tests/non262/RegExp/regress-209919.js new file mode 100644 index 0000000000..c8113f8abe --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-209919.js @@ -0,0 +1,138 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 19 June 2003 + * SUMMARY: Testing regexp submatches with quantifiers + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=209919 + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 209919; +var summary = 'Testing regexp submatches with quantifiers'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +/* + * Waldemar: "ECMA-262 15.10.2.5, third algorithm, step 2.1 states that + * once the minimum repeat count (which is 0 for *, 1 for +, etc.) has + * been satisfied, an atom being repeated must not match the empty string." + * + * In this example, the minimum repeat count is 0, so the last thing the + * capturing parens is permitted to contain is the 'a'. It may NOT go on + * to capture the '' at the $ position of 'a', even though '' satifies + * the condition b* + * + */ +status = inSection(1); +string = 'a'; +pattern = /(a|b*)*/; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'a'); +addThis(); + + +/* + * In this example, the minimum repeat count is 5, so the capturing parens + * captures the 'a', then goes on to capture the '' at the $ position of 'a' + * 4 times before it has to stop. Therefore the last thing it contains is ''. + */ +status = inSection(2); +string = 'a'; +pattern = /(a|b*){5,}/; +actualmatch = string.match(pattern); +expectedmatch = Array(string, ''); +addThis(); + + +/* + * Reduction of the above examples to contain only the condition b* + * inside the capturing parens. This can be even harder to grasp! + * + * The global match is the '' at the ^ position of 'a', but the parens + * is NOT permitted to capture it since the minimum repeat count is 0! + */ +status = inSection(3); +string = 'a'; +pattern = /(b*)*/; +actualmatch = string.match(pattern); +expectedmatch = Array('', undefined); +addThis(); + + +/* + * Here we have used the + quantifier (repeat count 1) outside the parens. + * Therefore the parens must capture at least once before stopping, so it + * does capture the '' this time - + */ +status = inSection(4); +string = 'a'; +pattern = /(b*)+/; +actualmatch = string.match(pattern); +expectedmatch = Array('', ''); +addThis(); + + +/* + * More complex examples - + */ +pattern = /^\-?(\d{1,}|\.{0,})*(\,\d{1,})?$/; + +status = inSection(5); +string = '100.00'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, '00', undefined); +addThis(); + +status = inSection(6); +string = '100,00'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, '100', ',00'); +addThis(); + +status = inSection(7); +string = '1.000,00'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, '000', ',00'); +addThis(); + + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-216591.js b/js/src/tests/non262/RegExp/regress-216591.js new file mode 100644 index 0000000000..28104ef95d --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-216591.js @@ -0,0 +1,81 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 19 August 2003 + * SUMMARY: Regexp conformance test + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=216591 + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 216591; +var summary = 'Regexp conformance test'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +status = inSection(1); +string = 'a {result.data.DATA} b'; +pattern = /\{(([a-z0-9\-_]+?\.)+?)([a-z0-9\-_]+?)\}/i; +actualmatch = string.match(pattern); +expectedmatch = Array('{result.data.DATA}', 'result.data.', 'data.', 'DATA'); +addThis(); + +/* + * Add a global flag to the regexp. In Perl 5, this gives the same results as above. Compare: + * + * [ ] perl -e '"a {result.data.DATA} b" =~ /\{(([a-z0-9\-_]+?\.)+?)([a-z0-9\-_]+?)\}/i; print("$&, $1, $2, $3");' + * {result.data.DATA}, result.data., data., DATA + * + * [ ] perl -e '"a {result.data.DATA} b" =~ /\{(([a-z0-9\-_]+?\.)+?)([a-z0-9\-_]+?)\}/gi; print("$&, $1, $2, $3");' + * {result.data.DATA}, result.data., data., DATA + * + * + * But in JavaScript, there will no longer be any sub-captures: + */ +status = inSection(2); +string = 'a {result.data.DATA} b'; +pattern = /\{(([a-z0-9\-_]+?\.)+?)([a-z0-9\-_]+?)\}/gi; +actualmatch = string.match(pattern); +expectedmatch = Array('{result.data.DATA}'); +addThis(); + + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-220367-001.js b/js/src/tests/non262/RegExp/regress-220367-001.js new file mode 100644 index 0000000000..40e83b4b38 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-220367-001.js @@ -0,0 +1,68 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 26 September 2003 + * SUMMARY: Regexp conformance test + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=220367 + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 220367; +var summary = 'Regexp conformance test'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +status = inSection(1); +string = 'a'; +pattern = /(a)|(b)/; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'a', undefined); +addThis(); + +status = inSection(2); +string = 'b'; +pattern = /(a)|(b)/; +actualmatch = string.match(pattern); +expectedmatch = Array(string, undefined, 'b'); +addThis(); + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-223273.js b/js/src/tests/non262/RegExp/regress-223273.js new file mode 100644 index 0000000000..fc842fe53d --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-223273.js @@ -0,0 +1,242 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 23 October 2003 + * SUMMARY: Unescaped, unbalanced parens in a regexp should cause SyntaxError. + * + * The same would also be true for unescaped, unbalanced brackets or braces + * if we followed the ECMA-262 Ed. 3 spec on this. But it was decided for + * backward compatibility reasons to follow Perl 5, which permits + * + * 1. an unescaped, unbalanced right bracket ] + * 2. an unescaped, unbalanced left brace { + * 3. an unescaped, unbalanced right brace } + * + * If any of these should occur, Perl treats each as a literal + * character. Therefore we permit all three of these cases, even + * though not ECMA-compliant. Note Perl errors on an unescaped, + * unbalanced left bracket; so will we. + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=223273 + * + */ +//----------------------------------------------------------------------------- +var UBound = 0; +var BUGNUMBER = 223273; +var summary = 'Unescaped, unbalanced parens in regexp should be a SyntaxError'; +var TEST_PASSED = 'SyntaxError'; +var TEST_FAILED = 'Generated an error, but NOT a SyntaxError!'; +var TEST_FAILED_BADLY = 'Did not generate ANY error!!!'; +var CHECK_PASSED = 'Should not generate an error'; +var CHECK_FAILED = 'Generated an error!'; +var status = ''; +var statusitems = []; +var actual = ''; +var actualvalues = []; +var expect= ''; +var expectedvalues = []; + + +/* + * All the following contain unescaped, unbalanced parens and + * should generate SyntaxErrors. That's what we're testing for. + * + * To allow the test to compile and run, we have to hide the errors + * inside eval strings, and check they are caught at run-time. + * + * Inside such strings, remember to escape any escape character! + */ +status = inSection(1); +testThis(' /(/ '); + +status = inSection(2); +testThis(' /)/ '); + +status = inSection(3); +testThis(' /(abc\\)def(g/ '); + +status = inSection(4); +testThis(' /\\(abc)def)g/ '); + + +/* + * These regexp patterns are correct and should not generate + * any errors. Note we use checkThis() instead of testThis(). + */ +status = inSection(5); +checkThis(' /\\(/ '); + +status = inSection(6); +checkThis(' /\\)/ '); + +status = inSection(7); +checkThis(' /(abc)def\\(g/ '); + +status = inSection(8); +checkThis(' /(abc\\)def)g/ '); + +status = inSection(9); +checkThis(' /(abc(\\))def)g/ '); + +status = inSection(10); +checkThis(' /(abc([x\\)yz]+)def)g/ '); + + + +/* + * Unescaped, unbalanced left brackets should be a SyntaxError + */ +status = inSection(11); +testThis(' /[/ '); + +status = inSection(12); +testThis(' /[abc\\]def[g/ '); + + +/* + * We permit unescaped, unbalanced right brackets, as does Perl. + * No error should result, even though this is not ECMA-compliant. + * Note we use checkThis() instead of testThis(). + */ +status = inSection(13); +checkThis(' /]/ '); + +status = inSection(14); +checkThis(' /\\[abc]def]g/ '); + + +/* + * These regexp patterns are correct and should not generate + * any errors. Note we use checkThis() instead of testThis(). + */ +status = inSection(15); +checkThis(' /\\[/ '); + +status = inSection(16); +checkThis(' /\\]/ '); + +status = inSection(17); +checkThis(' /[abc]def\\[g/ '); + +status = inSection(18); +checkThis(' /[abc\\]def]g/ '); + +status = inSection(19); +checkThis(' /(abc[\\]]def)g/ '); + +status = inSection(20); +checkThis(' /[abc(x\\]yz+)def]g/ '); + + + +/* + * Run some tests for unbalanced braces. We again follow Perl, and + * thus permit unescaped unbalanced braces - both left and right, + * even though this is not ECMA-compliant. + * + * Note we use checkThis() instead of testThis(). + */ +status = inSection(21); +checkThis(' /abc{def/ '); + +status = inSection(22); +checkThis(' /abc}def/ '); + +status = inSection(23); +checkThis(' /a{2}bc{def/ '); + +status = inSection(24); +checkThis(' /a}b{3}c}def/ '); + + +/* + * These regexp patterns are correct and should not generate + * any errors. Note we use checkThis() instead of testThis(). + */ +status = inSection(25); +checkThis(' /abc\\{def/ '); + +status = inSection(26); +checkThis(' /abc\\}def/ '); + +status = inSection(27); +checkThis(' /a{2}bc\\{def/ '); + +status = inSection(28); +checkThis(' /a\\}b{3}c\\}def/ '); + + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + + +/* + * Invalid syntax should generate a SyntaxError + */ +function testThis(sInvalidSyntax) +{ + expect = TEST_PASSED; + actual = TEST_FAILED_BADLY; + + try + { + eval(sInvalidSyntax); + } + catch(e) + { + if (e instanceof SyntaxError) + actual = TEST_PASSED; + else + actual = TEST_FAILED; + } + + statusitems[UBound] = status; + expectedvalues[UBound] = expect; + actualvalues[UBound] = actual; + UBound++; +} + + +/* + * Valid syntax shouldn't generate any errors + */ +function checkThis(sValidSyntax) +{ + expect = CHECK_PASSED; + actual = CHECK_PASSED; + + try + { + eval(sValidSyntax); + } + catch(e) + { + actual = CHECK_FAILED; + } + + statusitems[UBound] = status; + expectedvalues[UBound] = expect; + actualvalues[UBound] = actual; + UBound++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus(summary); + + for (var i=0; i<UBound; i++) + { + reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]); + } +} diff --git a/js/src/tests/non262/RegExp/regress-223535.js b/js/src/tests/non262/RegExp/regress-223535.js new file mode 100644 index 0000000000..1d84fcdf39 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-223535.js @@ -0,0 +1,97 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 24 October 2003 + * SUMMARY: Testing regexps with empty alternatives + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=223535 + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 223535; +var summary = 'Testing regexps with empty alternatives'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +string = 'a'; +status = inSection(1); +pattern = /a|/; +actualmatch = string.match(pattern); +expectedmatch = Array('a'); +addThis(); + +status = inSection(2); +pattern = /|a/; +actualmatch = string.match(pattern); +expectedmatch = Array(''); +addThis(); + +status = inSection(3); +pattern = /|/; +actualmatch = string.match(pattern); +expectedmatch = Array(''); +addThis(); + +status = inSection(4); +pattern = /(a|)/; +actualmatch = string.match(pattern); +expectedmatch = Array('a', 'a'); +addThis(); + +status = inSection(5); +pattern = /(a||)/; +actualmatch = string.match(pattern); +expectedmatch = Array('a', 'a'); +addThis(); + +status = inSection(6); +pattern = /(|a)/; +actualmatch = string.match(pattern); +expectedmatch = Array('', ''); +addThis(); + +status = inSection(7); +pattern = /(|a|)/; +actualmatch = string.match(pattern); +expectedmatch = Array('', ''); +addThis(); + + + +//------------------------------------------------------------------------------------------------- +test(); +//------------------------------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-224676.js b/js/src/tests/non262/RegExp/regress-224676.js new file mode 100644 index 0000000000..132ead9aeb --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-224676.js @@ -0,0 +1,190 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 04 November 2003 + * SUMMARY: Testing regexps with various disjunction + character class patterns + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=224676 + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 224676; +var summary = 'Regexps with various disjunction + character class patterns'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +string = 'ZZZxZZZ'; +status = inSection(1); +pattern = /[x]|x/; +actualmatch = string.match(pattern); +expectedmatch = Array('x'); +addThis(); + +status = inSection(2); +pattern = /x|[x]/; +actualmatch = string.match(pattern); +expectedmatch = Array('x'); +addThis(); + + +string = 'ZZZxbZZZ'; +status = inSection(3); +pattern = /a|[x]b/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb'); +addThis(); + +status = inSection(4); +pattern = /[x]b|a/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb'); +addThis(); + +status = inSection(5); +pattern = /([x]b|a)/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb', 'xb'); +addThis(); + +status = inSection(6); +pattern = /([x]b|a)|a/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb', 'xb'); +addThis(); + +status = inSection(7); +pattern = /^[x]b|a/; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + + +string = 'xb'; +status = inSection(8); +pattern = /^[x]b|a/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb'); +addThis(); + + +string = 'ZZZxbZZZ'; +status = inSection(9); +pattern = /([x]b)|a/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb', 'xb'); +addThis(); + +status = inSection(10); +pattern = /()[x]b|a/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb', ''); +addThis(); + +status = inSection(11); +pattern = /x[b]|a/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb'); +addThis(); + +status = inSection(12); +pattern = /[x]{1}b|a/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb'); +addThis(); + +status = inSection(13); +pattern = /[x]b|a|a/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb'); +addThis(); + +status = inSection(14); +pattern = /[x]b|[a]/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb'); +addThis(); + +status = inSection(15); +pattern = /[x]b|a+/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb'); +addThis(); + +status = inSection(16); +pattern = /[x]b|a{1}/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb'); +addThis(); + +status = inSection(17); +pattern = /[x]b|(a)/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb', undefined); +addThis(); + +status = inSection(18); +pattern = /[x]b|()a/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb', undefined); +addThis(); + +status = inSection(19); +pattern = /[x]b|^a/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb'); +addThis(); + +status = inSection(20); +pattern = /a|[^b]b/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb'); +addThis(); + +status = inSection(21); +pattern = /a|[^b]{1}b/; +actualmatch = string.match(pattern); +expectedmatch = Array('xb'); +addThis(); + + +string = 'hallo\";'; +status = inSection(22); +pattern = /^((\\[^\x00-\x1f]|[^\x00-\x1f"\\])*)"/; +actualmatch = string.match(pattern); +expectedmatch = Array('hallo"', 'hallo', 'o'); +addThis(); + +//---------------------------------------------------------------------------- +test(); +//---------------------------------------------------------------------------- + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-225289.js b/js/src/tests/non262/RegExp/regress-225289.js new file mode 100644 index 0000000000..d89be6bc7e --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-225289.js @@ -0,0 +1,140 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 10 November 2003 + * SUMMARY: Testing regexps with complementary alternatives + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=225289 + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 225289; +var summary = 'Testing regexps with complementary alternatives'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +// this pattern should match any string! +pattern = /a|[^a]/; + +status = inSection(1); +string = 'a'; +actualmatch = string.match(pattern); +expectedmatch = Array('a'); +addThis(); + +status = inSection(2); +string = ''; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(3); +string = '()'; +actualmatch = string.match(pattern); +expectedmatch = Array('('); +addThis(); + + +pattern = /(a|[^a])/; + +status = inSection(4); +string = 'a'; +actualmatch = string.match(pattern); +expectedmatch = Array('a', 'a'); +addThis(); + +status = inSection(5); +string = ''; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(6); +string = '()'; +actualmatch = string.match(pattern); +expectedmatch = Array('(', '('); +addThis(); + + +pattern = /(a)|([^a])/; + +status = inSection(7); +string = 'a'; +actualmatch = string.match(pattern); +expectedmatch = Array('a', 'a', undefined); +addThis(); + +status = inSection(8); +string = ''; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(9); +string = '()'; +actualmatch = string.match(pattern); +expectedmatch = Array('(', undefined, '('); +addThis(); + + +// note this pattern has one non-capturing parens +pattern = /((?:a|[^a])*)/g; + +status = inSection(10); +string = 'a'; +actualmatch = string.match(pattern); +expectedmatch = Array('a', ''); // see bug 225289 comment 6 +addThis(); + +status = inSection(11); +string = ''; +actualmatch = string.match(pattern); +expectedmatch = Array(''); // see bug 225289 comment 9 +addThis(); + +status = inSection(12); +string = '()'; +actualmatch = string.match(pattern); +expectedmatch = Array('()', ''); // see bug 225289 comment 6 +addThis(); + + + + +//------------------------------------------------------------------------------------------------- +test(); +//------------------------------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-225343.js b/js/src/tests/non262/RegExp/regress-225343.js new file mode 100644 index 0000000000..c1a70ec02f --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-225343.js @@ -0,0 +1,89 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 11 November 2003 + * SUMMARY: Testing regexp character classes and the case-insensitive flag + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=225343 + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 225343; +var summary = 'Testing regexp character classes and the case-insensitive flag'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +status = inSection(1); +string = 'a'; +pattern = /[A]/i; +actualmatch = string.match(pattern); +expectedmatch = Array('a'); +addThis(); + +status = inSection(2); +string = 'A'; +pattern = /[a]/i; +actualmatch = string.match(pattern); +expectedmatch = Array('A'); +addThis(); + +status = inSection(3); +string = '123abc123'; +pattern = /([A-Z]+)/i; +actualmatch = string.match(pattern); +expectedmatch = Array('abc', 'abc'); +addThis(); + +status = inSection(4); +string = '123abc123'; +pattern = /([A-Z])+/i; +actualmatch = string.match(pattern); +expectedmatch = Array('abc', 'c'); +addThis(); + +status = inSection(5); +string = 'abc@test.com'; +pattern = /^[-!#$%&\'*+\.\/0-9=?A-Z^_`{|}~]+@([-0-9A-Z]+\.)+([0-9A-Z]){2,4}$/i; +actualmatch = string.match(pattern); +expectedmatch = Array('abc@test.com', 'test.', 'm'); +addThis(); + + + +//------------------------------------------------------------------------------------------------- +test(); +//------------------------------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-24712.js b/js/src/tests/non262/RegExp/regress-24712.js new file mode 100644 index 0000000000..fead641be3 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-24712.js @@ -0,0 +1,19 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var BUGNUMBER = 24712; + +test(); + +function test() +{ + printBugNumber (BUGNUMBER); + + var re = /([\S]+([ \t]+[\S]+)*)[ \t]*=[ \t]*[\S]+/; + var result = re.exec("Course_Creator = Test") + ''; + + reportCompare('Course_Creator = Test,Course_Creator,', result, 'exec() returned null'); +} + diff --git a/js/src/tests/non262/RegExp/regress-285219.js b/js/src/tests/non262/RegExp/regress-285219.js new file mode 100644 index 0000000000..a73308d9bd --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-285219.js @@ -0,0 +1,18 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 285219; +var summary = 'Do not crash on RangeError: reserved slot out of range'; +var actual = 'No Crash'; +var expect = 'No Crash'; + +printBugNumber(BUGNUMBER); +printStatus (summary); + +var o = {hi: 'there'}; +eval("var r = /re(1)(2)(3)/g", o); + +reportCompare(expect, actual, summary); diff --git a/js/src/tests/non262/RegExp/regress-28686.js b/js/src/tests/non262/RegExp/regress-28686.js new file mode 100644 index 0000000000..6e75237249 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-28686.js @@ -0,0 +1,17 @@ +/* -*- tab-width: 8; indent-tabs-mode: nil; js-indent-level: 4 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var BUGNUMBER = 28686; + +test(); + +function test() +{ + printBugNumber (BUGNUMBER); + + var str = 'foo "bar" baz'; + reportCompare ('foo \\"bar\\" baz', str.replace(/([\'\"])/g, "\\$1"), + "str.replace failed."); +} diff --git a/js/src/tests/non262/RegExp/regress-305064.js b/js/src/tests/non262/RegExp/regress-305064.js new file mode 100644 index 0000000000..32c4f4bb71 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-305064.js @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 305064; +var summary = 'CharacterClassEscape \\s'; +var actual = ''; +var expect = ''; + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + /** List from ES 3.1 Recommendation for String.trim (bug 305064) **/ + var whitespace = [ + {s : '\u0009', t : 'HORIZONTAL TAB'}, + {s : '\u000B', t : 'VERTICAL TAB'}, + {s : '\u000C', t : 'FORMFEED'}, + {s : '\u0020', t : 'SPACE'}, + {s : '\u00A0', t : 'NO-BREAK SPACE'}, + {s : '\u1680', t : 'OGHAM SPACE MARK'}, + {s : '\u2000', t : 'EN QUAD'}, + {s : '\u2001', t : 'EM QUAD'}, + {s : '\u2002', t : 'EN SPACE'}, + {s : '\u2003', t : 'EM SPACE'}, + {s : '\u2004', t : 'THREE-PER-EM SPACE'}, + {s : '\u2005', t : 'FOUR-PER-EM SPACE'}, + {s : '\u2006', t : 'SIX-PER-EM SPACE'}, + {s : '\u2007', t : 'FIGURE SPACE'}, + {s : '\u2008', t : 'PUNCTUATION SPACE'}, + {s : '\u2009', t : 'THIN SPACE'}, + {s : '\u200A', t : 'HAIR SPACE'}, + {s : '\u202F', t : 'NARROW NO-BREAK SPACE'}, + {s : '\u205F', t : 'MEDIUM MATHEMATICAL SPACE'}, + {s : '\u3000', t : 'IDEOGRAPHIC SPACE'}, + {s : '\u000A', t : 'LINE FEED OR NEW LINE'}, + {s : '\u000D', t : 'CARRIAGE RETURN'}, + {s : '\u2028', t : 'LINE SEPARATOR'}, + {s : '\u2029', t : 'PARAGRAPH SEPARATOR'}, + ]; + + for (var i = 0; i < whitespace.length; ++i) + { + var v = whitespace[i]; + reportCompare(true, !!(/\s/.test(v.s)), 'Is ' + v.t + ' a space'); + } +} diff --git a/js/src/tests/non262/RegExp/regress-309840.js b/js/src/tests/non262/RegExp/regress-309840.js new file mode 100644 index 0000000000..ff1e5927c7 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-309840.js @@ -0,0 +1,24 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 309840; +var summary = 'Treat / in a literal regexp class as valid'; +var actual = 'No error'; +var expect = 'No error'; + +printBugNumber(BUGNUMBER); +printStatus (summary); + +try +{ + var re = eval('/[/]/'); +} +catch(e) +{ + actual = e.toString(); +} + +reportCompare(expect, actual, summary); diff --git a/js/src/tests/non262/RegExp/regress-312351.js b/js/src/tests/non262/RegExp/regress-312351.js new file mode 100644 index 0000000000..72a52a1839 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-312351.js @@ -0,0 +1,17 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 312351; +var summary = 'Do not crash on RegExp(null)'; +var actual = 'No Crash'; +var expect = 'No Crash'; + +printBugNumber(BUGNUMBER); +printStatus (summary); + +var x = RegExp(null); + +reportCompare(expect, actual, summary); diff --git a/js/src/tests/non262/RegExp/regress-31316.js b/js/src/tests/non262/RegExp/regress-31316.js new file mode 100644 index 0000000000..7ef2a14549 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-31316.js @@ -0,0 +1,60 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 01 May 2001 + * + * SUMMARY: Regression test for Bugzilla bug 31316: + * "Rhino: Regexp matches return garbage" + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=31316 + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 31316; +var summary = 'Regression test for Bugzilla bug 31316'; +var cnEmptyString = ''; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +status = inSection(1); +pattern = /<([^\/<>][^<>]*[^\/])>|<([^\/<>])>/; +string = '<p>Some<br />test</p>'; +actualmatch = string.match(pattern); +expectedmatch = Array('<p>', undefined, 'p'); +addThis(); + + +//------------------------------------------------------------------------------------------------- +test(); +//------------------------------------------------------------------------------------------------- + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-330684.js b/js/src/tests/non262/RegExp/regress-330684.js new file mode 100644 index 0000000000..097c697943 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-330684.js @@ -0,0 +1,21 @@ +// |reftest| slow +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 330684; +var summary = 'Do not hang on RegExp'; +var actual = 'Do not hang on RegExp'; +var expect = ''; + +printBugNumber(BUGNUMBER); +printStatus (summary); + +var re = /^(?:(?:%[0-9A-Fa-f]{2})*[!\$&'\*-;=\?-Z_a-z]*)+$/; +var url = "http://tw.yimg.com/a/tw/wenchuan/cam_240x400_381615_030806_2.swf?clickTAG=javascript:VRECopenWindow(1)"; + +printStatus(re.test(url)); + +reportCompare(expect, actual, summary); diff --git a/js/src/tests/non262/RegExp/regress-334158.js b/js/src/tests/non262/RegExp/regress-334158.js new file mode 100644 index 0000000000..a561445536 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-334158.js @@ -0,0 +1,25 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 334158; +var summary = 'Parse error in control letter escapes (RegExp)'; +var actual = ''; +var expect = ''; + +printBugNumber(BUGNUMBER); +printStatus (summary); + +expect = true; +actual = /\ca/.test( "\x01" ); +reportCompare(expect, actual, summary + ':/\ca/.test( "\x01" )'); + +expect = false + actual = /\ca/.test( "\\ca" ); +reportCompare(expect, actual, summary + ': /\ca/.test( "\\ca" )'); + +expect = false + actual = /\c[a/]/.test( "\x1ba/]" ); +reportCompare(expect, actual, summary + ': /\c[a/]/.test( "\x1ba/]" )'); diff --git a/js/src/tests/non262/RegExp/regress-346090.js b/js/src/tests/non262/RegExp/regress-346090.js new file mode 100644 index 0000000000..a25c38a563 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-346090.js @@ -0,0 +1,26 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 346090; +var summary = 'Do not crash with this regexp'; +var actual = 'No Crash'; +var expect = 'No Crash'; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + var r = /%((h[^l]+)|(l[^h]+)){0,2}?a/g; + r.exec('%lld %d'); + + reportCompare(expect, actual, summary); +} diff --git a/js/src/tests/non262/RegExp/regress-367888.js b/js/src/tests/non262/RegExp/regress-367888.js new file mode 100644 index 0000000000..f303758ca9 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-367888.js @@ -0,0 +1,26 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 367888; +var summary = 'RegExp /(|)??x/g.exec("y") barfs'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + expect = null; + actual = /(|)??x/g.exec("y"); + + reportCompare(expect, actual, summary); +} diff --git a/js/src/tests/non262/RegExp/regress-375642.js b/js/src/tests/non262/RegExp/regress-375642.js new file mode 100644 index 0000000000..48cba8fd78 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-375642.js @@ -0,0 +1,25 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 375642; +var summary = 'RegExp /(?:a??)+?/.exec("")'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + /(?:a??)+?/.exec("") + + reportCompare(expect, actual, summary); +} diff --git a/js/src/tests/non262/RegExp/regress-375651.js b/js/src/tests/non262/RegExp/regress-375651.js new file mode 100644 index 0000000000..8f3984e875 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-375651.js @@ -0,0 +1,26 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +//----------------------------------------------------------------------------- +var BUGNUMBER = 375651; +var summary = 'Do not assert with regexp quantifiers'; +var actual = 'No Crash'; +var expect = 'No Crash'; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + /(.{2,3}){0,2}?t/.exec("abt"); + + reportCompare(expect, actual, summary); +} diff --git a/js/src/tests/non262/RegExp/regress-375711.js b/js/src/tests/non262/RegExp/regress-375711.js new file mode 100644 index 0000000000..4de183691a --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-375711.js @@ -0,0 +1,82 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 375711; +var summary = 'Do not assert with /[Q-b]/i.exec("")'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + var s; + + // see bug 416933 + print('see bug 416933 for changed behavior on Gecko 1.9'); + + try + { + s = '/[Q-b]/.exec("")'; + expect = 'No Error'; + print(s + ' expect ' + expect); + eval(s); + actual = 'No Error'; + } + catch(ex) + { + actual = ex + ''; + } + reportCompare(expect, actual, summary + ': ' + s); + + try + { + s ='/[Q-b]/i.exec("")'; + expect = 'No Error'; + print(s + ' expect ' + expect); + eval(s); + actual = 'No Error'; + } + catch(ex) + { + actual = ex + ''; + } + reportCompare(expect, actual, summary + ': ' + s); + + try + { + s = '/[q-b]/.exec("")'; + expect = 'SyntaxError: invalid range in character class'; + print(s + ' expect ' + expect); + eval(s); + actual = 'No Error'; + } + catch(ex) + { + actual = ex + ''; + } + reportCompare(expect, actual, summary + ': ' + s); + + try + { + s ='/[q-b]/i.exec("")'; + expect = 'SyntaxError: invalid range in character class'; + print(s + ' expect ' + expect); + eval(s); + actual = 'No Error'; + } + catch(ex) + { + actual = ex + ''; + } + reportCompare(expect, actual, summary + ': ' + s); +} diff --git a/js/src/tests/non262/RegExp/regress-375715-01-n.js b/js/src/tests/non262/RegExp/regress-375715-01-n.js new file mode 100644 index 0000000000..dcd003ec17 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-375715-01-n.js @@ -0,0 +1,27 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 375715; +var summary = 'Do not assert: (c2 <= cs->length) && (c1 <= c2)'; +var actual = ''; +var expect = ''; + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + // note that the assertion does not fire if the regexp is + // evald or used in new RegExp, so this test must be an -n + // with uncaught SyntaxError. + + /[\Wb-G]/.exec(""); + reportCompare(expect, actual, summary + ' /[\Wb-G]/.exec("")'); +} diff --git a/js/src/tests/non262/RegExp/regress-375715-02.js b/js/src/tests/non262/RegExp/regress-375715-02.js new file mode 100644 index 0000000000..9f872cedfc --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-375715-02.js @@ -0,0 +1,24 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 375715; +var summary = 'Do not assert: (c2 <= cs->length) && (c1 <= c2)'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + /[\s-:]/; + reportCompare(expect, actual, summary + '/[\s-:]/'); +} diff --git a/js/src/tests/non262/RegExp/regress-375715-03.js b/js/src/tests/non262/RegExp/regress-375715-03.js new file mode 100644 index 0000000000..112da17df0 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-375715-03.js @@ -0,0 +1,24 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 375715; +var summary = 'Do not assert: (c2 <= cs->length) && (c1 <= c2)'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + /[_-t]/i.exec(""); + reportCompare(expect, actual, summary + '/[_-t]/i.exec("")'); +} diff --git a/js/src/tests/non262/RegExp/regress-375715-04.js b/js/src/tests/non262/RegExp/regress-375715-04.js new file mode 100644 index 0000000000..8a56c3fe6e --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-375715-04.js @@ -0,0 +1,32 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 375715; +var summary = 'Do not assert: (c2 <= cs->length) && (c1 <= c2)'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + try + { + expect = 'SyntaxError: invalid range in character class'; + (new RegExp("[\xDF-\xC7]]", "i")).exec(""); + } + catch(ex) + { + actual = ex + ''; + } + reportCompare(expect, actual, summary + '(new RegExp("[\xDF-\xC7]]", "i")).exec("")'); +} diff --git a/js/src/tests/non262/RegExp/regress-429241.js b/js/src/tests/non262/RegExp/regress-429241.js new file mode 100644 index 0000000000..a4b588fead --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-429241.js @@ -0,0 +1,200 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var gTestfile = 'regress-429241.js'; +var BUGNUMBER = 429241; +var summary = '\\x or \\u followed by too few hex digits'; +var r; + +reportCompare( + "x", + (r = /[\x]+/.exec("\\x\0")) && r[0], + "Section 1" +); + +reportCompare( + "xy", + (r = /[\xy]+/.exec("\\xy\0")) && r[0], + "Section 2" +); + +reportCompare( + "x0", + (r = /[\x0]+/.exec("\\x0\0")) && r[0], + "Section 3" +); + +reportCompare( + "x0y", + (r = /[\x0y]+/.exec("\\x0y\0")) && r[0], + "Section 4" +); + +reportCompare( + "\0", + (r = /[\x00]+/.exec("\\x\0")) && r[0], + "Section 5" +); + +reportCompare( + "0\0", + (r = /[\x000]+/.exec("0\0")) && r[0], + "Section 6" +); + +reportCompare( + "x", + (r = /^\x$/.exec("x")) && r[0], + "Section 7" +); + +reportCompare( + "xy", + (r = /^\xy$/.exec("xy")) && r[0], + "Section 8" +); + +reportCompare( + "x0", + (r = /^\x0$/.exec("x0")) && r[0], + "Section 9" +); + +reportCompare( + "x0y", + (r = /^\x0y$/.exec("x0y")) && r[0], + "Section 10" +); + +reportCompare( + null, + /^\x00$/.exec("\0" + "0"), + "Section 11" +); + +reportCompare( + "\0" + "0", + (r = /^\x000$/.exec("\0" + "0")) && r[0], + "Section 12" +); + +reportCompare( + "u", + (r = /[\u]+/.exec("\\u\0")) && r[0], + "Section 13" +); + +reportCompare( + "uy", + (r = /[\uy]+/.exec("\\uy\0")) && r[0], + "Section 14" +); + +reportCompare( + "u0", + (r = /[\u0]+/.exec("\\u0\0")) && r[0], + "Section 15" +); + +reportCompare( + "u0", + (r = /[\u00]+/.exec("\\u0\0")) && r[0], + "Section 16" +); + +reportCompare( + "u0", + (r = /[\u000]+/.exec("\\u0\0")) && r[0], + "Section 17" +); + +reportCompare( + "u0y", + (r = /[\u0y]+/.exec("\\u0y\0")) && r[0], + "Section 18" +); + +reportCompare( + "u0y", + (r = /[\u00y]+/.exec("\\u0y\0")) && r[0], + "Section 19" +); + +reportCompare( + "u0y", + (r = /[\u000y]+/.exec("\\u0y\0")) && r[0], + "Section 20" +); + +reportCompare( + "\0", + (r = /[\u0000]+/.exec("\\u\0")) && r[0], + "Section 21" +); + +reportCompare( + "0\0", + (r = /[\u00000]+/.exec("0\0")) && r[0], + "Section 22" +); + +reportCompare( + "u", + (r = /^\u$/.exec("u")) && r[0], + "Section 23" +); + +reportCompare( + "uy", + (r = /^\uy$/.exec("uy")) && r[0], + "Section 24" +); + +reportCompare( + "u0", + (r = /^\u0$/.exec("u0")) && r[0], + "Section 25" +); + +reportCompare( + "u00", + (r = /^\u00$/.exec("u00")) && r[0], + "Section 26" +); + +reportCompare( + "u000", + (r = /^\u000$/.exec("u000")) && r[0], + "Section 27" +); + +reportCompare( + "u0y", + (r = /^\u0y$/.exec("u0y")) && r[0], + "Section 28" +); + +reportCompare( + "u00y", + (r = /^\u00y$/.exec("u00y")) && r[0], + "Section 29" +); + +reportCompare( + "u000y", + (r = /^\u000y$/.exec("u000y")) && r[0], + "Section 30" +); + +reportCompare( + null, + /^\u0000$/.exec("\0" + "0"), + "Section 31" +); + +reportCompare( + "\0" + "0", + (r = /^\u00000$/.exec("\0" + "0")) && r[0], + "Section 32" +); diff --git a/js/src/tests/non262/RegExp/regress-436700.js b/js/src/tests/non262/RegExp/regress-436700.js new file mode 100644 index 0000000000..f5991cdae8 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-436700.js @@ -0,0 +1,31 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 436700; +var summary = 'Do not assert: 1 <= num && num <= 0x10000'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + try + { + /\2147483648/.exec(String.fromCharCode(140) + "7483648").toString(); + } + catch(ex) + { + } + + reportCompare(expect, actual, summary); +} diff --git a/js/src/tests/non262/RegExp/regress-465862.js b/js/src/tests/non262/RegExp/regress-465862.js new file mode 100644 index 0000000000..cb1cfe10f5 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-465862.js @@ -0,0 +1,80 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 465862; +var summary = 'Do case-insensitive matching correctly in JIT for non-ASCII-letters'; + +var i = 0; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + +// Note: we must call the RegExp constructor here instead of using +// literals. Otherwise, because the regexps are compiled at parse +// time, they will not be compiled to native code and we will not +// actually be testing jitted regexps. + + +status = inSection(1); +string = '@'; +pattern = new RegExp('@', 'i'); +actualmatch = string.match(pattern); +expectedmatch = Array(string); +addThis(); + +status = inSection(2); +string = '`'; +pattern = new RegExp('`', 'i'); +actualmatch = string.match(pattern); +expectedmatch = Array(string); +addThis(); + +status = inSection(3); +string = '@'; +pattern = new RegExp('`', 'i'); +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(4); +string = '`'; +pattern = new RegExp('@', 'i'); +print(string + ' ' + pattern); +actualmatch = string.match(pattern); +print('z ' + actualmatch); +print('`'.match(/@/i)); +expectedmatch = null; +addThis(); + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-57572.js b/js/src/tests/non262/RegExp/regress-57572.js new file mode 100644 index 0000000000..373f69191b --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-57572.js @@ -0,0 +1,114 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 28 December 2000 + * + * SUMMARY: Testing regular expressions containing the ? character. + * Arose from Bugzilla bug 57572: "RegExp with ? matches incorrectly" + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=57572 + * + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 57572; +var summary = 'Testing regular expressions containing "?"'; +var cnEmptyString = ''; var cnSingleSpace = ' '; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +status = inSection(1); +pattern = /(\S+)?(.*)/; +string = 'Test this'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'Test', ' this'); //single space in front of 'this' +addThis(); + +status = inSection(2); +pattern = /(\S+)? ?(.*)/; //single space between the ? characters +string= 'Test this'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'Test', 'this'); //NO space in front of 'this' +addThis(); + +status = inSection(3); +pattern = /(\S+)?(.*)/; +string = 'Stupid phrase, with six - (short) words'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'Stupid', ' phrase, with six - (short) words'); //single space in front of 'phrase' +addThis(); + +status = inSection(4); +pattern = /(\S+)? ?(.*)/; //single space between the ? characters +string = 'Stupid phrase, with six - (short) words'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'Stupid', 'phrase, with six - (short) words'); //NO space in front of 'phrase' +addThis(); + + +// let's add an extra back-reference this time - three instead of two - +status = inSection(5); +pattern = /(\S+)?( ?)(.*)/; //single space before second ? character +string = 'Stupid phrase, with six - (short) words'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'Stupid', cnSingleSpace, 'phrase, with six - (short) words'); +addThis(); + +status = inSection(6); +pattern = /^(\S+)?( ?)(B+)$/; //single space before second ? character +string = 'AAABBB'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'AAABB', cnEmptyString, 'B'); +addThis(); + +status = inSection(7); +pattern = /(\S+)?(!?)(.*)/; +string = 'WOW !!! !!!'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'WOW', cnEmptyString, ' !!! !!!'); +addThis(); + +status = inSection(8); +pattern = /(.+)?(!?)(!+)/; +string = 'WOW !!! !!!'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'WOW !!! !!', cnEmptyString, '!'); +addThis(); + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-57631.js b/js/src/tests/non262/RegExp/regress-57631.js new file mode 100644 index 0000000000..eb598d2e7d --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-57631.js @@ -0,0 +1,115 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 26 November 2000 + * + * + * SUMMARY: This test arose from Bugzilla bug 57631: + * "RegExp with invalid pattern or invalid flag causes segfault" + * + * Either error should throw an exception of type SyntaxError, + * and we check to see that it does... + */ +//----------------------------------------------------------------------------- +var BUGNUMBER = '57631'; +var summary = 'Testing new RegExp(pattern,flag) with illegal pattern or flag'; +var statprefix = 'Testing for error creating illegal RegExp object on pattern '; +var statsuffix = 'and flag '; +var cnSUCCESS = 'SyntaxError'; +var cnFAILURE = 'not a SyntaxError'; +var singlequote = "'"; +var i = -1; var j = -1; var s = ''; var f = ''; +var obj = {}; +var status = ''; var actual = ''; var expect = ''; var msg = ''; +var legalpatterns = new Array(); var illegalpatterns = new Array(); +var legalflags = new Array(); var illegalflags = new Array(); + + +// valid regular expressions to try - +legalpatterns[0] = ''; +legalpatterns[1] = 'abc'; +legalpatterns[2] = '(.*)(3-1)\s\w'; +legalpatterns[3] = '(.*)(...)\\s\\w'; +legalpatterns[4] = '[^A-Za-z0-9_]'; +legalpatterns[5] = '[^\f\n\r\t\v](123.5)([4 - 8]$)'; + +// invalid regular expressions to try - +illegalpatterns[0] = '(?)'; +illegalpatterns[1] = '(a'; +illegalpatterns[2] = '( ]'; +//illegalpatterns[3] = '\d{1,s}'; + +// valid flags to try - +legalflags[0] = 'i'; +legalflags[1] = 'g'; +legalflags[2] = 'm'; +legalflags[3] = undefined; + +// invalid flags to try - +illegalflags[0] = 'a'; +illegalflags[1] = 123; +illegalflags[2] = new RegExp(); + + + +//------------------------------------------------------------------------------------------------- +test(); +//------------------------------------------------------------------------------------------------- + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + testIllegalRegExps(legalpatterns, illegalflags); + testIllegalRegExps(illegalpatterns, legalflags); + testIllegalRegExps(illegalpatterns, illegalflags); +} + + +// This function will only be called where all the patterns are illegal, or all the flags +function testIllegalRegExps(patterns, flags) +{ + for (i in patterns) + { + s = patterns[i]; + + for (j in flags) + { + f = flags[j]; + status = getStatus(s, f); + actual = cnFAILURE; + expect = cnSUCCESS; + + try + { + // This should cause an exception if either s or f is illegal - + eval('obj = new RegExp(s, f);'); + } + catch(e) + { + // We expect to get a SyntaxError - test for this: + if (e instanceof SyntaxError) + actual = cnSUCCESS; + } + + reportCompare(expect, actual, status); + } + } +} + + +function getStatus(regexp, flag) +{ + return (statprefix + quote(regexp) + statsuffix + quote(flag)); +} + + +function quote(text) +{ + return (singlequote + text + singlequote); +} diff --git a/js/src/tests/non262/RegExp/regress-576828.js b/js/src/tests/non262/RegExp/regress-576828.js new file mode 100644 index 0000000000..45e97dc3b1 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-576828.js @@ -0,0 +1,8 @@ +var re = /(z\1){3}/; +var str = 'zzz'; +var actual = re.exec(str); +var expected = makeExpectedMatch(['zzz', 'z'], 0, str); +checkRegExpMatch(actual, expected); + +if (typeof reportCompare == 'function') + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/regress-613820-1.js b/js/src/tests/non262/RegExp/regress-613820-1.js new file mode 100644 index 0000000000..e5e755b24a --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-613820-1.js @@ -0,0 +1,9 @@ +/* Back reference is actually a forwards reference. */ +var re = /(\2(a)){2}/; +var str = 'aaa'; +var actual = re.exec(str); +var expected = makeExpectedMatch(['aa', 'a', 'a'], 0, str); +checkRegExpMatch(actual, expected); + +if (typeof reportCompare === 'function') + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/regress-613820-2.js b/js/src/tests/non262/RegExp/regress-613820-2.js new file mode 100644 index 0000000000..5db7244ba2 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-613820-2.js @@ -0,0 +1,9 @@ +/* Resetting of inner capture groups across quantified capturing parens. */ +var re = /(?:(f)(o)(o)|(b)(a)(r))*/; +var str = 'foobar'; +var actual = re.exec(str); +var expected = makeExpectedMatch(['foobar', undefined, undefined, undefined, 'b', 'a', 'r'], 0, str); +checkRegExpMatch(actual, expected); + +if (typeof reportCompare === 'function') + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/regress-613820-3.js b/js/src/tests/non262/RegExp/regress-613820-3.js new file mode 100644 index 0000000000..126e838ff2 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-613820-3.js @@ -0,0 +1,9 @@ +/* Capture group reset to undefined during second iteration, so backreference doesn't see prior result. */ +var re = /(?:^(a)|\1(a)|(ab)){2}/; +var str = 'aab'; +var actual = re.exec(str); +var expected = makeExpectedMatch(['aa', undefined, 'a', undefined], 0, str); +checkRegExpMatch(actual, expected); + +if (typeof reportCompare === 'function') + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/regress-617935.js b/js/src/tests/non262/RegExp/regress-617935.js new file mode 100644 index 0000000000..3764d81b0e --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-617935.js @@ -0,0 +1,42 @@ +// |reftest| skip-if(!xulRuntime.shell&&(Android||xulRuntime.OS=="WINNT")) silentfail +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * + * Author: Christian Holler <decoder@own-hero.net> + */ + +expectExitCode(0); +expectExitCode(5); + +/* Length of 32 */ +var foo = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + +/* Make len(foo) 32768 */ +for (i = 0; i < 10; ++i) { + foo += foo; +} + +/* Add one "a" to cause overflow later */ +foo += "a"; + +var bar = "bbbbbbbbbbbbbbbb"; + +/* Make len(bar) 8192 */ +for (i = 0; i < 9; ++i) { + bar += bar; +} + +/* + * Resulting string should be + * len(foo) * len(bar) = (2**10 * 32 + 1) * 8192 = 268443648 + * which will be larger than the max string length (2**28, or 268435456). + */ +try { + foo.replace(/[a]/g, bar); +} catch (e) { + reportCompare(e instanceof InternalError, true, "Internal error due to overallocation is ok."); +} +reportCompare(true, true, "No crash occurred."); + +print("Tests complete"); diff --git a/js/src/tests/non262/RegExp/regress-6359.js b/js/src/tests/non262/RegExp/regress-6359.js new file mode 100644 index 0000000000..fae056fa53 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-6359.js @@ -0,0 +1,52 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +/** + * File Name: regress-6359.js + * Reference: ** replace with bugzilla URL or document reference ** + * Description: ** replace with description of test ** + * Author: ** replace with your e-mail address ** + */ + +var SECTION = "js1_2"; // provide a document reference (ie, ECMA section) +var TITLE = "Regression test for bugzilla # 6359"; // Provide ECMA section title or a description +var BUGNUMBER = "http://bugzilla.mozilla.org/show_bug.cgi?id=6359"; // Provide URL to bugsplat or bugzilla report + +printBugNumber(BUGNUMBER); + +/* + * Calls to AddTestCase here. AddTestCase is a function that is defined + * in shell.js and takes three arguments: + * - a string representation of what is being tested + * - the expected result + * - the actual result + * + * For example, a test might look like this: + * + * var zip = /[\d]{5}$/; + * + * AddTestCase( + * "zip = /[\d]{5}$/; \"PO Box 12345 Boston, MA 02134\".match(zip)", // description of the test + * "02134", // expected result + * "PO Box 12345 Boston, MA 02134".match(zip) ); // actual result + * + */ + +AddTestCase( '/(a*)b\1+/.exec("baaac").length', + 2, + /(a*)b\1+/.exec("baaac").length ); + +AddTestCase( '/(a*)b\1+/.exec("baaac")[0]', + "b", + /(a*)b\1+/.exec("baaac")[0]); + +AddTestCase( '/(a*)b\1+/.exec("baaac")[1]', + "", + /(a*)b\1+/.exec("baaac")[1]); + + +test(); // leave this alone. this executes the test cases and +// displays results. diff --git a/js/src/tests/non262/RegExp/regress-67773.js b/js/src/tests/non262/RegExp/regress-67773.js new file mode 100644 index 0000000000..1df7680d0f --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-67773.js @@ -0,0 +1,175 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 06 February 2001 + * + * SUMMARY: Arose from Bugzilla bug 67773: + * "Regular subexpressions followed by + failing to run to completion" + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=67773 + * See http://bugzilla.mozilla.org/show_bug.cgi?id=69989 + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 67773; +var summary = 'Testing regular subexpressions followed by ? or +\n'; +var cnSingleSpace = ' '; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +pattern = /^(\S+)?( ?)(B+)$/; //single space before second ? character +status = inSection(1); +string = 'AAABBB AAABBB '; //single space at middle and at end - +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(2); +string = 'AAABBB BBB'; //single space in the middle +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'AAABBB', cnSingleSpace, 'BBB'); +addThis(); + +status = inSection(3); +string = 'AAABBB AAABBB'; //single space in the middle +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + + +pattern = /^(A+B)+$/; +status = inSection(4); +string = 'AABAAB'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'AAB'); +addThis(); + +status = inSection(5); +string = 'ABAABAAAAAAB'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'AAAAAAB'); +addThis(); + +status = inSection(6); +string = 'ABAABAABAB'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'AB'); +addThis(); + +status = inSection(7); +string = 'ABAABAABABB'; +actualmatch = string.match(pattern); +expectedmatch = null; // because string doesn't match at end +addThis(); + + +pattern = /^(A+1)+$/; +status = inSection(8); +string = 'AA1AA1'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'AA1'); +addThis(); + + +pattern = /^(\w+\-)+$/; +status = inSection(9); +string = ''; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(10); +string = 'bla-'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, string); +addThis(); + +status = inSection(11); +string = 'bla-bla'; // hyphen missing at end - +actualmatch = string.match(pattern); +expectedmatch = null; //because string doesn't match at end +addThis(); + +status = inSection(12); +string = 'bla-bla-'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'bla-'); +addThis(); + + +pattern = /^(\S+)+(A+)$/; +status = inSection(13); +string = 'asdldflkjAAA'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'asdldflkjAA', 'A'); +addThis(); + +status = inSection(14); +string = 'asdldflkj AAA'; // space in middle +actualmatch = string.match(pattern); +expectedmatch = null; //because of the space +addThis(); + + +pattern = /^(\S+)+(\d+)$/; +status = inSection(15); +string = 'asdldflkj122211'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'asdldflkj12221', '1'); +addThis(); + +status = inSection(16); +string = 'asdldflkj1111111aaa1'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, 'asdldflkj1111111aaa', '1'); +addThis(); + + +/* + * This one comes from Stephen Ostermiller. + * See http://bugzilla.mozilla.org/show_bug.cgi?id=69989 + */ +pattern = /^[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)+$/; +status = inSection(17); +string = 'some.host.tld'; +actualmatch = string.match(pattern); +expectedmatch = Array(string, '.tld', '.'); +addThis(); + + + +//------------------------------------------------------------------------------------------------- +test(); +//------------------------------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-72964.js b/js/src/tests/non262/RegExp/regress-72964.js new file mode 100644 index 0000000000..70ca502ff1 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-72964.js @@ -0,0 +1,85 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 2001-07-17 + * + * SUMMARY: Regression test for Bugzilla bug 72964: + * "String method for pattern matching failed for Chinese Simplified (GB2312)" + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=72964 + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 72964; +var summary = 'Testing regular expressions containing non-Latin1 characters'; +var cnSingleSpace = ' '; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +pattern = /[\S]+/; +// 4 low Unicode chars = Latin1; whole string should match +status = inSection(1); +string = '\u00BF\u00CD\u00BB\u00A7'; +actualmatch = string.match(pattern); +expectedmatch = Array(string); +addThis(); + +// Now put a space in the middle; first half of string should match +status = inSection(2); +string = '\u00BF\u00CD \u00BB\u00A7'; +actualmatch = string.match(pattern); +expectedmatch = Array('\u00BF\u00CD'); +addThis(); + + +// 4 high Unicode chars = non-Latin1; whole string should match +status = inSection(3); +string = '\u4e00\uac00\u4e03\u4e00'; +actualmatch = string.match(pattern); +expectedmatch = Array(string); +addThis(); + +// Now put a space in the middle; first half of string should match +status = inSection(4); +string = '\u4e00\uac00 \u4e03\u4e00'; +actualmatch = string.match(pattern); +expectedmatch = Array('\u4e00\uac00'); +addThis(); + + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-76683.js b/js/src/tests/non262/RegExp/regress-76683.js new file mode 100644 index 0000000000..ff839bb0ca --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-76683.js @@ -0,0 +1,78 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 01 May 2001 + * + * SUMMARY: Regression test for Bugzilla bug 76683 on Rhino: + * "RegExp regression (NullPointerException)" + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=76683 + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 76683; +var summary = 'Regression test for Bugzilla bug 76683'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +/* + * Rhino (2001-04-19) crashed on the 3rd regular expression below. + * It didn't matter what the string was. No problem in SpiderMonkey - + */ +string = 'abc'; +status = inSection(1); +pattern = /(<!--([^-]|-[^-]|--[^>])*-->)|(<([\$\w:\.\-]+)((([ ][^\/>]*)?\/>)|(([ ][^>]*)?>)))/; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +status = inSection(2); +pattern = /(<!--([^-]|-[^-]|--[^>])*-->)|(<(tagPattern)((([ ][^\/>]*)?\/>)|(([ ][^>]*)?>)))/; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + +// This was the one causing a Rhino crash - +status = inSection(3); +pattern = /(<!--([^-]|-[^-]|--[^>])*-->)|(<(tagPattern)((([ ][^\/>]*)?\/>)|(([ ][^>]*)?>)))|(<\/tagPattern[^>]*>)/; +actualmatch = string.match(pattern); +expectedmatch = null; +addThis(); + + + +//------------------------------------------------------------------------------------------------- +test(); +//------------------------------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-78156.js b/js/src/tests/non262/RegExp/regress-78156.js new file mode 100644 index 0000000000..01ef647638 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-78156.js @@ -0,0 +1,87 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 06 February 2001 + * + * SUMMARY: Arose from Bugzilla bug 78156: + * "m flag of regular expression does not work with $" + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=78156 + * + * The m flag means a regular expression should search strings + * across multiple lines, i.e. across '\n', '\r'. + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 78156; +var summary = 'Testing regular expressions with ^, $, and the m flag -'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + +/* + * All patterns have an m flag; all strings are multiline. + * Looking for digit characters at beginning/end of lines. + */ + +string = 'aaa\n789\r\nccc\r\n345'; +status = inSection(1); +pattern = /^\d/gm; +actualmatch = string.match(pattern); +expectedmatch = ['7','3']; +addThis(); + +status = inSection(2); +pattern = /\d$/gm; +actualmatch = string.match(pattern); +expectedmatch = ['9','5']; +addThis(); + +string = 'aaa\n789\r\nccc\r\nddd'; +status = inSection(3); +pattern = /^\d/gm; +actualmatch = string.match(pattern); +expectedmatch = ['7']; +addThis(); + +status = inSection(4); +pattern = /\d$/gm; +actualmatch = string.match(pattern); +expectedmatch = ['9']; +addThis(); + + + +//------------------------------------------------------------------------------------------------- +test(); +//------------------------------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-85721.js b/js/src/tests/non262/RegExp/regress-85721.js new file mode 100644 index 0000000000..e04ae97f35 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-85721.js @@ -0,0 +1,243 @@ +// |reftest| random -- bogus perf test (bug 467263) +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * + * Date: 14 Feb 2002 + * SUMMARY: Performance: Regexp performance degraded from 4.7 + * See http://bugzilla.mozilla.org/show_bug.cgi?id=85721 + * + * Adjust this testcase if necessary. The FAST constant defines + * an upper bound in milliseconds for any execution to take. + * + */ +//----------------------------------------------------------------------------- +var BUGNUMBER = 85721; +var summary = 'Performance: execution of regular expression'; +var FAST = 100; // execution should be 100 ms or less to pass the test +var MSG_FAST = 'Execution took less than ' + FAST + ' ms'; +var MSG_SLOW = 'Execution took '; +var MSG_MS = ' ms'; +var str = ''; +var re = ''; +var status = ''; +var actual = ''; +var expect= ''; + +printBugNumber(BUGNUMBER); +printStatus (summary); + + +function elapsedTime(startTime) +{ + return new Date() - startTime; +} + + +function isThisFast(ms) +{ + if (ms <= FAST) + return MSG_FAST; + return MSG_SLOW + ms + MSG_MS; +} + + + +/* + * The first regexp. We'll test for performance (Section 1) and accuracy (Section 2). + */ +str='<sql:connection id="conn1"> <sql:url>www.m.com</sql:url> <sql:driver>drive.class</sql:driver>\n<sql:userId>foo</sql:userId> <sql:password>goo</sql:password> </sql:connection>'; +re = /<sql:connection id="([^\r\n]*?)">\s*<sql:url>\s*([^\r\n]*?)\s*<\/sql:url>\s*<sql:driver>\s*([^\r\n]*?)\s*<\/sql:driver>\s*(\s*<sql:userId>\s*([^\r\n]*?)\s*<\/sql:userId>\s*)?\s*(\s*<sql:password>\s*([^\r\n]*?)\s*<\/sql:password>\s*)?\s*<\/sql:connection>/; +expect = Array("<sql:connection id=\"conn1\"> <sql:url>www.m.com</sql:url> <sql:driver>drive.class</sql:driver>\n<sql:userId>foo</sql:userId> <sql:password>goo</sql:password> </sql:connection>","conn1","www.m.com","drive.class","<sql:userId>foo</sql:userId> ","foo","<sql:password>goo</sql:password> ","goo"); + +/* + * Check performance - + */ +status = inSection(1); +var start = new Date(); +var result = re.exec(str); +actual = elapsedTime(start); +reportCompare(isThisFast(FAST), isThisFast(actual), status); + +/* + * Check accuracy - + */ +status = inSection(2); +testRegExp([status], [re], [str], [result], [expect]); + + + +/* + * The second regexp (HUGE!). We'll test for performance (Section 3) and accuracy (Section 4). + * It comes from the O'Reilly book "Mastering Regular Expressions" by Jeffrey Friedl, Appendix B + */ + +//# Some things for avoiding backslashitis later on. +$esc = '\\\\'; +$Period = '\.'; +$space = '\040'; $tab = '\t'; +$OpenBR = '\\['; $CloseBR = '\\]'; +$OpenParen = '\\('; $CloseParen = '\\)'; +$NonASCII = '\x80-\xff'; $ctrl = '\000-\037'; +$CRlist = '\n\015'; //# note: this should really be only \015. +// Items 19, 20, 21 +$qtext = '[^' + $esc + $NonASCII + $CRlist + '\"]'; // # for within "..." +$dtext = '[^' + $esc + $NonASCII + $CRlist + $OpenBR + $CloseBR + ']'; // # for within [...] +$quoted_pair = $esc + '[^' + $NonASCII + ']'; // # an escaped character + +//############################################################################## +//# Items 22 and 23, comment. +//# Impossible to do properly with a regex, I make do by allowing at most one level of nesting. +$ctext = '[^' + $esc + $NonASCII + $CRlist + '()]'; + +//# $Cnested matches one non-nested comment. +//# It is unrolled, with normal of $ctext, special of $quoted_pair. +$Cnested = + $OpenParen + // # ( + $ctext + '*' + // # normal* + '(?:' + $quoted_pair + $ctext + '*)*' + // # (special normal*)* + $CloseParen; // # ) + + +//# $comment allows one level of nested parentheses +//# It is unrolled, with normal of $ctext, special of ($quoted_pair|$Cnested) +$comment = + $OpenParen + // # ( + $ctext + '*' + // # normal* + '(?:' + // # ( + '(?:' + $quoted_pair + '|' + $Cnested + ')' + // # special + $ctext + '*' + // # normal* + ')*' + // # )* + $CloseParen; // # ) + + +//############################################################################## +//# $X is optional whitespace/comments. +$X = + '[' + $space + $tab + ']*' + // # Nab whitespace. + '(?:' + $comment + '[' + $space + $tab + ']*)*'; // # If comment found, allow more spaces. + + +//# Item 10: atom +$atom_char = '[^(' + $space + '<>\@,;:\".' + $esc + $OpenBR + $CloseBR + $ctrl + $NonASCII + ']'; +$atom = + $atom_char + '+' + // # some number of atom characters... + '(?!' + $atom_char + ')'; // # ..not followed by something that could be part of an atom + +// # Item 11: doublequoted string, unrolled. +$quoted_str = + '\"' + // # " + $qtext + '*' + // # normal + '(?:' + $quoted_pair + $qtext + '*)*' + // # ( special normal* )* + '\"'; // # " + +//# Item 7: word is an atom or quoted string +$word = + '(?:' + + $atom + // # Atom + '|' + // # or + $quoted_str + // # Quoted string + ')' + +//# Item 12: domain-ref is just an atom + $domain_ref = $atom; + +//# Item 13: domain-literal is like a quoted string, but [...] instead of "..." +$domain_lit = + $OpenBR + // # [ + '(?:' + $dtext + '|' + $quoted_pair + ')*' + // # stuff + $CloseBR; // # ] + +// # Item 9: sub-domain is a domain-ref or domain-literal +$sub_domain = + '(?:' + + $domain_ref + + '|' + + $domain_lit + + ')' + + $X; // # optional trailing comments + +// # Item 6: domain is a list of subdomains separated by dots. +$domain = + $sub_domain + + '(?:' + + $Period + $X + $sub_domain + + ')*'; + +//# Item 8: a route. A bunch of "@ $domain" separated by commas, followed by a colon. +$route = + '\@' + $X + $domain + + '(?:,' + $X + '\@' + $X + $domain + ')*' + // # additional domains + ':' + + $X; // # optional trailing comments + +//# Item 6: local-part is a bunch of $word separated by periods +$local_part = + $word + $X + '(?:' + + $Period + $X + $word + $X + // # additional words + ')*'; + +// # Item 2: addr-spec is local@domain +$addr_spec = + $local_part + '\@' + $X + $domain; + +//# Item 4: route-addr is <route? addr-spec> +$route_addr = + '<' + $X + // # < + '(?:' + $route + ')?' + // # optional route + $addr_spec + // # address spec + '>'; // # > + +//# Item 3: phrase........ +$phrase_ctrl = '\000-\010\012-\037'; // # like ctrl, but without tab + +//# Like atom-char, but without listing space, and uses phrase_ctrl. +//# Since the class is negated, this matches the same as atom-char plus space and tab +$phrase_char = + '[^()<>\@,;:\".' + $esc + $OpenBR + $CloseBR + $NonASCII + $phrase_ctrl + ']'; + +// # We've worked it so that $word, $comment, and $quoted_str to not consume trailing $X +// # because we take care of it manually. +$phrase = + $word + // # leading word + $phrase_char + '*' + // # "normal" atoms and/or spaces + '(?:' + + '(?:' + $comment + '|' + $quoted_str + ')' + // # "special" comment or quoted string + $phrase_char + '*' + // # more "normal" + ')*'; + +// ## Item #1: mailbox is an addr_spec or a phrase/route_addr +$mailbox = + $X + // # optional leading comment + '(?:' + + $phrase + $route_addr + // # name and address + '|' + // # or + $addr_spec + // # address + ')'; + + +//########################################################################### + + +re = new RegExp($mailbox, "g"); +str = 'Jeffy<"That Tall Guy"@ora.com (this address is no longer active)>'; +expect = Array('Jeffy<"That Tall Guy"@ora.com (this address is no longer active)>'); + +/* + * Check performance - + */ +status = inSection(3); +var start = new Date(); +var result = re.exec(str); +actual = elapsedTime(start); +reportCompare(isThisFast(FAST), isThisFast(actual), status); + +/* + * Check accuracy - + */ +status = inSection(4); +testRegExp([status], [re], [str], [result], [expect]); diff --git a/js/src/tests/non262/RegExp/regress-87231.js b/js/src/tests/non262/RegExp/regress-87231.js new file mode 100644 index 0000000000..9d5adaedeb --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-87231.js @@ -0,0 +1,109 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 22 June 2001 + * + * SUMMARY: Regression test for Bugzilla bug 87231: + * "Regular expression /(A)?(A.*)/ picks 'A' twice" + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=87231 + * Key case: + * + * pattern = /^(A)?(A.*)$/; + * string = 'A'; + * expectedmatch = Array('A', '', 'A'); + * + * + * We expect the 1st subexpression (A)? NOT to consume the single 'A'. + * Recall that "?" means "match 0 or 1 times". Here, it should NOT do + * greedy matching: it should match 0 times instead of 1. This allows + * the 2nd subexpression to make the only match it can: the single 'A'. + * Such "altruism" is the only way there can be a successful global match... + */ +//----------------------------------------------------------------------------- +var i = 0; +var BUGNUMBER = 87231; +var cnEmptyString = ''; +var summary = 'Testing regular expression /(A)?(A.*)/'; +var status = ''; +var statusmessages = new Array(); +var pattern = ''; +var patterns = new Array(); +var string = ''; +var strings = new Array(); +var actualmatch = ''; +var actualmatches = new Array(); +var expectedmatch = ''; +var expectedmatches = new Array(); + + +pattern = /^(A)?(A.*)$/; +status = inSection(1); +string = 'AAA'; +actualmatch = string.match(pattern); +expectedmatch = Array('AAA', 'A', 'AA'); +addThis(); + +status = inSection(2); +string = 'AA'; +actualmatch = string.match(pattern); +expectedmatch = Array('AA', 'A', 'A'); +addThis(); + +status = inSection(3); +string = 'A'; +actualmatch = string.match(pattern); +expectedmatch = Array('A', undefined, 'A'); // 'altruistic' case: see above +addThis(); + + +pattern = /(A)?(A.*)/; +var strL = 'zxcasd;fl\\\ ^'; +var strR = 'aaAAaaaf;lrlrzs'; + +status = inSection(4); +string = strL + 'AAA' + strR; +actualmatch = string.match(pattern); +expectedmatch = Array('AAA' + strR, 'A', 'AA' + strR); +addThis(); + +status = inSection(5); +string = strL + 'AA' + strR; +actualmatch = string.match(pattern); +expectedmatch = Array('AA' + strR, 'A', 'A' + strR); +addThis(); + +status = inSection(6); +string = strL + 'A' + strR; +actualmatch = string.match(pattern); +expectedmatch = Array('A' + strR, undefined, 'A' + strR); // 'altruistic' case: see above +addThis(); + + + +//------------------------------------------------------------------------------------------------- +test(); +//------------------------------------------------------------------------------------------------- + + + +function addThis() +{ + statusmessages[i] = status; + patterns[i] = pattern; + strings[i] = string; + actualmatches[i] = actualmatch; + expectedmatches[i] = expectedmatch; + i++; +} + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); +} diff --git a/js/src/tests/non262/RegExp/regress-9141.js b/js/src/tests/non262/RegExp/regress-9141.js new file mode 100644 index 0000000000..b95e40aaa1 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-9141.js @@ -0,0 +1,71 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + + +/** + * File Name: regress-9141.js + * Reference: "http://bugzilla.mozilla.org/show_bug.cgi?id=9141"; + * Description: + * From waldemar@netscape.com: + * + * The following page crashes the system: + * + * <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" + * "http://www.w3.org/TR/REC-html40/loose.dtd"> + * <HTML> + * <HEAD> + * </HEAD> + * <BODY> + * <SCRIPT type="text/javascript"> + * var s = "x"; + * for (var i = 0; i != 13; i++) s += s; + * var a = /(?:xx|x)*[slash](s); + * var b = /(xx|x)*[slash](s); + * document.write("Results = " + a.length + "," + b.length); + * </SCRIPT> + * </BODY> + */ + +var SECTION = "js1_2"; // provide a document reference (ie, ECMA section) +var TITLE = "Regression test for bugzilla # 9141"; // Provide ECMA section title or a description +var BUGNUMBER = "http://bugzilla.mozilla.org/show_bug.cgi?id=9141"; // Provide URL to bugsplat or bugzilla report + +printBugNumber(BUGNUMBER); + +/* + * Calls to AddTestCase here. AddTestCase is a function that is defined + * in shell.js and takes three arguments: + * - a string representation of what is being tested + * - the expected result + * - the actual result + * + * For example, a test might look like this: + * + * var zip = /[\d]{5}$/; + * + * AddTestCase( + * "zip = /[\d]{5}$/; \"PO Box 12345 Boston, MA 02134\".match(zip)", // description of the test + * "02134", // expected result + * "PO Box 12345 Boston, MA 02134".match(zip) ); // actual result + * + */ + +var s = "x"; +for (var i = 0; i != 13; i++) s += s; +var a = /(?:xx|x)*/.exec(s); +var b = /(xx|x)*/.exec(s); + +AddTestCase( "var s = 'x'; for (var i = 0; i != 13; i++) s += s; " + + "a = /(?:xx|x)*/.exec(s); a.length", + 1, + a.length ); + +AddTestCase( "var b = /(xx|x)*/.exec(s); b.length", + 2, + b.length ); + +test(); // leave this alone. this executes the test cases and +// displays results. diff --git a/js/src/tests/non262/RegExp/regress-98306.js b/js/src/tests/non262/RegExp/regress-98306.js new file mode 100644 index 0000000000..261f0de316 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-98306.js @@ -0,0 +1,63 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 04 September 2001 + * + * SUMMARY: Regression test for Bugzilla bug 98306 + * "JS parser crashes in ParseAtom for script using Regexp()" + * + * See http://bugzilla.mozilla.org/show_bug.cgi?id=98306 + */ +//----------------------------------------------------------------------------- +var BUGNUMBER = 98306; +var summary = "Testing that we don't crash on this code -"; +var cnUBOUND = 10; +var re; +var s; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + s = '"Hello".match(/[/]/)'; + tryThis(s); + + s = 're = /[/'; + tryThis(s); + + s = 're = /[/]/'; + tryThis(s); + + s = 're = /[//]/'; + tryThis(s); + + reportCompare('No Crash', 'No Crash', ''); +} + + +// Try to provoke a crash - +function tryThis(sCode) +{ + // sometimes more than one attempt is necessary - + for (var i=0; i<cnUBOUND; i++) + { + try + { + eval(sCode); + } + catch(e) + { + // do nothing; keep going - + } + } +} diff --git a/js/src/tests/non262/RegExp/regress-yarr-regexp.js b/js/src/tests/non262/RegExp/regress-yarr-regexp.js new file mode 100644 index 0000000000..58cea3f4f0 --- /dev/null +++ b/js/src/tests/non262/RegExp/regress-yarr-regexp.js @@ -0,0 +1,18 @@ +var gcgcz = /((?:.)+)((?:.)*)/; /* Greedy capture, greedy capture zero. */ +assertEqArray(["a", "a", ""], gcgcz.exec("a")); +assertEqArray(["ab", "ab", ""], gcgcz.exec("ab")); +assertEqArray(["abc", "abc", ""], gcgcz.exec("abc")); + +assertEqArray(["a", ""], /((?:)*?)a/.exec("a")); +assertEqArray(["a", ""], /((?:.)*?)a/.exec("a")); +assertEqArray(["a", ""], /a((?:.)*)/.exec("a")); + +assertEqArray(["B", "B"], /([A-Z])/.exec("fooBar")); + +// These just mustn't crash. See bug 872971 +try { reportCompare(/x{2147483648}x/.test('1'), false); } catch (e) {} +try { reportCompare(/x{2147483648,}x/.test('1'), false); } catch (e) {} +try { reportCompare(/x{2147483647,2147483648}x/.test('1'), false); } catch (e) {} +// Same for these. See bug 813366 +try { reportCompare("".match(/.{2147483647}11/), null); } catch (e) {} +try { reportCompare("".match(/(?:(?=g)).{2147483648,}/ + ""), null); } catch (e) {} diff --git a/js/src/tests/non262/RegExp/replace-compile-elembase.js b/js/src/tests/non262/RegExp/replace-compile-elembase.js new file mode 100644 index 0000000000..591d27cfe9 --- /dev/null +++ b/js/src/tests/non262/RegExp/replace-compile-elembase.js @@ -0,0 +1,22 @@ +(function() { + var rx = /a/g; + var b = { + get a() { + rx.compile("b"); + return "A"; + } + }; + + // Replacer function which is applicable for the elem-base optimization in + // RegExp.prototype.@@replace. + function replacer(a) { + return b[a]; + } + + var result = rx[Symbol.replace]("aaa", replacer); + + assertEq(result, "AAA"); +})(); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/replace-compile.js b/js/src/tests/non262/RegExp/replace-compile.js new file mode 100644 index 0000000000..45359037af --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/replace-global-unicode.js b/js/src/tests/non262/RegExp/replace-global-unicode.js new file mode 100644 index 0000000000..80b3ea1996 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/replace-local-tolength-lastindex.js b/js/src/tests/non262/RegExp/replace-local-tolength-lastindex.js new file mode 100644 index 0000000000..7ba840e000 --- /dev/null +++ b/js/src/tests/non262/RegExp/replace-local-tolength-lastindex.js @@ -0,0 +1,22 @@ +// RegExp.prototype[@@replace] always executes ToLength(regExp.lastIndex) for +// non-global RegExps. + +for (var flag of ["", "g", "y", "gy"]) { + var regExp = new RegExp("a", flag); + + var called = false; + regExp.lastIndex = { + valueOf() { + assertEq(called, false); + called = true; + return 0; + } + }; + + assertEq(called, false); + regExp[Symbol.replace](""); + assertEq(called, !flag.includes("g")); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/replace-local-tolength-recompilation.js b/js/src/tests/non262/RegExp/replace-local-tolength-recompilation.js new file mode 100644 index 0000000000..e03177286f --- /dev/null +++ b/js/src/tests/non262/RegExp/replace-local-tolength-recompilation.js @@ -0,0 +1,75 @@ +// Side-effects when calling ToLength(regExp.lastIndex) in +// RegExp.prototype[@@replace] for non-global RegExp can recompile the RegExp. + +for (var flag of ["", "y"]) { + var regExp = new RegExp("a", flag); + + regExp.lastIndex = { + valueOf() { + regExp.compile("b"); + return 0; + } + }; + + var result = regExp[Symbol.replace]("b", "pass"); + assertEq(result, "pass"); +} + +// Recompilation modifies flag: +// Case 1: Adds global flag, validate by checking lastIndex. +var regExp = new RegExp("a", ""); +regExp.lastIndex = { + valueOf() { + // |regExp| is now in global mode, RegExpBuiltinExec should update the + // lastIndex property to reflect last match. + regExp.compile("a", "g"); + return 0; + } +}; +regExp[Symbol.replace]("a", ""); +assertEq(regExp.lastIndex, 1); + +// Case 2: Removes sticky flag with match, validate by checking lastIndex. +var regExp = new RegExp("a", "y"); +regExp.lastIndex = { + valueOf() { + // |regExp| is no longer sticky, RegExpBuiltinExec shouldn't modify the + // lastIndex property. + regExp.compile("a", ""); + regExp.lastIndex = 9000; + return 0; + } +}; +regExp[Symbol.replace]("a", ""); +assertEq(regExp.lastIndex, 9000); + +// Case 3.a: Removes sticky flag without match, validate by checking lastIndex. +var regExp = new RegExp("a", "y"); +regExp.lastIndex = { + valueOf() { + // |regExp| is no longer sticky, RegExpBuiltinExec shouldn't modify the + // lastIndex property. + regExp.compile("b", ""); + regExp.lastIndex = 9001; + return 0; + } +}; +regExp[Symbol.replace]("a", ""); +assertEq(regExp.lastIndex, 9001); + +// Case 3.b: Removes sticky flag without match, validate by checking lastIndex. +var regExp = new RegExp("a", "y"); +regExp.lastIndex = { + valueOf() { + // |regExp| is no longer sticky, RegExpBuiltinExec shouldn't modify the + // lastIndex property. + regExp.compile("b", ""); + regExp.lastIndex = 9002; + return 10000; + } +}; +regExp[Symbol.replace]("a", ""); +assertEq(regExp.lastIndex, 9002); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/replace-sticky-lastIndex.js b/js/src/tests/non262/RegExp/replace-sticky-lastIndex.js new file mode 100644 index 0000000000..2500b2c42d --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/replace-sticky.js b/js/src/tests/non262/RegExp/replace-sticky.js new file mode 100644 index 0000000000..32a6e2aee0 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/replace-this.js b/js/src/tests/non262/RegExp/replace-this.js new file mode 100644 index 0000000000..499304f9c0 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/replace-trace.js b/js/src/tests/non262/RegExp/replace-trace.js new file mode 100644 index 0000000000..8ddf0990e0 --- /dev/null +++ b/js/src/tests/non262/RegExp/replace-trace.js @@ -0,0 +1,299 @@ +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 flags() { + log += "get:flags,"; + var flags = ""; + if (global) flags += "g"; + if (unicode) flags += "u"; + return flags; + }, + 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"; + 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:flags," + + "set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:exec,call:exec," + + "get:result[length],get:result[0],get:result[index],get:result[groups],"); + +// 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:flags," + + "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[groups],"); + +// 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:flags," + + "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[groups]," + + "get:result[length],get:result[0],get:result[index],get:result[groups]," + + "get:result[length],get:result[0],get:result[index],get:result[groups]," + + "get:result[length],get:result[0],get:result[index],get:result[groups]," + + "get:result[length],get:result[0],get:result[index],get:result[groups],"); + +// 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:flags," + + "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],get:result[groups],"); + +// 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:flags," + + "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],get:result[groups],"); + +// 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:flags," + + "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],get:result[groups]," + + "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:flags," + + "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[groups]," + + "get:result[length],get:result[0],get:result[index],get:result[groups],"); + +// 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:flags," + + "set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:exec,call:exec," + + "get:result[length],get:result[0],get:result[index],get:result[groups],"); + +// 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:flags," + + "set:lastIndex," + + "get:exec,call:exec," + + "get:result[0]," + + "get:exec,call:exec," + + "get:result[length],get:result[0],get:result[index],get:result[groups],"); + +// 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:flags," + + "get:exec,call:exec," + + "get:result[length],get:result[0],get:result[index],get:result[groups],"); + +stopObserve(); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/replace-twoBytes.js b/js/src/tests/non262/RegExp/replace-twoBytes.js new file mode 100644 index 0000000000..660677c9f1 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/replace.js b/js/src/tests/non262/RegExp/replace.js new file mode 100644 index 0000000000..304531a5df --- /dev/null +++ b/js/src/tests/non262/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_$+_$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_$+_$345"); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/search-this.js b/js/src/tests/non262/RegExp/search-this.js new file mode 100644 index 0000000000..731f5480fa --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/search-trace.js b/js/src/tests/non262/RegExp/search-trace.js new file mode 100644 index 0000000000..fc6bee754c --- /dev/null +++ b/js/src/tests/non262/RegExp/search-trace.js @@ -0,0 +1,78 @@ +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," + + "get:lastIndex," + + "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," + + "get:lastIndex," + + "set:lastIndex,"); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/search.js b/js/src/tests/non262/RegExp/search.js new file mode 100644 index 0000000000..0875ee47ed --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/shell.js b/js/src/tests/non262/RegExp/shell.js new file mode 100644 index 0000000000..8d52ad35df --- /dev/null +++ b/js/src/tests/non262/RegExp/shell.js @@ -0,0 +1,256 @@ +/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Date: 07 February 2001 + * + * Functionality common to RegExp testing - + */ +//----------------------------------------------------------------------------- + +(function(global) { + + var MSG_PATTERN = '\nregexp = '; + var MSG_STRING = '\nstring = '; + var MSG_EXPECT = '\nExpect: '; + var MSG_ACTUAL = '\nActual: '; + var ERR_LENGTH = '\nERROR !!! match arrays have different lengths:'; + var ERR_MATCH = '\nERROR !!! regexp failed to give expected match array:'; + var ERR_NO_MATCH = '\nERROR !!! regexp FAILED to match anything !!!'; + var ERR_UNEXP_MATCH = '\nERROR !!! regexp MATCHED when we expected it to fail !!!'; + var CHAR_LBRACKET = '['; + var CHAR_RBRACKET = ']'; + var CHAR_QT_DBL = '"'; + var CHAR_QT = "'"; + var CHAR_NL = '\n'; + var CHAR_COMMA = ','; + var CHAR_SPACE = ' '; + var TYPE_STRING = typeof 'abc'; + + + + global.testRegExp = function testRegExp(statuses, patterns, strings, actualmatches, expectedmatches) + { + var status = ''; + var pattern = new RegExp(); + var string = ''; + var actualmatch = new Array(); + var expectedmatch = new Array(); + var state = ''; + var lActual = -1; + var lExpect = -1; + + + for (var i=0; i != patterns.length; i++) + { + status = statuses[i]; + pattern = patterns[i]; + string = strings[i]; + actualmatch=actualmatches[i]; + expectedmatch=expectedmatches[i]; + state = getState(status, pattern, string); + + description = status; + + if(actualmatch) + { + actual = formatArray(actualmatch); + if(expectedmatch) + { + // expectedmatch and actualmatch are arrays - + lExpect = expectedmatch.length; + lActual = actualmatch.length; + + var expected = formatArray(expectedmatch); + + if (lActual != lExpect) + { + reportCompare(lExpect, lActual, + state + ERR_LENGTH + + MSG_EXPECT + expected + + MSG_ACTUAL + actual + + CHAR_NL + ); + continue; + } + + // OK, the arrays have same length - + if (expected != actual) + { + reportCompare(expected, actual, + state + ERR_MATCH + + MSG_EXPECT + expected + + MSG_ACTUAL + actual + + CHAR_NL + ); + } + else + { + reportCompare(expected, actual, state) + } + + } + else //expectedmatch is null - that is, we did not expect a match - + { + expected = expectedmatch; + reportCompare(expected, actual, + state + ERR_UNEXP_MATCH + + MSG_EXPECT + expectedmatch + + MSG_ACTUAL + actual + + CHAR_NL + ); + } + + } + else // actualmatch is null + { + if (expectedmatch) + { + actual = actualmatch; + reportCompare(expected, actual, + state + ERR_NO_MATCH + + MSG_EXPECT + expectedmatch + + MSG_ACTUAL + actualmatch + + CHAR_NL + ); + } + else // we did not expect a match + { + // Being ultra-cautious. Presumably expectedmatch===actualmatch===null + expected = expectedmatch; + actual = actualmatch; + reportCompare (expectedmatch, actualmatch, state); + } + } + } + } + + function getState(status, pattern, string) + { + /* + * Escape \n's, etc. to make them LITERAL in the presentation string. + * We don't have to worry about this in |pattern|; such escaping is + * done automatically by pattern.toString(), invoked implicitly below. + * + * One would like to simply do: string = string.replace(/(\s)/g, '\$1'). + * However, the backreference $1 is not a literal string value, + * so this method doesn't work. + * + * Also tried string = string.replace(/(\s)/g, escape('$1')); + * but this just inserts the escape of the literal '$1', i.e. '%241'. + */ + string = string.replace(/\n/g, '\\n'); + string = string.replace(/\r/g, '\\r'); + string = string.replace(/\t/g, '\\t'); + string = string.replace(/\v/g, '\\v'); + string = string.replace(/\f/g, '\\f'); + + return (status + MSG_PATTERN + pattern + MSG_STRING + singleQuote(string)); + } + + + + /* + * If available, arr.toSource() gives more detail than arr.toString() + * + * var arr = Array(1,2,'3'); + * + * arr.toSource() + * [1, 2, "3"] + * + * arr.toString() + * 1,2,3 + * + * But toSource() doesn't exist in Rhino, so use our own imitation, below - + * + */ + function formatArray(arr) + { + try + { + return arr.toSource(); + } + catch(e) + { + return toSource(arr); + } + } + + + /* + * Imitate SpiderMonkey's arr.toSource() method: + * + * a) Double-quote each array element that is of string type + * b) Represent |undefined| and |null| by empty strings + * c) Delimit elements by a comma + single space + * d) Do not add delimiter at the end UNLESS the last element is |undefined| + * e) Add square brackets to the beginning and end of the string + */ + function toSource(arr) + { + var delim = CHAR_COMMA + CHAR_SPACE; + var elt = ''; + var ret = ''; + var len = arr.length; + + for (i=0; i<len; i++) + { + elt = arr[i]; + + switch(true) + { + case (typeof elt === TYPE_STRING) : + ret += doubleQuote(elt); + break; + + case (elt === undefined || elt === null) : + break; // add nothing but the delimiter, below - + + default: + ret += elt.toString(); + } + + if ((i < len-1) || (elt === undefined)) + ret += delim; + } + + return CHAR_LBRACKET + ret + CHAR_RBRACKET; + } + + + function doubleQuote(text) + { + return CHAR_QT_DBL + text + CHAR_QT_DBL; + } + + + function singleQuote(text) + { + return CHAR_QT + text + CHAR_QT; + } + + global.makeExpectedMatch = function makeExpectedMatch(arr, index, input) { + var expectedMatch = { + index: index, + input: input, + length: arr.length, + }; + + for (var i = 0; i < arr.length; ++i) + expectedMatch[i] = arr[i]; + + return expectedMatch; + } + + global.checkRegExpMatch = function checkRegExpMatch(actual, expected) { + assertEq(actual.length, expected.length); + for (var i = 0; i < actual.length; ++i) + assertEq(actual[i], expected[i]); + + assertEq(actual.index, expected.index); + assertEq(actual.input, expected.input); + } + +})(this); diff --git a/js/src/tests/non262/RegExp/source.js b/js/src/tests/non262/RegExp/source.js new file mode 100644 index 0000000000..354a9d19de --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/split-deleted-flags.js b/js/src/tests/non262/RegExp/split-deleted-flags.js new file mode 100644 index 0000000000..d2ccc852d1 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/split-flags-on-obj.js b/js/src/tests/non262/RegExp/split-flags-on-obj.js new file mode 100644 index 0000000000..8c68efed57 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/split-invalid-lastIndex.js b/js/src/tests/non262/RegExp/split-invalid-lastIndex.js new file mode 100644 index 0000000000..3def559ad0 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/split-limit.js b/js/src/tests/non262/RegExp/split-limit.js new file mode 100644 index 0000000000..5fa194b90b --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/split-obj.js b/js/src/tests/non262/RegExp/split-obj.js new file mode 100644 index 0000000000..75c09f38d1 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/split-prop-access.js b/js/src/tests/non262/RegExp/split-prop-access.js new file mode 100644 index 0000000000..73c5bebb31 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/split-this.js b/js/src/tests/non262/RegExp/split-this.js new file mode 100644 index 0000000000..ece29fe8a2 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/split-trace.js b/js/src/tests/non262/RegExp/split-trace.js new file mode 100644 index 0000000000..fe7fe95981 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/split.js b/js/src/tests/non262/RegExp/split.js new file mode 100644 index 0000000000..d7e28d7919 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/sticky.js b/js/src/tests/non262/RegExp/sticky.js new file mode 100644 index 0000000000..13a6debe95 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/test-emptyMatch.js b/js/src/tests/non262/RegExp/test-emptyMatch.js new file mode 100644 index 0000000000..6103c28d52 --- /dev/null +++ b/js/src/tests/non262/RegExp/test-emptyMatch.js @@ -0,0 +1,23 @@ +var BUGNUMBER = 1322035; +var summary = 'RegExp.prototype.test should update lastIndex to correct position even if pattern starts with .*'; + +print(BUGNUMBER + ": " + summary); + +var regExp = /.*x?/g; +regExp.test('12345'); +assertEq(regExp.lastIndex, 5); + +regExp = /.*x*/g; +regExp.test('12345'); +assertEq(regExp.lastIndex, 5); + +regExp = /.*()/g; +regExp.test('12345'); +assertEq(regExp.lastIndex, 5); + +regExp = /.*(x|)/g; +regExp.test('12345'); +assertEq(regExp.lastIndex, 5); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/test-trailing.js b/js/src/tests/non262/RegExp/test-trailing.js new file mode 100644 index 0000000000..7cb910ee62 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/toString.js b/js/src/tests/non262/RegExp/toString.js new file mode 100644 index 0000000000..5ffbeed331 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-back-reference.js b/js/src/tests/non262/RegExp/unicode-back-reference.js new file mode 100644 index 0000000000..2a65432a1d --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-braced.js b/js/src/tests/non262/RegExp/unicode-braced.js new file mode 100644 index 0000000000..97df7acabf --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-character-class-escape.js b/js/src/tests/non262/RegExp/unicode-character-class-escape.js new file mode 100644 index 0000000000..175207d5ae --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-class-braced.js b/js/src/tests/non262/RegExp/unicode-class-braced.js new file mode 100644 index 0000000000..4b59540129 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-class-empty.js b/js/src/tests/non262/RegExp/unicode-class-empty.js new file mode 100644 index 0000000000..4d187551f6 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-class-ignoreCase.js b/js/src/tests/non262/RegExp/unicode-class-ignoreCase.js new file mode 100644 index 0000000000..afa7705c72 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-class-lead-trail.js b/js/src/tests/non262/RegExp/unicode-class-lead-trail.js new file mode 100644 index 0000000000..c83bf937d4 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-class-negated.js b/js/src/tests/non262/RegExp/unicode-class-negated.js new file mode 100644 index 0000000000..0b573f6dcf --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-class-range.js b/js/src/tests/non262/RegExp/unicode-class-range.js new file mode 100644 index 0000000000..5bb7575601 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-class-raw.js b/js/src/tests/non262/RegExp/unicode-class-raw.js new file mode 100644 index 0000000000..742fec2b4d --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-disallow-extended.js b/js/src/tests/non262/RegExp/unicode-disallow-extended.js new file mode 100644 index 0000000000..01d5d244e1 --- /dev/null +++ b/js/src/tests/non262/RegExp/unicode-disallow-extended.js @@ -0,0 +1,139 @@ +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); + +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); + +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); + +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/non262/RegExp/unicode-everything.js b/js/src/tests/non262/RegExp/unicode-everything.js new file mode 100644 index 0000000000..a18ac2867a --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-ignoreCase-ascii.js b/js/src/tests/non262/RegExp/unicode-ignoreCase-ascii.js new file mode 100644 index 0000000000..6d453290e9 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-ignoreCase-escape.js b/js/src/tests/non262/RegExp/unicode-ignoreCase-escape.js new file mode 100644 index 0000000000..d731fb6bbe --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-ignoreCase-negated.js b/js/src/tests/non262/RegExp/unicode-ignoreCase-negated.js new file mode 100644 index 0000000000..30909a515a --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-ignoreCase-word-boundary.js b/js/src/tests/non262/RegExp/unicode-ignoreCase-word-boundary.js new file mode 100644 index 0000000000..a5698de365 --- /dev/null +++ b/js/src/tests/non262/RegExp/unicode-ignoreCase-word-boundary.js @@ -0,0 +1,46 @@ +var BUGNUMBER = 1338373; +var summary = "Word boundary should match U+017F and U+212A in unicode+ignoreCase."; + +assertEq(/\b/iu.test('\u017F'), true); +assertEq(/\b/i.test('\u017F'), false); +assertEq(/\b/u.test('\u017F'), false); +assertEq(/\b/.test('\u017F'), false); + +assertEq(/\b/iu.test('\u212A'), true); +assertEq(/\b/i.test('\u212A'), false); +assertEq(/\b/u.test('\u212A'), false); +assertEq(/\b/.test('\u212A'), false); + +assertEq(/\B/iu.test('\u017F'), false); +assertEq(/\B/i.test('\u017F'), true); +assertEq(/\B/u.test('\u017F'), true); +assertEq(/\B/.test('\u017F'), true); + +assertEq(/\B/iu.test('\u212A'), false); +assertEq(/\B/i.test('\u212A'), true); +assertEq(/\B/u.test('\u212A'), true); +assertEq(/\B/.test('\u212A'), true); + +// Bug 1338779 - More testcases. +assertEq(/(i\B\u017F)/ui.test("is"), true); +assertEq(/(i\B\u017F)/ui.test("it"), false); +assertEq(/(i\B\u017F)+/ui.test("is"), true); +assertEq(/(i\B\u017F)+/ui.test("it"), false); + +assertEq(/(\u017F\Bi)/ui.test("si"), true); +assertEq(/(\u017F\Bi)/ui.test("ti"), false); +assertEq(/(\u017F\Bi)+/ui.test("si"), true); +assertEq(/(\u017F\Bi)+/ui.test("ti"), false); + +assertEq(/(i\B\u212A)/ui.test("ik"), true); +assertEq(/(i\B\u212A)/ui.test("it"), false); +assertEq(/(i\B\u212A)+/ui.test("ik"), true); +assertEq(/(i\B\u212A)+/ui.test("it"), false); + +assertEq(/(\u212A\Bi)/ui.test("ki"), true); +assertEq(/(\u212A\Bi)/ui.test("ti"), false); +assertEq(/(\u212A\Bi)+/ui.test("ki"), true); +assertEq(/(\u212A\Bi)+/ui.test("ti"), false); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/unicode-ignoreCase.js b/js/src/tests/non262/RegExp/unicode-ignoreCase.js new file mode 100644 index 0000000000..2cf489f310 --- /dev/null +++ b/js/src/tests/non262/RegExp/unicode-ignoreCase.js @@ -0,0 +1,2901 @@ +/* Generated by make_unicode.py DO NOT MODIFY */ +/* Unicode version: 15.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(0x0041, 0x0061); // LATIN CAPITAL LETTER A, LATIN SMALL LETTER A +test(0x0042, 0x0062); // LATIN CAPITAL LETTER B, LATIN SMALL LETTER B +test(0x0043, 0x0063); // LATIN CAPITAL LETTER C, LATIN SMALL LETTER C +test(0x0044, 0x0064); // LATIN CAPITAL LETTER D, LATIN SMALL LETTER D +test(0x0045, 0x0065); // LATIN CAPITAL LETTER E, LATIN SMALL LETTER E +test(0x0046, 0x0066); // LATIN CAPITAL LETTER F, LATIN SMALL LETTER F +test(0x0047, 0x0067); // LATIN CAPITAL LETTER G, LATIN SMALL LETTER G +test(0x0048, 0x0068); // LATIN CAPITAL LETTER H, LATIN SMALL LETTER H +test(0x0049, 0x0069); // LATIN CAPITAL LETTER I, LATIN SMALL LETTER I +test(0x004A, 0x006A); // LATIN CAPITAL LETTER J, LATIN SMALL LETTER J +test(0x004B, 0x006B, 0x212A); // LATIN CAPITAL LETTER K, LATIN SMALL LETTER K, KELVIN SIGN (DEGREES KELVIN) +test(0x004C, 0x006C); // LATIN CAPITAL LETTER L, LATIN SMALL LETTER L +test(0x004D, 0x006D); // LATIN CAPITAL LETTER M, LATIN SMALL LETTER M +test(0x004E, 0x006E); // LATIN CAPITAL LETTER N, LATIN SMALL LETTER N +test(0x004F, 0x006F); // LATIN CAPITAL LETTER O, LATIN SMALL LETTER O +test(0x0050, 0x0070); // LATIN CAPITAL LETTER P, LATIN SMALL LETTER P +test(0x0051, 0x0071); // LATIN CAPITAL LETTER Q, LATIN SMALL LETTER Q +test(0x0052, 0x0072); // LATIN CAPITAL LETTER R, LATIN SMALL LETTER R +test(0x0053, 0x0073, 0x017F); // LATIN CAPITAL LETTER S, LATIN SMALL LETTER S, LATIN SMALL LETTER LONG S +test(0x0054, 0x0074); // LATIN CAPITAL LETTER T, LATIN SMALL LETTER T +test(0x0055, 0x0075); // LATIN CAPITAL LETTER U, LATIN SMALL LETTER U +test(0x0056, 0x0076); // LATIN CAPITAL LETTER V, LATIN SMALL LETTER V +test(0x0057, 0x0077); // LATIN CAPITAL LETTER W, LATIN SMALL LETTER W +test(0x0058, 0x0078); // LATIN CAPITAL LETTER X, LATIN SMALL LETTER X +test(0x0059, 0x0079); // LATIN CAPITAL LETTER Y, LATIN SMALL LETTER Y +test(0x005A, 0x007A); // LATIN CAPITAL LETTER Z, LATIN SMALL LETTER Z +test(0x0061, 0x0041); // LATIN SMALL LETTER A, LATIN CAPITAL LETTER A +test(0x0062, 0x0042); // LATIN SMALL LETTER B, LATIN CAPITAL LETTER B +test(0x0063, 0x0043); // LATIN SMALL LETTER C, LATIN CAPITAL LETTER C +test(0x0064, 0x0044); // LATIN SMALL LETTER D, LATIN CAPITAL LETTER D +test(0x0065, 0x0045); // LATIN SMALL LETTER E, LATIN CAPITAL LETTER E +test(0x0066, 0x0046); // LATIN SMALL LETTER F, LATIN CAPITAL LETTER F +test(0x0067, 0x0047); // LATIN SMALL LETTER G, LATIN CAPITAL LETTER G +test(0x0068, 0x0048); // LATIN SMALL LETTER H, LATIN CAPITAL LETTER H +test(0x0069, 0x0049); // LATIN SMALL LETTER I, LATIN CAPITAL LETTER I +test(0x006A, 0x004A); // LATIN SMALL LETTER J, LATIN CAPITAL LETTER J +test(0x006B, 0x004B, 0x212A); // LATIN SMALL LETTER K, LATIN CAPITAL LETTER K, KELVIN SIGN (DEGREES KELVIN) +test(0x006C, 0x004C); // LATIN SMALL LETTER L, LATIN CAPITAL LETTER L +test(0x006D, 0x004D); // LATIN SMALL LETTER M, LATIN CAPITAL LETTER M +test(0x006E, 0x004E); // LATIN SMALL LETTER N, LATIN CAPITAL LETTER N +test(0x006F, 0x004F); // LATIN SMALL LETTER O, LATIN CAPITAL LETTER O +test(0x0070, 0x0050); // LATIN SMALL LETTER P, LATIN CAPITAL LETTER P +test(0x0071, 0x0051); // LATIN SMALL LETTER Q, LATIN CAPITAL LETTER Q +test(0x0072, 0x0052); // LATIN SMALL LETTER R, LATIN CAPITAL LETTER R +test(0x0073, 0x0053, 0x017F); // LATIN SMALL LETTER S, LATIN CAPITAL LETTER S, LATIN SMALL LETTER LONG S +test(0x0074, 0x0054); // LATIN SMALL LETTER T, LATIN CAPITAL LETTER T +test(0x0075, 0x0055); // LATIN SMALL LETTER U, LATIN CAPITAL LETTER U +test(0x0076, 0x0056); // LATIN SMALL LETTER V, LATIN CAPITAL LETTER V +test(0x0077, 0x0057); // LATIN SMALL LETTER W, LATIN CAPITAL LETTER W +test(0x0078, 0x0058); // LATIN SMALL LETTER X, LATIN CAPITAL LETTER X +test(0x0079, 0x0059); // LATIN SMALL LETTER Y, LATIN CAPITAL LETTER Y +test(0x007A, 0x005A); // LATIN SMALL LETTER Z, LATIN CAPITAL LETTER Z +test(0x00B5, 0x03BC, 0x039C); // MICRO SIGN, GREEK SMALL LETTER MU, GREEK CAPITAL LETTER MU +test(0x00C0, 0x00E0); // LATIN CAPITAL LETTER A WITH GRAVE (LATIN CAPITAL LETTER A GRAVE), LATIN SMALL LETTER A WITH GRAVE (LATIN SMALL LETTER A GRAVE) +test(0x00C1, 0x00E1); // LATIN CAPITAL LETTER A WITH ACUTE (LATIN CAPITAL LETTER A ACUTE), LATIN SMALL LETTER A WITH ACUTE (LATIN SMALL LETTER A ACUTE) +test(0x00C2, 0x00E2); // LATIN CAPITAL LETTER A WITH CIRCUMFLEX (LATIN CAPITAL LETTER A CIRCUMFLEX), LATIN SMALL LETTER A WITH CIRCUMFLEX (LATIN SMALL LETTER A CIRCUMFLEX) +test(0x00C3, 0x00E3); // LATIN CAPITAL LETTER A WITH TILDE (LATIN CAPITAL LETTER A TILDE), LATIN SMALL LETTER A WITH TILDE (LATIN SMALL LETTER A TILDE) +test(0x00C4, 0x00E4); // LATIN CAPITAL LETTER A WITH DIAERESIS (LATIN CAPITAL LETTER A DIAERESIS), LATIN SMALL LETTER A WITH DIAERESIS (LATIN SMALL LETTER A DIAERESIS) +test(0x00C5, 0x00E5, 0x212B); // LATIN CAPITAL LETTER A WITH RING ABOVE (LATIN CAPITAL LETTER A RING), LATIN SMALL LETTER A WITH RING ABOVE (LATIN SMALL LETTER A RING), ANGSTROM SIGN (ANGSTROM UNIT) +test(0x00C6, 0x00E6); // LATIN CAPITAL LETTER AE (LATIN CAPITAL LETTER A E), LATIN SMALL LETTER AE (LATIN SMALL LETTER A E) +test(0x00C7, 0x00E7); // LATIN CAPITAL LETTER C WITH CEDILLA (LATIN CAPITAL LETTER C CEDILLA), LATIN SMALL LETTER C WITH CEDILLA (LATIN SMALL LETTER C CEDILLA) +test(0x00C8, 0x00E8); // LATIN CAPITAL LETTER E WITH GRAVE (LATIN CAPITAL LETTER E GRAVE), LATIN SMALL LETTER E WITH GRAVE (LATIN SMALL LETTER E GRAVE) +test(0x00C9, 0x00E9); // LATIN CAPITAL LETTER E WITH ACUTE (LATIN CAPITAL LETTER E ACUTE), LATIN SMALL LETTER E WITH ACUTE (LATIN SMALL LETTER E ACUTE) +test(0x00CA, 0x00EA); // LATIN CAPITAL LETTER E WITH CIRCUMFLEX (LATIN CAPITAL LETTER E CIRCUMFLEX), LATIN SMALL LETTER E WITH CIRCUMFLEX (LATIN SMALL LETTER E CIRCUMFLEX) +test(0x00CB, 0x00EB); // LATIN CAPITAL LETTER E WITH DIAERESIS (LATIN CAPITAL LETTER E DIAERESIS), LATIN SMALL LETTER E WITH DIAERESIS (LATIN SMALL LETTER E DIAERESIS) +test(0x00CC, 0x00EC); // LATIN CAPITAL LETTER I WITH GRAVE (LATIN CAPITAL LETTER I GRAVE), LATIN SMALL LETTER I WITH GRAVE (LATIN SMALL LETTER I GRAVE) +test(0x00CD, 0x00ED); // LATIN CAPITAL LETTER I WITH ACUTE (LATIN CAPITAL LETTER I ACUTE), LATIN SMALL LETTER I WITH ACUTE (LATIN SMALL LETTER I ACUTE) +test(0x00CE, 0x00EE); // LATIN CAPITAL LETTER I WITH CIRCUMFLEX (LATIN CAPITAL LETTER I CIRCUMFLEX), LATIN SMALL LETTER I WITH CIRCUMFLEX (LATIN SMALL LETTER I CIRCUMFLEX) +test(0x00CF, 0x00EF); // LATIN CAPITAL LETTER I WITH DIAERESIS (LATIN CAPITAL LETTER I DIAERESIS), LATIN SMALL LETTER I WITH DIAERESIS (LATIN SMALL LETTER I DIAERESIS) +test(0x00D0, 0x00F0); // LATIN CAPITAL LETTER ETH, LATIN SMALL LETTER ETH +test(0x00D1, 0x00F1); // LATIN CAPITAL LETTER N WITH TILDE (LATIN CAPITAL LETTER N TILDE), LATIN SMALL LETTER N WITH TILDE (LATIN SMALL LETTER N TILDE) +test(0x00D2, 0x00F2); // LATIN CAPITAL LETTER O WITH GRAVE (LATIN CAPITAL LETTER O GRAVE), LATIN SMALL LETTER O WITH GRAVE (LATIN SMALL LETTER O GRAVE) +test(0x00D3, 0x00F3); // LATIN CAPITAL LETTER O WITH ACUTE (LATIN CAPITAL LETTER O ACUTE), LATIN SMALL LETTER O WITH ACUTE (LATIN SMALL LETTER O ACUTE) +test(0x00D4, 0x00F4); // LATIN CAPITAL LETTER O WITH CIRCUMFLEX (LATIN CAPITAL LETTER O CIRCUMFLEX), LATIN SMALL LETTER O WITH CIRCUMFLEX (LATIN SMALL LETTER O CIRCUMFLEX) +test(0x00D5, 0x00F5); // LATIN CAPITAL LETTER O WITH TILDE (LATIN CAPITAL LETTER O TILDE), LATIN SMALL LETTER O WITH TILDE (LATIN SMALL LETTER O TILDE) +test(0x00D6, 0x00F6); // LATIN CAPITAL LETTER O WITH DIAERESIS (LATIN CAPITAL LETTER O DIAERESIS), LATIN SMALL LETTER O WITH DIAERESIS (LATIN SMALL LETTER O DIAERESIS) +test(0x00D8, 0x00F8); // LATIN CAPITAL LETTER O WITH STROKE (LATIN CAPITAL LETTER O SLASH), LATIN SMALL LETTER O WITH STROKE (LATIN SMALL LETTER O SLASH) +test(0x00D9, 0x00F9); // LATIN CAPITAL LETTER U WITH GRAVE (LATIN CAPITAL LETTER U GRAVE), LATIN SMALL LETTER U WITH GRAVE (LATIN SMALL LETTER U GRAVE) +test(0x00DA, 0x00FA); // LATIN CAPITAL LETTER U WITH ACUTE (LATIN CAPITAL LETTER U ACUTE), LATIN SMALL LETTER U WITH ACUTE (LATIN SMALL LETTER U ACUTE) +test(0x00DB, 0x00FB); // LATIN CAPITAL LETTER U WITH CIRCUMFLEX (LATIN CAPITAL LETTER U CIRCUMFLEX), LATIN SMALL LETTER U WITH CIRCUMFLEX (LATIN SMALL LETTER U CIRCUMFLEX) +test(0x00DC, 0x00FC); // LATIN CAPITAL LETTER U WITH DIAERESIS (LATIN CAPITAL LETTER U DIAERESIS), LATIN SMALL LETTER U WITH DIAERESIS (LATIN SMALL LETTER U DIAERESIS) +test(0x00DD, 0x00FD); // LATIN CAPITAL LETTER Y WITH ACUTE (LATIN CAPITAL LETTER Y ACUTE), LATIN SMALL LETTER Y WITH ACUTE (LATIN SMALL LETTER Y ACUTE) +test(0x00DE, 0x00FE); // LATIN CAPITAL LETTER THORN, LATIN SMALL LETTER THORN +test(0x00DF, 0x1E9E); // LATIN SMALL LETTER SHARP S, LATIN CAPITAL LETTER SHARP S +test(0x00E0, 0x00C0); // LATIN SMALL LETTER A WITH GRAVE (LATIN SMALL LETTER A GRAVE), LATIN CAPITAL LETTER A WITH GRAVE (LATIN CAPITAL LETTER A GRAVE) +test(0x00E1, 0x00C1); // LATIN SMALL LETTER A WITH ACUTE (LATIN SMALL LETTER A ACUTE), LATIN CAPITAL LETTER A WITH ACUTE (LATIN CAPITAL LETTER A ACUTE) +test(0x00E2, 0x00C2); // LATIN SMALL LETTER A WITH CIRCUMFLEX (LATIN SMALL LETTER A CIRCUMFLEX), LATIN CAPITAL LETTER A WITH CIRCUMFLEX (LATIN CAPITAL LETTER A CIRCUMFLEX) +test(0x00E3, 0x00C3); // LATIN SMALL LETTER A WITH TILDE (LATIN SMALL LETTER A TILDE), LATIN CAPITAL LETTER A WITH TILDE (LATIN CAPITAL LETTER A TILDE) +test(0x00E4, 0x00C4); // LATIN SMALL LETTER A WITH DIAERESIS (LATIN SMALL LETTER A DIAERESIS), LATIN CAPITAL LETTER A WITH DIAERESIS (LATIN CAPITAL LETTER A DIAERESIS) +test(0x00E5, 0x00C5, 0x212B); // LATIN SMALL LETTER A WITH RING ABOVE (LATIN SMALL LETTER A RING), LATIN CAPITAL LETTER A WITH RING ABOVE (LATIN CAPITAL LETTER A RING), ANGSTROM SIGN (ANGSTROM UNIT) +test(0x00E6, 0x00C6); // LATIN SMALL LETTER AE (LATIN SMALL LETTER A E), LATIN CAPITAL LETTER AE (LATIN CAPITAL LETTER A E) +test(0x00E7, 0x00C7); // LATIN SMALL LETTER C WITH CEDILLA (LATIN SMALL LETTER C CEDILLA), LATIN CAPITAL LETTER C WITH CEDILLA (LATIN CAPITAL LETTER C CEDILLA) +test(0x00E8, 0x00C8); // LATIN SMALL LETTER E WITH GRAVE (LATIN SMALL LETTER E GRAVE), LATIN CAPITAL LETTER E WITH GRAVE (LATIN CAPITAL LETTER E GRAVE) +test(0x00E9, 0x00C9); // LATIN SMALL LETTER E WITH ACUTE (LATIN SMALL LETTER E ACUTE), LATIN CAPITAL LETTER E WITH ACUTE (LATIN CAPITAL LETTER E ACUTE) +test(0x00EA, 0x00CA); // LATIN SMALL LETTER E WITH CIRCUMFLEX (LATIN SMALL LETTER E CIRCUMFLEX), LATIN CAPITAL LETTER E WITH CIRCUMFLEX (LATIN CAPITAL LETTER E CIRCUMFLEX) +test(0x00EB, 0x00CB); // LATIN SMALL LETTER E WITH DIAERESIS (LATIN SMALL LETTER E DIAERESIS), LATIN CAPITAL LETTER E WITH DIAERESIS (LATIN CAPITAL LETTER E DIAERESIS) +test(0x00EC, 0x00CC); // LATIN SMALL LETTER I WITH GRAVE (LATIN SMALL LETTER I GRAVE), LATIN CAPITAL LETTER I WITH GRAVE (LATIN CAPITAL LETTER I GRAVE) +test(0x00ED, 0x00CD); // LATIN SMALL LETTER I WITH ACUTE (LATIN SMALL LETTER I ACUTE), LATIN CAPITAL LETTER I WITH ACUTE (LATIN CAPITAL LETTER I ACUTE) +test(0x00EE, 0x00CE); // LATIN SMALL LETTER I WITH CIRCUMFLEX (LATIN SMALL LETTER I CIRCUMFLEX), LATIN CAPITAL LETTER I WITH CIRCUMFLEX (LATIN CAPITAL LETTER I CIRCUMFLEX) +test(0x00EF, 0x00CF); // LATIN SMALL LETTER I WITH DIAERESIS (LATIN SMALL LETTER I DIAERESIS), LATIN CAPITAL LETTER I WITH DIAERESIS (LATIN CAPITAL LETTER I DIAERESIS) +test(0x00F0, 0x00D0); // LATIN SMALL LETTER ETH, LATIN CAPITAL LETTER ETH +test(0x00F1, 0x00D1); // LATIN SMALL LETTER N WITH TILDE (LATIN SMALL LETTER N TILDE), LATIN CAPITAL LETTER N WITH TILDE (LATIN CAPITAL LETTER N TILDE) +test(0x00F2, 0x00D2); // LATIN SMALL LETTER O WITH GRAVE (LATIN SMALL LETTER O GRAVE), LATIN CAPITAL LETTER O WITH GRAVE (LATIN CAPITAL LETTER O GRAVE) +test(0x00F3, 0x00D3); // LATIN SMALL LETTER O WITH ACUTE (LATIN SMALL LETTER O ACUTE), LATIN CAPITAL LETTER O WITH ACUTE (LATIN CAPITAL LETTER O ACUTE) +test(0x00F4, 0x00D4); // LATIN SMALL LETTER O WITH CIRCUMFLEX (LATIN SMALL LETTER O CIRCUMFLEX), LATIN CAPITAL LETTER O WITH CIRCUMFLEX (LATIN CAPITAL LETTER O CIRCUMFLEX) +test(0x00F5, 0x00D5); // LATIN SMALL LETTER O WITH TILDE (LATIN SMALL LETTER O TILDE), LATIN CAPITAL LETTER O WITH TILDE (LATIN CAPITAL LETTER O TILDE) +test(0x00F6, 0x00D6); // LATIN SMALL LETTER O WITH DIAERESIS (LATIN SMALL LETTER O DIAERESIS), LATIN CAPITAL LETTER O WITH DIAERESIS (LATIN CAPITAL LETTER O DIAERESIS) +test(0x00F8, 0x00D8); // LATIN SMALL LETTER O WITH STROKE (LATIN SMALL LETTER O SLASH), LATIN CAPITAL LETTER O WITH STROKE (LATIN CAPITAL LETTER O SLASH) +test(0x00F9, 0x00D9); // LATIN SMALL LETTER U WITH GRAVE (LATIN SMALL LETTER U GRAVE), LATIN CAPITAL LETTER U WITH GRAVE (LATIN CAPITAL LETTER U GRAVE) +test(0x00FA, 0x00DA); // LATIN SMALL LETTER U WITH ACUTE (LATIN SMALL LETTER U ACUTE), LATIN CAPITAL LETTER U WITH ACUTE (LATIN CAPITAL LETTER U ACUTE) +test(0x00FB, 0x00DB); // LATIN SMALL LETTER U WITH CIRCUMFLEX (LATIN SMALL LETTER U CIRCUMFLEX), LATIN CAPITAL LETTER U WITH CIRCUMFLEX (LATIN CAPITAL LETTER U CIRCUMFLEX) +test(0x00FC, 0x00DC); // LATIN SMALL LETTER U WITH DIAERESIS (LATIN SMALL LETTER U DIAERESIS), LATIN CAPITAL LETTER U WITH DIAERESIS (LATIN CAPITAL LETTER U DIAERESIS) +test(0x00FD, 0x00DD); // LATIN SMALL LETTER Y WITH ACUTE (LATIN SMALL LETTER Y ACUTE), LATIN CAPITAL LETTER Y WITH ACUTE (LATIN CAPITAL LETTER Y ACUTE) +test(0x00FE, 0x00DE); // LATIN SMALL LETTER THORN, LATIN CAPITAL LETTER THORN +test(0x00FF, 0x0178); // LATIN SMALL LETTER Y WITH DIAERESIS (LATIN SMALL LETTER Y DIAERESIS), LATIN CAPITAL LETTER Y WITH DIAERESIS (LATIN CAPITAL LETTER Y DIAERESIS) +test(0x0100, 0x0101); // LATIN CAPITAL LETTER A WITH MACRON (LATIN CAPITAL LETTER A MACRON), LATIN SMALL LETTER A WITH MACRON (LATIN SMALL LETTER A MACRON) +test(0x0101, 0x0100); // LATIN SMALL LETTER A WITH MACRON (LATIN SMALL LETTER A MACRON), LATIN CAPITAL LETTER A WITH MACRON (LATIN CAPITAL LETTER A MACRON) +test(0x0102, 0x0103); // LATIN CAPITAL LETTER A WITH BREVE (LATIN CAPITAL LETTER A BREVE), LATIN SMALL LETTER A WITH BREVE (LATIN SMALL LETTER A BREVE) +test(0x0103, 0x0102); // LATIN SMALL LETTER A WITH BREVE (LATIN SMALL LETTER A BREVE), LATIN CAPITAL LETTER A WITH BREVE (LATIN CAPITAL LETTER A BREVE) +test(0x0104, 0x0105); // LATIN CAPITAL LETTER A WITH OGONEK (LATIN CAPITAL LETTER A OGONEK), LATIN SMALL LETTER A WITH OGONEK (LATIN SMALL LETTER A OGONEK) +test(0x0105, 0x0104); // LATIN SMALL LETTER A WITH OGONEK (LATIN SMALL LETTER A OGONEK), LATIN CAPITAL LETTER A WITH OGONEK (LATIN CAPITAL LETTER A OGONEK) +test(0x0106, 0x0107); // LATIN CAPITAL LETTER C WITH ACUTE (LATIN CAPITAL LETTER C ACUTE), LATIN SMALL LETTER C WITH ACUTE (LATIN SMALL LETTER C ACUTE) +test(0x0107, 0x0106); // LATIN SMALL LETTER C WITH ACUTE (LATIN SMALL LETTER C ACUTE), LATIN CAPITAL LETTER C WITH ACUTE (LATIN CAPITAL LETTER C ACUTE) +test(0x0108, 0x0109); // LATIN CAPITAL LETTER C WITH CIRCUMFLEX (LATIN CAPITAL LETTER C CIRCUMFLEX), LATIN SMALL LETTER C WITH CIRCUMFLEX (LATIN SMALL LETTER C CIRCUMFLEX) +test(0x0109, 0x0108); // LATIN SMALL LETTER C WITH CIRCUMFLEX (LATIN SMALL LETTER C CIRCUMFLEX), LATIN CAPITAL LETTER C WITH CIRCUMFLEX (LATIN CAPITAL LETTER C CIRCUMFLEX) +test(0x010A, 0x010B); // LATIN CAPITAL LETTER C WITH DOT ABOVE (LATIN CAPITAL LETTER C DOT), LATIN SMALL LETTER C WITH DOT ABOVE (LATIN SMALL LETTER C DOT) +test(0x010B, 0x010A); // LATIN SMALL LETTER C WITH DOT ABOVE (LATIN SMALL LETTER C DOT), LATIN CAPITAL LETTER C WITH DOT ABOVE (LATIN CAPITAL LETTER C DOT) +test(0x010C, 0x010D); // LATIN CAPITAL LETTER C WITH CARON (LATIN CAPITAL LETTER C HACEK), LATIN SMALL LETTER C WITH CARON (LATIN SMALL LETTER C HACEK) +test(0x010D, 0x010C); // LATIN SMALL LETTER C WITH CARON (LATIN SMALL LETTER C HACEK), LATIN CAPITAL LETTER C WITH CARON (LATIN CAPITAL LETTER C HACEK) +test(0x010E, 0x010F); // LATIN CAPITAL LETTER D WITH CARON (LATIN CAPITAL LETTER D HACEK), LATIN SMALL LETTER D WITH CARON (LATIN SMALL LETTER D HACEK) +test(0x010F, 0x010E); // LATIN SMALL LETTER D WITH CARON (LATIN SMALL LETTER D HACEK), LATIN CAPITAL LETTER D WITH CARON (LATIN CAPITAL LETTER D HACEK) +test(0x0110, 0x0111); // LATIN CAPITAL LETTER D WITH STROKE (LATIN CAPITAL LETTER D BAR), LATIN SMALL LETTER D WITH STROKE (LATIN SMALL LETTER D BAR) +test(0x0111, 0x0110); // LATIN SMALL LETTER D WITH STROKE (LATIN SMALL LETTER D BAR), LATIN CAPITAL LETTER D WITH STROKE (LATIN CAPITAL LETTER D BAR) +test(0x0112, 0x0113); // LATIN CAPITAL LETTER E WITH MACRON (LATIN CAPITAL LETTER E MACRON), LATIN SMALL LETTER E WITH MACRON (LATIN SMALL LETTER E MACRON) +test(0x0113, 0x0112); // LATIN SMALL LETTER E WITH MACRON (LATIN SMALL LETTER E MACRON), LATIN CAPITAL LETTER E WITH MACRON (LATIN CAPITAL LETTER E MACRON) +test(0x0114, 0x0115); // LATIN CAPITAL LETTER E WITH BREVE (LATIN CAPITAL LETTER E BREVE), LATIN SMALL LETTER E WITH BREVE (LATIN SMALL LETTER E BREVE) +test(0x0115, 0x0114); // LATIN SMALL LETTER E WITH BREVE (LATIN SMALL LETTER E BREVE), LATIN CAPITAL LETTER E WITH BREVE (LATIN CAPITAL LETTER E BREVE) +test(0x0116, 0x0117); // LATIN CAPITAL LETTER E WITH DOT ABOVE (LATIN CAPITAL LETTER E DOT), LATIN SMALL LETTER E WITH DOT ABOVE (LATIN SMALL LETTER E DOT) +test(0x0117, 0x0116); // LATIN SMALL LETTER E WITH DOT ABOVE (LATIN SMALL LETTER E DOT), LATIN CAPITAL LETTER E WITH DOT ABOVE (LATIN CAPITAL LETTER E DOT) +test(0x0118, 0x0119); // LATIN CAPITAL LETTER E WITH OGONEK (LATIN CAPITAL LETTER E OGONEK), LATIN SMALL LETTER E WITH OGONEK (LATIN SMALL LETTER E OGONEK) +test(0x0119, 0x0118); // LATIN SMALL LETTER E WITH OGONEK (LATIN SMALL LETTER E OGONEK), LATIN CAPITAL LETTER E WITH OGONEK (LATIN CAPITAL LETTER E OGONEK) +test(0x011A, 0x011B); // LATIN CAPITAL LETTER E WITH CARON (LATIN CAPITAL LETTER E HACEK), LATIN SMALL LETTER E WITH CARON (LATIN SMALL LETTER E HACEK) +test(0x011B, 0x011A); // LATIN SMALL LETTER E WITH CARON (LATIN SMALL LETTER E HACEK), LATIN CAPITAL LETTER E WITH CARON (LATIN CAPITAL LETTER E HACEK) +test(0x011C, 0x011D); // LATIN CAPITAL LETTER G WITH CIRCUMFLEX (LATIN CAPITAL LETTER G CIRCUMFLEX), LATIN SMALL LETTER G WITH CIRCUMFLEX (LATIN SMALL LETTER G CIRCUMFLEX) +test(0x011D, 0x011C); // LATIN SMALL LETTER G WITH CIRCUMFLEX (LATIN SMALL LETTER G CIRCUMFLEX), LATIN CAPITAL LETTER G WITH CIRCUMFLEX (LATIN CAPITAL LETTER G CIRCUMFLEX) +test(0x011E, 0x011F); // LATIN CAPITAL LETTER G WITH BREVE (LATIN CAPITAL LETTER G BREVE), LATIN SMALL LETTER G WITH BREVE (LATIN SMALL LETTER G BREVE) +test(0x011F, 0x011E); // LATIN SMALL LETTER G WITH BREVE (LATIN SMALL LETTER G BREVE), LATIN CAPITAL LETTER G WITH BREVE (LATIN CAPITAL LETTER G BREVE) +test(0x0120, 0x0121); // LATIN CAPITAL LETTER G WITH DOT ABOVE (LATIN CAPITAL LETTER G DOT), LATIN SMALL LETTER G WITH DOT ABOVE (LATIN SMALL LETTER G DOT) +test(0x0121, 0x0120); // LATIN SMALL LETTER G WITH DOT ABOVE (LATIN SMALL LETTER G DOT), LATIN CAPITAL LETTER G WITH DOT ABOVE (LATIN CAPITAL LETTER G DOT) +test(0x0122, 0x0123); // LATIN CAPITAL LETTER G WITH CEDILLA (LATIN CAPITAL LETTER G CEDILLA), LATIN SMALL LETTER G WITH CEDILLA (LATIN SMALL LETTER G CEDILLA) +test(0x0123, 0x0122); // LATIN SMALL LETTER G WITH CEDILLA (LATIN SMALL LETTER G CEDILLA), LATIN CAPITAL LETTER G WITH CEDILLA (LATIN CAPITAL LETTER G CEDILLA) +test(0x0124, 0x0125); // LATIN CAPITAL LETTER H WITH CIRCUMFLEX (LATIN CAPITAL LETTER H CIRCUMFLEX), LATIN SMALL LETTER H WITH CIRCUMFLEX (LATIN SMALL LETTER H CIRCUMFLEX) +test(0x0125, 0x0124); // LATIN SMALL LETTER H WITH CIRCUMFLEX (LATIN SMALL LETTER H CIRCUMFLEX), LATIN CAPITAL LETTER H WITH CIRCUMFLEX (LATIN CAPITAL LETTER H CIRCUMFLEX) +test(0x0126, 0x0127); // LATIN CAPITAL LETTER H WITH STROKE (LATIN CAPITAL LETTER H BAR), LATIN SMALL LETTER H WITH STROKE (LATIN SMALL LETTER H BAR) +test(0x0127, 0x0126); // LATIN SMALL LETTER H WITH STROKE (LATIN SMALL LETTER H BAR), LATIN CAPITAL LETTER H WITH STROKE (LATIN CAPITAL LETTER H BAR) +test(0x0128, 0x0129); // LATIN CAPITAL LETTER I WITH TILDE (LATIN CAPITAL LETTER I TILDE), LATIN SMALL LETTER I WITH TILDE (LATIN SMALL LETTER I TILDE) +test(0x0129, 0x0128); // LATIN SMALL LETTER I WITH TILDE (LATIN SMALL LETTER I TILDE), LATIN CAPITAL LETTER I WITH TILDE (LATIN CAPITAL LETTER I TILDE) +test(0x012A, 0x012B); // LATIN CAPITAL LETTER I WITH MACRON (LATIN CAPITAL LETTER I MACRON), LATIN SMALL LETTER I WITH MACRON (LATIN SMALL LETTER I MACRON) +test(0x012B, 0x012A); // LATIN SMALL LETTER I WITH MACRON (LATIN SMALL LETTER I MACRON), LATIN CAPITAL LETTER I WITH MACRON (LATIN CAPITAL LETTER I MACRON) +test(0x012C, 0x012D); // LATIN CAPITAL LETTER I WITH BREVE (LATIN CAPITAL LETTER I BREVE), LATIN SMALL LETTER I WITH BREVE (LATIN SMALL LETTER I BREVE) +test(0x012D, 0x012C); // LATIN SMALL LETTER I WITH BREVE (LATIN SMALL LETTER I BREVE), LATIN CAPITAL LETTER I WITH BREVE (LATIN CAPITAL LETTER I BREVE) +test(0x012E, 0x012F); // LATIN CAPITAL LETTER I WITH OGONEK (LATIN CAPITAL LETTER I OGONEK), LATIN SMALL LETTER I WITH OGONEK (LATIN SMALL LETTER I OGONEK) +test(0x012F, 0x012E); // LATIN SMALL LETTER I WITH OGONEK (LATIN SMALL LETTER I OGONEK), LATIN CAPITAL LETTER I WITH OGONEK (LATIN CAPITAL LETTER I OGONEK) +test(0x0132, 0x0133); // LATIN CAPITAL LIGATURE IJ (LATIN CAPITAL LETTER I J), LATIN SMALL LIGATURE IJ (LATIN SMALL LETTER I J) +test(0x0133, 0x0132); // LATIN SMALL LIGATURE IJ (LATIN SMALL LETTER I J), LATIN CAPITAL LIGATURE IJ (LATIN CAPITAL LETTER I J) +test(0x0134, 0x0135); // LATIN CAPITAL LETTER J WITH CIRCUMFLEX (LATIN CAPITAL LETTER J CIRCUMFLEX), LATIN SMALL LETTER J WITH CIRCUMFLEX (LATIN SMALL LETTER J CIRCUMFLEX) +test(0x0135, 0x0134); // LATIN SMALL LETTER J WITH CIRCUMFLEX (LATIN SMALL LETTER J CIRCUMFLEX), LATIN CAPITAL LETTER J WITH CIRCUMFLEX (LATIN CAPITAL LETTER J CIRCUMFLEX) +test(0x0136, 0x0137); // LATIN CAPITAL LETTER K WITH CEDILLA (LATIN CAPITAL LETTER K CEDILLA), LATIN SMALL LETTER K WITH CEDILLA (LATIN SMALL LETTER K CEDILLA) +test(0x0137, 0x0136); // LATIN SMALL LETTER K WITH CEDILLA (LATIN SMALL LETTER K CEDILLA), LATIN CAPITAL LETTER K WITH CEDILLA (LATIN CAPITAL LETTER K CEDILLA) +test(0x0139, 0x013A); // LATIN CAPITAL LETTER L WITH ACUTE (LATIN CAPITAL LETTER L ACUTE), LATIN SMALL LETTER L WITH ACUTE (LATIN SMALL LETTER L ACUTE) +test(0x013A, 0x0139); // LATIN SMALL LETTER L WITH ACUTE (LATIN SMALL LETTER L ACUTE), LATIN CAPITAL LETTER L WITH ACUTE (LATIN CAPITAL LETTER L ACUTE) +test(0x013B, 0x013C); // LATIN CAPITAL LETTER L WITH CEDILLA (LATIN CAPITAL LETTER L CEDILLA), LATIN SMALL LETTER L WITH CEDILLA (LATIN SMALL LETTER L CEDILLA) +test(0x013C, 0x013B); // LATIN SMALL LETTER L WITH CEDILLA (LATIN SMALL LETTER L CEDILLA), LATIN CAPITAL LETTER L WITH CEDILLA (LATIN CAPITAL LETTER L CEDILLA) +test(0x013D, 0x013E); // LATIN CAPITAL LETTER L WITH CARON (LATIN CAPITAL LETTER L HACEK), LATIN SMALL LETTER L WITH CARON (LATIN SMALL LETTER L HACEK) +test(0x013E, 0x013D); // LATIN SMALL LETTER L WITH CARON (LATIN SMALL LETTER L HACEK), LATIN CAPITAL LETTER L WITH CARON (LATIN CAPITAL LETTER L HACEK) +test(0x013F, 0x0140); // LATIN CAPITAL LETTER L WITH MIDDLE DOT, LATIN SMALL LETTER L WITH MIDDLE DOT +test(0x0140, 0x013F); // LATIN SMALL LETTER L WITH MIDDLE DOT, LATIN CAPITAL LETTER L WITH MIDDLE DOT +test(0x0141, 0x0142); // LATIN CAPITAL LETTER L WITH STROKE (LATIN CAPITAL LETTER L SLASH), LATIN SMALL LETTER L WITH STROKE (LATIN SMALL LETTER L SLASH) +test(0x0142, 0x0141); // LATIN SMALL LETTER L WITH STROKE (LATIN SMALL LETTER L SLASH), LATIN CAPITAL LETTER L WITH STROKE (LATIN CAPITAL LETTER L SLASH) +test(0x0143, 0x0144); // LATIN CAPITAL LETTER N WITH ACUTE (LATIN CAPITAL LETTER N ACUTE), LATIN SMALL LETTER N WITH ACUTE (LATIN SMALL LETTER N ACUTE) +test(0x0144, 0x0143); // LATIN SMALL LETTER N WITH ACUTE (LATIN SMALL LETTER N ACUTE), LATIN CAPITAL LETTER N WITH ACUTE (LATIN CAPITAL LETTER N ACUTE) +test(0x0145, 0x0146); // LATIN CAPITAL LETTER N WITH CEDILLA (LATIN CAPITAL LETTER N CEDILLA), LATIN SMALL LETTER N WITH CEDILLA (LATIN SMALL LETTER N CEDILLA) +test(0x0146, 0x0145); // LATIN SMALL LETTER N WITH CEDILLA (LATIN SMALL LETTER N CEDILLA), LATIN CAPITAL LETTER N WITH CEDILLA (LATIN CAPITAL LETTER N CEDILLA) +test(0x0147, 0x0148); // LATIN CAPITAL LETTER N WITH CARON (LATIN CAPITAL LETTER N HACEK), LATIN SMALL LETTER N WITH CARON (LATIN SMALL LETTER N HACEK) +test(0x0148, 0x0147); // LATIN SMALL LETTER N WITH CARON (LATIN SMALL LETTER N HACEK), LATIN CAPITAL LETTER N WITH CARON (LATIN CAPITAL LETTER N HACEK) +test(0x014A, 0x014B); // LATIN CAPITAL LETTER ENG, LATIN SMALL LETTER ENG +test(0x014B, 0x014A); // LATIN SMALL LETTER ENG, LATIN CAPITAL LETTER ENG +test(0x014C, 0x014D); // LATIN CAPITAL LETTER O WITH MACRON (LATIN CAPITAL LETTER O MACRON), LATIN SMALL LETTER O WITH MACRON (LATIN SMALL LETTER O MACRON) +test(0x014D, 0x014C); // LATIN SMALL LETTER O WITH MACRON (LATIN SMALL LETTER O MACRON), LATIN CAPITAL LETTER O WITH MACRON (LATIN CAPITAL LETTER O MACRON) +test(0x014E, 0x014F); // LATIN CAPITAL LETTER O WITH BREVE (LATIN CAPITAL LETTER O BREVE), LATIN SMALL LETTER O WITH BREVE (LATIN SMALL LETTER O BREVE) +test(0x014F, 0x014E); // LATIN SMALL LETTER O WITH BREVE (LATIN SMALL LETTER O BREVE), LATIN CAPITAL LETTER O WITH BREVE (LATIN CAPITAL LETTER O BREVE) +test(0x0150, 0x0151); // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE (LATIN CAPITAL LETTER O DOUBLE ACUTE), LATIN SMALL LETTER O WITH DOUBLE ACUTE (LATIN SMALL LETTER O DOUBLE ACUTE) +test(0x0151, 0x0150); // LATIN SMALL LETTER O WITH DOUBLE ACUTE (LATIN SMALL LETTER O DOUBLE ACUTE), LATIN CAPITAL LETTER O WITH DOUBLE ACUTE (LATIN CAPITAL LETTER O DOUBLE ACUTE) +test(0x0152, 0x0153); // LATIN CAPITAL LIGATURE OE (LATIN CAPITAL LETTER O E), LATIN SMALL LIGATURE OE (LATIN SMALL LETTER O E) +test(0x0153, 0x0152); // LATIN SMALL LIGATURE OE (LATIN SMALL LETTER O E), LATIN CAPITAL LIGATURE OE (LATIN CAPITAL LETTER O E) +test(0x0154, 0x0155); // LATIN CAPITAL LETTER R WITH ACUTE (LATIN CAPITAL LETTER R ACUTE), LATIN SMALL LETTER R WITH ACUTE (LATIN SMALL LETTER R ACUTE) +test(0x0155, 0x0154); // LATIN SMALL LETTER R WITH ACUTE (LATIN SMALL LETTER R ACUTE), LATIN CAPITAL LETTER R WITH ACUTE (LATIN CAPITAL LETTER R ACUTE) +test(0x0156, 0x0157); // LATIN CAPITAL LETTER R WITH CEDILLA (LATIN CAPITAL LETTER R CEDILLA), LATIN SMALL LETTER R WITH CEDILLA (LATIN SMALL LETTER R CEDILLA) +test(0x0157, 0x0156); // LATIN SMALL LETTER R WITH CEDILLA (LATIN SMALL LETTER R CEDILLA), LATIN CAPITAL LETTER R WITH CEDILLA (LATIN CAPITAL LETTER R CEDILLA) +test(0x0158, 0x0159); // LATIN CAPITAL LETTER R WITH CARON (LATIN CAPITAL LETTER R HACEK), LATIN SMALL LETTER R WITH CARON (LATIN SMALL LETTER R HACEK) +test(0x0159, 0x0158); // LATIN SMALL LETTER R WITH CARON (LATIN SMALL LETTER R HACEK), LATIN CAPITAL LETTER R WITH CARON (LATIN CAPITAL LETTER R HACEK) +test(0x015A, 0x015B); // LATIN CAPITAL LETTER S WITH ACUTE (LATIN CAPITAL LETTER S ACUTE), LATIN SMALL LETTER S WITH ACUTE (LATIN SMALL LETTER S ACUTE) +test(0x015B, 0x015A); // LATIN SMALL LETTER S WITH ACUTE (LATIN SMALL LETTER S ACUTE), LATIN CAPITAL LETTER S WITH ACUTE (LATIN CAPITAL LETTER S ACUTE) +test(0x015C, 0x015D); // LATIN CAPITAL LETTER S WITH CIRCUMFLEX (LATIN CAPITAL LETTER S CIRCUMFLEX), LATIN SMALL LETTER S WITH CIRCUMFLEX (LATIN SMALL LETTER S CIRCUMFLEX) +test(0x015D, 0x015C); // LATIN SMALL LETTER S WITH CIRCUMFLEX (LATIN SMALL LETTER S CIRCUMFLEX), LATIN CAPITAL LETTER S WITH CIRCUMFLEX (LATIN CAPITAL LETTER S CIRCUMFLEX) +test(0x015E, 0x015F); // LATIN CAPITAL LETTER S WITH CEDILLA (LATIN CAPITAL LETTER S CEDILLA), LATIN SMALL LETTER S WITH CEDILLA (LATIN SMALL LETTER S CEDILLA) +test(0x015F, 0x015E); // LATIN SMALL LETTER S WITH CEDILLA (LATIN SMALL LETTER S CEDILLA), LATIN CAPITAL LETTER S WITH CEDILLA (LATIN CAPITAL LETTER S CEDILLA) +test(0x0160, 0x0161); // LATIN CAPITAL LETTER S WITH CARON (LATIN CAPITAL LETTER S HACEK), LATIN SMALL LETTER S WITH CARON (LATIN SMALL LETTER S HACEK) +test(0x0161, 0x0160); // LATIN SMALL LETTER S WITH CARON (LATIN SMALL LETTER S HACEK), LATIN CAPITAL LETTER S WITH CARON (LATIN CAPITAL LETTER S HACEK) +test(0x0162, 0x0163); // LATIN CAPITAL LETTER T WITH CEDILLA (LATIN CAPITAL LETTER T CEDILLA), LATIN SMALL LETTER T WITH CEDILLA (LATIN SMALL LETTER T CEDILLA) +test(0x0163, 0x0162); // LATIN SMALL LETTER T WITH CEDILLA (LATIN SMALL LETTER T CEDILLA), LATIN CAPITAL LETTER T WITH CEDILLA (LATIN CAPITAL LETTER T CEDILLA) +test(0x0164, 0x0165); // LATIN CAPITAL LETTER T WITH CARON (LATIN CAPITAL LETTER T HACEK), LATIN SMALL LETTER T WITH CARON (LATIN SMALL LETTER T HACEK) +test(0x0165, 0x0164); // LATIN SMALL LETTER T WITH CARON (LATIN SMALL LETTER T HACEK), LATIN CAPITAL LETTER T WITH CARON (LATIN CAPITAL LETTER T HACEK) +test(0x0166, 0x0167); // LATIN CAPITAL LETTER T WITH STROKE (LATIN CAPITAL LETTER T BAR), LATIN SMALL LETTER T WITH STROKE (LATIN SMALL LETTER T BAR) +test(0x0167, 0x0166); // LATIN SMALL LETTER T WITH STROKE (LATIN SMALL LETTER T BAR), LATIN CAPITAL LETTER T WITH STROKE (LATIN CAPITAL LETTER T BAR) +test(0x0168, 0x0169); // LATIN CAPITAL LETTER U WITH TILDE (LATIN CAPITAL LETTER U TILDE), LATIN SMALL LETTER U WITH TILDE (LATIN SMALL LETTER U TILDE) +test(0x0169, 0x0168); // LATIN SMALL LETTER U WITH TILDE (LATIN SMALL LETTER U TILDE), LATIN CAPITAL LETTER U WITH TILDE (LATIN CAPITAL LETTER U TILDE) +test(0x016A, 0x016B); // LATIN CAPITAL LETTER U WITH MACRON (LATIN CAPITAL LETTER U MACRON), LATIN SMALL LETTER U WITH MACRON (LATIN SMALL LETTER U MACRON) +test(0x016B, 0x016A); // LATIN SMALL LETTER U WITH MACRON (LATIN SMALL LETTER U MACRON), LATIN CAPITAL LETTER U WITH MACRON (LATIN CAPITAL LETTER U MACRON) +test(0x016C, 0x016D); // LATIN CAPITAL LETTER U WITH BREVE (LATIN CAPITAL LETTER U BREVE), LATIN SMALL LETTER U WITH BREVE (LATIN SMALL LETTER U BREVE) +test(0x016D, 0x016C); // LATIN SMALL LETTER U WITH BREVE (LATIN SMALL LETTER U BREVE), LATIN CAPITAL LETTER U WITH BREVE (LATIN CAPITAL LETTER U BREVE) +test(0x016E, 0x016F); // LATIN CAPITAL LETTER U WITH RING ABOVE (LATIN CAPITAL LETTER U RING), LATIN SMALL LETTER U WITH RING ABOVE (LATIN SMALL LETTER U RING) +test(0x016F, 0x016E); // LATIN SMALL LETTER U WITH RING ABOVE (LATIN SMALL LETTER U RING), LATIN CAPITAL LETTER U WITH RING ABOVE (LATIN CAPITAL LETTER U RING) +test(0x0170, 0x0171); // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE (LATIN CAPITAL LETTER U DOUBLE ACUTE), LATIN SMALL LETTER U WITH DOUBLE ACUTE (LATIN SMALL LETTER U DOUBLE ACUTE) +test(0x0171, 0x0170); // LATIN SMALL LETTER U WITH DOUBLE ACUTE (LATIN SMALL LETTER U DOUBLE ACUTE), LATIN CAPITAL LETTER U WITH DOUBLE ACUTE (LATIN CAPITAL LETTER U DOUBLE ACUTE) +test(0x0172, 0x0173); // LATIN CAPITAL LETTER U WITH OGONEK (LATIN CAPITAL LETTER U OGONEK), LATIN SMALL LETTER U WITH OGONEK (LATIN SMALL LETTER U OGONEK) +test(0x0173, 0x0172); // LATIN SMALL LETTER U WITH OGONEK (LATIN SMALL LETTER U OGONEK), LATIN CAPITAL LETTER U WITH OGONEK (LATIN CAPITAL LETTER U OGONEK) +test(0x0174, 0x0175); // LATIN CAPITAL LETTER W WITH CIRCUMFLEX (LATIN CAPITAL LETTER W CIRCUMFLEX), LATIN SMALL LETTER W WITH CIRCUMFLEX (LATIN SMALL LETTER W CIRCUMFLEX) +test(0x0175, 0x0174); // LATIN SMALL LETTER W WITH CIRCUMFLEX (LATIN SMALL LETTER W CIRCUMFLEX), LATIN CAPITAL LETTER W WITH CIRCUMFLEX (LATIN CAPITAL LETTER W CIRCUMFLEX) +test(0x0176, 0x0177); // LATIN CAPITAL LETTER Y WITH CIRCUMFLEX (LATIN CAPITAL LETTER Y CIRCUMFLEX), LATIN SMALL LETTER Y WITH CIRCUMFLEX (LATIN SMALL LETTER Y CIRCUMFLEX) +test(0x0177, 0x0176); // LATIN SMALL LETTER Y WITH CIRCUMFLEX (LATIN SMALL LETTER Y CIRCUMFLEX), LATIN CAPITAL LETTER Y WITH CIRCUMFLEX (LATIN CAPITAL LETTER Y CIRCUMFLEX) +test(0x0178, 0x00FF); // LATIN CAPITAL LETTER Y WITH DIAERESIS (LATIN CAPITAL LETTER Y DIAERESIS), LATIN SMALL LETTER Y WITH DIAERESIS (LATIN SMALL LETTER Y DIAERESIS) +test(0x0179, 0x017A); // LATIN CAPITAL LETTER Z WITH ACUTE (LATIN CAPITAL LETTER Z ACUTE), LATIN SMALL LETTER Z WITH ACUTE (LATIN SMALL LETTER Z ACUTE) +test(0x017A, 0x0179); // LATIN SMALL LETTER Z WITH ACUTE (LATIN SMALL LETTER Z ACUTE), LATIN CAPITAL LETTER Z WITH ACUTE (LATIN CAPITAL LETTER Z ACUTE) +test(0x017B, 0x017C); // LATIN CAPITAL LETTER Z WITH DOT ABOVE (LATIN CAPITAL LETTER Z DOT), LATIN SMALL LETTER Z WITH DOT ABOVE (LATIN SMALL LETTER Z DOT) +test(0x017C, 0x017B); // LATIN SMALL LETTER Z WITH DOT ABOVE (LATIN SMALL LETTER Z DOT), LATIN CAPITAL LETTER Z WITH DOT ABOVE (LATIN CAPITAL LETTER Z DOT) +test(0x017D, 0x017E); // LATIN CAPITAL LETTER Z WITH CARON (LATIN CAPITAL LETTER Z HACEK), LATIN SMALL LETTER Z WITH CARON (LATIN SMALL LETTER Z HACEK) +test(0x017E, 0x017D); // LATIN SMALL LETTER Z WITH CARON (LATIN SMALL LETTER Z HACEK), LATIN CAPITAL LETTER Z WITH CARON (LATIN CAPITAL LETTER Z HACEK) +test(0x017F, 0x0073, 0x0053); // LATIN SMALL LETTER LONG S, LATIN SMALL LETTER S, LATIN CAPITAL LETTER S +test(0x0180, 0x0243); // LATIN SMALL LETTER B WITH STROKE (LATIN SMALL LETTER B BAR), LATIN CAPITAL LETTER B WITH STROKE +test(0x0181, 0x0253); // LATIN CAPITAL LETTER B WITH HOOK (LATIN CAPITAL LETTER B HOOK), LATIN SMALL LETTER B WITH HOOK (LATIN SMALL LETTER B HOOK) +test(0x0182, 0x0183); // LATIN CAPITAL LETTER B WITH TOPBAR (LATIN CAPITAL LETTER B TOPBAR), LATIN SMALL LETTER B WITH TOPBAR (LATIN SMALL LETTER B TOPBAR) +test(0x0183, 0x0182); // LATIN SMALL LETTER B WITH TOPBAR (LATIN SMALL LETTER B TOPBAR), LATIN CAPITAL LETTER B WITH TOPBAR (LATIN CAPITAL LETTER B TOPBAR) +test(0x0184, 0x0185); // LATIN CAPITAL LETTER TONE SIX, LATIN SMALL LETTER TONE SIX +test(0x0185, 0x0184); // LATIN SMALL LETTER TONE SIX, LATIN CAPITAL LETTER TONE SIX +test(0x0186, 0x0254); // LATIN CAPITAL LETTER OPEN O, LATIN SMALL LETTER OPEN O +test(0x0187, 0x0188); // LATIN CAPITAL LETTER C WITH HOOK (LATIN CAPITAL LETTER C HOOK), LATIN SMALL LETTER C WITH HOOK (LATIN SMALL LETTER C HOOK) +test(0x0188, 0x0187); // LATIN SMALL LETTER C WITH HOOK (LATIN SMALL LETTER C HOOK), LATIN CAPITAL LETTER C WITH HOOK (LATIN CAPITAL LETTER C HOOK) +test(0x0189, 0x0256); // LATIN CAPITAL LETTER AFRICAN D, LATIN SMALL LETTER D WITH TAIL (LATIN SMALL LETTER D RETROFLEX HOOK) +test(0x018A, 0x0257); // LATIN CAPITAL LETTER D WITH HOOK (LATIN CAPITAL LETTER D HOOK), LATIN SMALL LETTER D WITH HOOK (LATIN SMALL LETTER D HOOK) +test(0x018B, 0x018C); // LATIN CAPITAL LETTER D WITH TOPBAR (LATIN CAPITAL LETTER D TOPBAR), LATIN SMALL LETTER D WITH TOPBAR (LATIN SMALL LETTER D TOPBAR) +test(0x018C, 0x018B); // LATIN SMALL LETTER D WITH TOPBAR (LATIN SMALL LETTER D TOPBAR), LATIN CAPITAL LETTER D WITH TOPBAR (LATIN CAPITAL LETTER D TOPBAR) +test(0x018E, 0x01DD); // LATIN CAPITAL LETTER REVERSED E (LATIN CAPITAL LETTER TURNED E), LATIN SMALL LETTER TURNED E +test(0x018F, 0x0259); // LATIN CAPITAL LETTER SCHWA, LATIN SMALL LETTER SCHWA +test(0x0190, 0x025B); // LATIN CAPITAL LETTER OPEN E (LATIN CAPITAL LETTER EPSILON), LATIN SMALL LETTER OPEN E (LATIN SMALL LETTER EPSILON) +test(0x0191, 0x0192); // LATIN CAPITAL LETTER F WITH HOOK (LATIN CAPITAL LETTER F HOOK), LATIN SMALL LETTER F WITH HOOK (LATIN SMALL LETTER SCRIPT F) +test(0x0192, 0x0191); // LATIN SMALL LETTER F WITH HOOK (LATIN SMALL LETTER SCRIPT F), LATIN CAPITAL LETTER F WITH HOOK (LATIN CAPITAL LETTER F HOOK) +test(0x0193, 0x0260); // LATIN CAPITAL LETTER G WITH HOOK (LATIN CAPITAL LETTER G HOOK), LATIN SMALL LETTER G WITH HOOK (LATIN SMALL LETTER G HOOK) +test(0x0194, 0x0263); // LATIN CAPITAL LETTER GAMMA, LATIN SMALL LETTER GAMMA +test(0x0195, 0x01F6); // LATIN SMALL LETTER HV (LATIN SMALL LETTER H V), LATIN CAPITAL LETTER HWAIR +test(0x0196, 0x0269); // LATIN CAPITAL LETTER IOTA, LATIN SMALL LETTER IOTA +test(0x0197, 0x0268); // LATIN CAPITAL LETTER I WITH STROKE (LATIN CAPITAL LETTER BARRED I), LATIN SMALL LETTER I WITH STROKE (LATIN SMALL LETTER BARRED I) +test(0x0198, 0x0199); // LATIN CAPITAL LETTER K WITH HOOK (LATIN CAPITAL LETTER K HOOK), LATIN SMALL LETTER K WITH HOOK (LATIN SMALL LETTER K HOOK) +test(0x0199, 0x0198); // LATIN SMALL LETTER K WITH HOOK (LATIN SMALL LETTER K HOOK), LATIN CAPITAL LETTER K WITH HOOK (LATIN CAPITAL LETTER K HOOK) +test(0x019A, 0x023D); // LATIN SMALL LETTER L WITH BAR (LATIN SMALL LETTER BARRED L), LATIN CAPITAL LETTER L WITH BAR +test(0x019C, 0x026F); // LATIN CAPITAL LETTER TURNED M, LATIN SMALL LETTER TURNED M +test(0x019D, 0x0272); // LATIN CAPITAL LETTER N WITH LEFT HOOK (LATIN CAPITAL LETTER N HOOK), LATIN SMALL LETTER N WITH LEFT HOOK (LATIN SMALL LETTER N HOOK) +test(0x019E, 0x0220); // LATIN SMALL LETTER N WITH LONG RIGHT LEG, LATIN CAPITAL LETTER N WITH LONG RIGHT LEG +test(0x019F, 0x0275); // LATIN CAPITAL LETTER O WITH MIDDLE TILDE (LATIN CAPITAL LETTER BARRED O), LATIN SMALL LETTER BARRED O +test(0x01A0, 0x01A1); // LATIN CAPITAL LETTER O WITH HORN (LATIN CAPITAL LETTER O HORN), LATIN SMALL LETTER O WITH HORN (LATIN SMALL LETTER O HORN) +test(0x01A1, 0x01A0); // LATIN SMALL LETTER O WITH HORN (LATIN SMALL LETTER O HORN), LATIN CAPITAL LETTER O WITH HORN (LATIN CAPITAL LETTER O HORN) +test(0x01A2, 0x01A3); // LATIN CAPITAL LETTER OI (LATIN CAPITAL LETTER O I), LATIN SMALL LETTER OI (LATIN SMALL LETTER O I) +test(0x01A3, 0x01A2); // LATIN SMALL LETTER OI (LATIN SMALL LETTER O I), LATIN CAPITAL LETTER OI (LATIN CAPITAL LETTER O I) +test(0x01A4, 0x01A5); // LATIN CAPITAL LETTER P WITH HOOK (LATIN CAPITAL LETTER P HOOK), LATIN SMALL LETTER P WITH HOOK (LATIN SMALL LETTER P HOOK) +test(0x01A5, 0x01A4); // LATIN SMALL LETTER P WITH HOOK (LATIN SMALL LETTER P HOOK), LATIN CAPITAL LETTER P WITH HOOK (LATIN CAPITAL LETTER P HOOK) +test(0x01A6, 0x0280); // LATIN LETTER YR (LATIN LETTER Y R), LATIN LETTER SMALL CAPITAL R +test(0x01A7, 0x01A8); // LATIN CAPITAL LETTER TONE TWO, LATIN SMALL LETTER TONE TWO +test(0x01A8, 0x01A7); // LATIN SMALL LETTER TONE TWO, LATIN CAPITAL LETTER TONE TWO +test(0x01A9, 0x0283); // LATIN CAPITAL LETTER ESH, LATIN SMALL LETTER ESH +test(0x01AC, 0x01AD); // LATIN CAPITAL LETTER T WITH HOOK (LATIN CAPITAL LETTER T HOOK), LATIN SMALL LETTER T WITH HOOK (LATIN SMALL LETTER T HOOK) +test(0x01AD, 0x01AC); // LATIN SMALL LETTER T WITH HOOK (LATIN SMALL LETTER T HOOK), LATIN CAPITAL LETTER T WITH HOOK (LATIN CAPITAL LETTER T HOOK) +test(0x01AE, 0x0288); // LATIN CAPITAL LETTER T WITH RETROFLEX HOOK (LATIN CAPITAL LETTER T RETROFLEX HOOK), LATIN SMALL LETTER T WITH RETROFLEX HOOK (LATIN SMALL LETTER T RETROFLEX HOOK) +test(0x01AF, 0x01B0); // LATIN CAPITAL LETTER U WITH HORN (LATIN CAPITAL LETTER U HORN), LATIN SMALL LETTER U WITH HORN (LATIN SMALL LETTER U HORN) +test(0x01B0, 0x01AF); // LATIN SMALL LETTER U WITH HORN (LATIN SMALL LETTER U HORN), LATIN CAPITAL LETTER U WITH HORN (LATIN CAPITAL LETTER U HORN) +test(0x01B1, 0x028A); // LATIN CAPITAL LETTER UPSILON, LATIN SMALL LETTER UPSILON +test(0x01B2, 0x028B); // LATIN CAPITAL LETTER V WITH HOOK (LATIN CAPITAL LETTER SCRIPT V), LATIN SMALL LETTER V WITH HOOK (LATIN SMALL LETTER SCRIPT V) +test(0x01B3, 0x01B4); // LATIN CAPITAL LETTER Y WITH HOOK (LATIN CAPITAL LETTER Y HOOK), LATIN SMALL LETTER Y WITH HOOK (LATIN SMALL LETTER Y HOOK) +test(0x01B4, 0x01B3); // LATIN SMALL LETTER Y WITH HOOK (LATIN SMALL LETTER Y HOOK), LATIN CAPITAL LETTER Y WITH HOOK (LATIN CAPITAL LETTER Y HOOK) +test(0x01B5, 0x01B6); // LATIN CAPITAL LETTER Z WITH STROKE (LATIN CAPITAL LETTER Z BAR), LATIN SMALL LETTER Z WITH STROKE (LATIN SMALL LETTER Z BAR) +test(0x01B6, 0x01B5); // LATIN SMALL LETTER Z WITH STROKE (LATIN SMALL LETTER Z BAR), LATIN CAPITAL LETTER Z WITH STROKE (LATIN CAPITAL LETTER Z BAR) +test(0x01B7, 0x0292); // LATIN CAPITAL LETTER EZH (LATIN CAPITAL LETTER YOGH), LATIN SMALL LETTER EZH (LATIN SMALL LETTER YOGH) +test(0x01B8, 0x01B9); // LATIN CAPITAL LETTER EZH REVERSED (LATIN CAPITAL LETTER REVERSED YOGH), LATIN SMALL LETTER EZH REVERSED (LATIN SMALL LETTER REVERSED YOGH) +test(0x01B9, 0x01B8); // LATIN SMALL LETTER EZH REVERSED (LATIN SMALL LETTER REVERSED YOGH), LATIN CAPITAL LETTER EZH REVERSED (LATIN CAPITAL LETTER REVERSED YOGH) +test(0x01BC, 0x01BD); // LATIN CAPITAL LETTER TONE FIVE, LATIN SMALL LETTER TONE FIVE +test(0x01BD, 0x01BC); // LATIN SMALL LETTER TONE FIVE, LATIN CAPITAL LETTER TONE FIVE +test(0x01BF, 0x01F7); // LATIN LETTER WYNN, LATIN CAPITAL LETTER WYNN +test(0x01C4, 0x01C6, 0x01C5); // LATIN CAPITAL LETTER DZ WITH CARON (LATIN CAPITAL LETTER D Z HACEK), LATIN SMALL LETTER DZ WITH CARON (LATIN SMALL LETTER D Z HACEK), LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON (LATIN LETTER CAPITAL D SMALL Z HACEK) +test(0x01C5, 0x01C6, 0x01C4); // LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON (LATIN LETTER CAPITAL D SMALL Z HACEK), LATIN SMALL LETTER DZ WITH CARON (LATIN SMALL LETTER D Z HACEK), LATIN CAPITAL LETTER DZ WITH CARON (LATIN CAPITAL LETTER D Z HACEK) +test(0x01C6, 0x01C4, 0x01C5); // LATIN SMALL LETTER DZ WITH CARON (LATIN SMALL LETTER D Z HACEK), LATIN CAPITAL LETTER DZ WITH CARON (LATIN CAPITAL LETTER D Z HACEK), LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON (LATIN LETTER CAPITAL D SMALL Z HACEK) +test(0x01C7, 0x01C9, 0x01C8); // LATIN CAPITAL LETTER LJ (LATIN CAPITAL LETTER L J), LATIN SMALL LETTER LJ (LATIN SMALL LETTER L J), LATIN CAPITAL LETTER L WITH SMALL LETTER J (LATIN LETTER CAPITAL L SMALL J) +test(0x01C8, 0x01C9, 0x01C7); // LATIN CAPITAL LETTER L WITH SMALL LETTER J (LATIN LETTER CAPITAL L SMALL J), LATIN SMALL LETTER LJ (LATIN SMALL LETTER L J), LATIN CAPITAL LETTER LJ (LATIN CAPITAL LETTER L J) +test(0x01C9, 0x01C7, 0x01C8); // LATIN SMALL LETTER LJ (LATIN SMALL LETTER L J), LATIN CAPITAL LETTER LJ (LATIN CAPITAL LETTER L J), LATIN CAPITAL LETTER L WITH SMALL LETTER J (LATIN LETTER CAPITAL L SMALL J) +test(0x01CA, 0x01CC, 0x01CB); // LATIN CAPITAL LETTER NJ (LATIN CAPITAL LETTER N J), LATIN SMALL LETTER NJ (LATIN SMALL LETTER N J), LATIN CAPITAL LETTER N WITH SMALL LETTER J (LATIN LETTER CAPITAL N SMALL J) +test(0x01CB, 0x01CC, 0x01CA); // LATIN CAPITAL LETTER N WITH SMALL LETTER J (LATIN LETTER CAPITAL N SMALL J), LATIN SMALL LETTER NJ (LATIN SMALL LETTER N J), LATIN CAPITAL LETTER NJ (LATIN CAPITAL LETTER N J) +test(0x01CC, 0x01CA, 0x01CB); // LATIN SMALL LETTER NJ (LATIN SMALL LETTER N J), LATIN CAPITAL LETTER NJ (LATIN CAPITAL LETTER N J), LATIN CAPITAL LETTER N WITH SMALL LETTER J (LATIN LETTER CAPITAL N SMALL J) +test(0x01CD, 0x01CE); // LATIN CAPITAL LETTER A WITH CARON (LATIN CAPITAL LETTER A HACEK), LATIN SMALL LETTER A WITH CARON (LATIN SMALL LETTER A HACEK) +test(0x01CE, 0x01CD); // LATIN SMALL LETTER A WITH CARON (LATIN SMALL LETTER A HACEK), LATIN CAPITAL LETTER A WITH CARON (LATIN CAPITAL LETTER A HACEK) +test(0x01CF, 0x01D0); // LATIN CAPITAL LETTER I WITH CARON (LATIN CAPITAL LETTER I HACEK), LATIN SMALL LETTER I WITH CARON (LATIN SMALL LETTER I HACEK) +test(0x01D0, 0x01CF); // LATIN SMALL LETTER I WITH CARON (LATIN SMALL LETTER I HACEK), LATIN CAPITAL LETTER I WITH CARON (LATIN CAPITAL LETTER I HACEK) +test(0x01D1, 0x01D2); // LATIN CAPITAL LETTER O WITH CARON (LATIN CAPITAL LETTER O HACEK), LATIN SMALL LETTER O WITH CARON (LATIN SMALL LETTER O HACEK) +test(0x01D2, 0x01D1); // LATIN SMALL LETTER O WITH CARON (LATIN SMALL LETTER O HACEK), LATIN CAPITAL LETTER O WITH CARON (LATIN CAPITAL LETTER O HACEK) +test(0x01D3, 0x01D4); // LATIN CAPITAL LETTER U WITH CARON (LATIN CAPITAL LETTER U HACEK), LATIN SMALL LETTER U WITH CARON (LATIN SMALL LETTER U HACEK) +test(0x01D4, 0x01D3); // LATIN SMALL LETTER U WITH CARON (LATIN SMALL LETTER U HACEK), LATIN CAPITAL LETTER U WITH CARON (LATIN CAPITAL LETTER U HACEK) +test(0x01D5, 0x01D6); // LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON (LATIN CAPITAL LETTER U DIAERESIS MACRON), LATIN SMALL LETTER U WITH DIAERESIS AND MACRON (LATIN SMALL LETTER U DIAERESIS MACRON) +test(0x01D6, 0x01D5); // LATIN SMALL LETTER U WITH DIAERESIS AND MACRON (LATIN SMALL LETTER U DIAERESIS MACRON), LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON (LATIN CAPITAL LETTER U DIAERESIS MACRON) +test(0x01D7, 0x01D8); // LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE (LATIN CAPITAL LETTER U DIAERESIS ACUTE), LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE (LATIN SMALL LETTER U DIAERESIS ACUTE) +test(0x01D8, 0x01D7); // LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE (LATIN SMALL LETTER U DIAERESIS ACUTE), LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE (LATIN CAPITAL LETTER U DIAERESIS ACUTE) +test(0x01D9, 0x01DA); // LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON (LATIN CAPITAL LETTER U DIAERESIS HACEK), LATIN SMALL LETTER U WITH DIAERESIS AND CARON (LATIN SMALL LETTER U DIAERESIS HACEK) +test(0x01DA, 0x01D9); // LATIN SMALL LETTER U WITH DIAERESIS AND CARON (LATIN SMALL LETTER U DIAERESIS HACEK), LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON (LATIN CAPITAL LETTER U DIAERESIS HACEK) +test(0x01DB, 0x01DC); // LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE (LATIN CAPITAL LETTER U DIAERESIS GRAVE), LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE (LATIN SMALL LETTER U DIAERESIS GRAVE) +test(0x01DC, 0x01DB); // LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE (LATIN SMALL LETTER U DIAERESIS GRAVE), LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE (LATIN CAPITAL LETTER U DIAERESIS GRAVE) +test(0x01DD, 0x018E); // LATIN SMALL LETTER TURNED E, LATIN CAPITAL LETTER REVERSED E (LATIN CAPITAL LETTER TURNED E) +test(0x01DE, 0x01DF); // LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON (LATIN CAPITAL LETTER A DIAERESIS MACRON), LATIN SMALL LETTER A WITH DIAERESIS AND MACRON (LATIN SMALL LETTER A DIAERESIS MACRON) +test(0x01DF, 0x01DE); // LATIN SMALL LETTER A WITH DIAERESIS AND MACRON (LATIN SMALL LETTER A DIAERESIS MACRON), LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON (LATIN CAPITAL LETTER A DIAERESIS MACRON) +test(0x01E0, 0x01E1); // LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON (LATIN CAPITAL LETTER A DOT MACRON), LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON (LATIN SMALL LETTER A DOT MACRON) +test(0x01E1, 0x01E0); // LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON (LATIN SMALL LETTER A DOT MACRON), LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON (LATIN CAPITAL LETTER A DOT MACRON) +test(0x01E2, 0x01E3); // LATIN CAPITAL LETTER AE WITH MACRON (LATIN CAPITAL LETTER A E MACRON), LATIN SMALL LETTER AE WITH MACRON (LATIN SMALL LETTER A E MACRON) +test(0x01E3, 0x01E2); // LATIN SMALL LETTER AE WITH MACRON (LATIN SMALL LETTER A E MACRON), LATIN CAPITAL LETTER AE WITH MACRON (LATIN CAPITAL LETTER A E MACRON) +test(0x01E4, 0x01E5); // LATIN CAPITAL LETTER G WITH STROKE (LATIN CAPITAL LETTER G BAR), LATIN SMALL LETTER G WITH STROKE (LATIN SMALL LETTER G BAR) +test(0x01E5, 0x01E4); // LATIN SMALL LETTER G WITH STROKE (LATIN SMALL LETTER G BAR), LATIN CAPITAL LETTER G WITH STROKE (LATIN CAPITAL LETTER G BAR) +test(0x01E6, 0x01E7); // LATIN CAPITAL LETTER G WITH CARON (LATIN CAPITAL LETTER G HACEK), LATIN SMALL LETTER G WITH CARON (LATIN SMALL LETTER G HACEK) +test(0x01E7, 0x01E6); // LATIN SMALL LETTER G WITH CARON (LATIN SMALL LETTER G HACEK), LATIN CAPITAL LETTER G WITH CARON (LATIN CAPITAL LETTER G HACEK) +test(0x01E8, 0x01E9); // LATIN CAPITAL LETTER K WITH CARON (LATIN CAPITAL LETTER K HACEK), LATIN SMALL LETTER K WITH CARON (LATIN SMALL LETTER K HACEK) +test(0x01E9, 0x01E8); // LATIN SMALL LETTER K WITH CARON (LATIN SMALL LETTER K HACEK), LATIN CAPITAL LETTER K WITH CARON (LATIN CAPITAL LETTER K HACEK) +test(0x01EA, 0x01EB); // LATIN CAPITAL LETTER O WITH OGONEK (LATIN CAPITAL LETTER O OGONEK), LATIN SMALL LETTER O WITH OGONEK (LATIN SMALL LETTER O OGONEK) +test(0x01EB, 0x01EA); // LATIN SMALL LETTER O WITH OGONEK (LATIN SMALL LETTER O OGONEK), LATIN CAPITAL LETTER O WITH OGONEK (LATIN CAPITAL LETTER O OGONEK) +test(0x01EC, 0x01ED); // LATIN CAPITAL LETTER O WITH OGONEK AND MACRON (LATIN CAPITAL LETTER O OGONEK MACRON), LATIN SMALL LETTER O WITH OGONEK AND MACRON (LATIN SMALL LETTER O OGONEK MACRON) +test(0x01ED, 0x01EC); // LATIN SMALL LETTER O WITH OGONEK AND MACRON (LATIN SMALL LETTER O OGONEK MACRON), LATIN CAPITAL LETTER O WITH OGONEK AND MACRON (LATIN CAPITAL LETTER O OGONEK MACRON) +test(0x01EE, 0x01EF); // LATIN CAPITAL LETTER EZH WITH CARON (LATIN CAPITAL LETTER YOGH HACEK), LATIN SMALL LETTER EZH WITH CARON (LATIN SMALL LETTER YOGH HACEK) +test(0x01EF, 0x01EE); // LATIN SMALL LETTER EZH WITH CARON (LATIN SMALL LETTER YOGH HACEK), LATIN CAPITAL LETTER EZH WITH CARON (LATIN CAPITAL LETTER YOGH HACEK) +test(0x01F1, 0x01F3, 0x01F2); // LATIN CAPITAL LETTER DZ, LATIN SMALL LETTER DZ, LATIN CAPITAL LETTER D WITH SMALL LETTER Z +test(0x01F2, 0x01F3, 0x01F1); // LATIN CAPITAL LETTER D WITH SMALL LETTER Z, LATIN SMALL LETTER DZ, LATIN CAPITAL LETTER DZ +test(0x01F3, 0x01F1, 0x01F2); // LATIN SMALL LETTER DZ, LATIN CAPITAL LETTER DZ, LATIN CAPITAL LETTER D WITH SMALL LETTER Z +test(0x01F4, 0x01F5); // LATIN CAPITAL LETTER G WITH ACUTE, LATIN SMALL LETTER G WITH ACUTE +test(0x01F5, 0x01F4); // LATIN SMALL LETTER G WITH ACUTE, LATIN CAPITAL LETTER G WITH ACUTE +test(0x01F6, 0x0195); // LATIN CAPITAL LETTER HWAIR, LATIN SMALL LETTER HV (LATIN SMALL LETTER H V) +test(0x01F7, 0x01BF); // LATIN CAPITAL LETTER WYNN, LATIN LETTER WYNN +test(0x01F8, 0x01F9); // LATIN CAPITAL LETTER N WITH GRAVE, LATIN SMALL LETTER N WITH GRAVE +test(0x01F9, 0x01F8); // LATIN SMALL LETTER N WITH GRAVE, LATIN CAPITAL LETTER N WITH GRAVE +test(0x01FA, 0x01FB); // LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE, LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE +test(0x01FB, 0x01FA); // LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE, LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE +test(0x01FC, 0x01FD); // LATIN CAPITAL LETTER AE WITH ACUTE, LATIN SMALL LETTER AE WITH ACUTE +test(0x01FD, 0x01FC); // LATIN SMALL LETTER AE WITH ACUTE, LATIN CAPITAL LETTER AE WITH ACUTE +test(0x01FE, 0x01FF); // LATIN CAPITAL LETTER O WITH STROKE AND ACUTE, LATIN SMALL LETTER O WITH STROKE AND ACUTE +test(0x01FF, 0x01FE); // LATIN SMALL LETTER O WITH STROKE AND ACUTE, LATIN CAPITAL LETTER O WITH STROKE AND ACUTE +test(0x0200, 0x0201); // LATIN CAPITAL LETTER A WITH DOUBLE GRAVE, LATIN SMALL LETTER A WITH DOUBLE GRAVE +test(0x0201, 0x0200); // LATIN SMALL LETTER A WITH DOUBLE GRAVE, LATIN CAPITAL LETTER A WITH DOUBLE GRAVE +test(0x0202, 0x0203); // LATIN CAPITAL LETTER A WITH INVERTED BREVE, LATIN SMALL LETTER A WITH INVERTED BREVE +test(0x0203, 0x0202); // LATIN SMALL LETTER A WITH INVERTED BREVE, LATIN CAPITAL LETTER A WITH INVERTED BREVE +test(0x0204, 0x0205); // LATIN CAPITAL LETTER E WITH DOUBLE GRAVE, LATIN SMALL LETTER E WITH DOUBLE GRAVE +test(0x0205, 0x0204); // LATIN SMALL LETTER E WITH DOUBLE GRAVE, LATIN CAPITAL LETTER E WITH DOUBLE GRAVE +test(0x0206, 0x0207); // LATIN CAPITAL LETTER E WITH INVERTED BREVE, LATIN SMALL LETTER E WITH INVERTED BREVE +test(0x0207, 0x0206); // LATIN SMALL LETTER E WITH INVERTED BREVE, LATIN CAPITAL LETTER E WITH INVERTED BREVE +test(0x0208, 0x0209); // LATIN CAPITAL LETTER I WITH DOUBLE GRAVE, LATIN SMALL LETTER I WITH DOUBLE GRAVE +test(0x0209, 0x0208); // LATIN SMALL LETTER I WITH DOUBLE GRAVE, LATIN CAPITAL LETTER I WITH DOUBLE GRAVE +test(0x020A, 0x020B); // LATIN CAPITAL LETTER I WITH INVERTED BREVE, LATIN SMALL LETTER I WITH INVERTED BREVE +test(0x020B, 0x020A); // LATIN SMALL LETTER I WITH INVERTED BREVE, LATIN CAPITAL LETTER I WITH INVERTED BREVE +test(0x020C, 0x020D); // LATIN CAPITAL LETTER O WITH DOUBLE GRAVE, LATIN SMALL LETTER O WITH DOUBLE GRAVE +test(0x020D, 0x020C); // LATIN SMALL LETTER O WITH DOUBLE GRAVE, LATIN CAPITAL LETTER O WITH DOUBLE GRAVE +test(0x020E, 0x020F); // LATIN CAPITAL LETTER O WITH INVERTED BREVE, LATIN SMALL LETTER O WITH INVERTED BREVE +test(0x020F, 0x020E); // LATIN SMALL LETTER O WITH INVERTED BREVE, LATIN CAPITAL LETTER O WITH INVERTED BREVE +test(0x0210, 0x0211); // LATIN CAPITAL LETTER R WITH DOUBLE GRAVE, LATIN SMALL LETTER R WITH DOUBLE GRAVE +test(0x0211, 0x0210); // LATIN SMALL LETTER R WITH DOUBLE GRAVE, LATIN CAPITAL LETTER R WITH DOUBLE GRAVE +test(0x0212, 0x0213); // LATIN CAPITAL LETTER R WITH INVERTED BREVE, LATIN SMALL LETTER R WITH INVERTED BREVE +test(0x0213, 0x0212); // LATIN SMALL LETTER R WITH INVERTED BREVE, LATIN CAPITAL LETTER R WITH INVERTED BREVE +test(0x0214, 0x0215); // LATIN CAPITAL LETTER U WITH DOUBLE GRAVE, LATIN SMALL LETTER U WITH DOUBLE GRAVE +test(0x0215, 0x0214); // LATIN SMALL LETTER U WITH DOUBLE GRAVE, LATIN CAPITAL LETTER U WITH DOUBLE GRAVE +test(0x0216, 0x0217); // LATIN CAPITAL LETTER U WITH INVERTED BREVE, LATIN SMALL LETTER U WITH INVERTED BREVE +test(0x0217, 0x0216); // LATIN SMALL LETTER U WITH INVERTED BREVE, LATIN CAPITAL LETTER U WITH INVERTED BREVE +test(0x0218, 0x0219); // LATIN CAPITAL LETTER S WITH COMMA BELOW, LATIN SMALL LETTER S WITH COMMA BELOW +test(0x0219, 0x0218); // LATIN SMALL LETTER S WITH COMMA BELOW, LATIN CAPITAL LETTER S WITH COMMA BELOW +test(0x021A, 0x021B); // LATIN CAPITAL LETTER T WITH COMMA BELOW, LATIN SMALL LETTER T WITH COMMA BELOW +test(0x021B, 0x021A); // LATIN SMALL LETTER T WITH COMMA BELOW, LATIN CAPITAL LETTER T WITH COMMA BELOW +test(0x021C, 0x021D); // LATIN CAPITAL LETTER YOGH, LATIN SMALL LETTER YOGH +test(0x021D, 0x021C); // LATIN SMALL LETTER YOGH, LATIN CAPITAL LETTER YOGH +test(0x021E, 0x021F); // LATIN CAPITAL LETTER H WITH CARON, LATIN SMALL LETTER H WITH CARON +test(0x021F, 0x021E); // LATIN SMALL LETTER H WITH CARON, LATIN CAPITAL LETTER H WITH CARON +test(0x0220, 0x019E); // LATIN CAPITAL LETTER N WITH LONG RIGHT LEG, LATIN SMALL LETTER N WITH LONG RIGHT LEG +test(0x0222, 0x0223); // LATIN CAPITAL LETTER OU, LATIN SMALL LETTER OU +test(0x0223, 0x0222); // LATIN SMALL LETTER OU, LATIN CAPITAL LETTER OU +test(0x0224, 0x0225); // LATIN CAPITAL LETTER Z WITH HOOK, LATIN SMALL LETTER Z WITH HOOK +test(0x0225, 0x0224); // LATIN SMALL LETTER Z WITH HOOK, LATIN CAPITAL LETTER Z WITH HOOK +test(0x0226, 0x0227); // LATIN CAPITAL LETTER A WITH DOT ABOVE, LATIN SMALL LETTER A WITH DOT ABOVE +test(0x0227, 0x0226); // LATIN SMALL LETTER A WITH DOT ABOVE, LATIN CAPITAL LETTER A WITH DOT ABOVE +test(0x0228, 0x0229); // LATIN CAPITAL LETTER E WITH CEDILLA, LATIN SMALL LETTER E WITH CEDILLA +test(0x0229, 0x0228); // LATIN SMALL LETTER E WITH CEDILLA, LATIN CAPITAL LETTER E WITH CEDILLA +test(0x022A, 0x022B); // LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON, LATIN SMALL LETTER O WITH DIAERESIS AND MACRON +test(0x022B, 0x022A); // LATIN SMALL LETTER O WITH DIAERESIS AND MACRON, LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON +test(0x022C, 0x022D); // LATIN CAPITAL LETTER O WITH TILDE AND MACRON, LATIN SMALL LETTER O WITH TILDE AND MACRON +test(0x022D, 0x022C); // LATIN SMALL LETTER O WITH TILDE AND MACRON, LATIN CAPITAL LETTER O WITH TILDE AND MACRON +test(0x022E, 0x022F); // LATIN CAPITAL LETTER O WITH DOT ABOVE, LATIN SMALL LETTER O WITH DOT ABOVE +test(0x022F, 0x022E); // LATIN SMALL LETTER O WITH DOT ABOVE, LATIN CAPITAL LETTER O WITH DOT ABOVE +test(0x0230, 0x0231); // LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON, LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON +test(0x0231, 0x0230); // LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON, LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON +test(0x0232, 0x0233); // LATIN CAPITAL LETTER Y WITH MACRON, LATIN SMALL LETTER Y WITH MACRON +test(0x0233, 0x0232); // LATIN SMALL LETTER Y WITH MACRON, LATIN CAPITAL LETTER Y WITH MACRON +test(0x023A, 0x2C65); // LATIN CAPITAL LETTER A WITH STROKE, LATIN SMALL LETTER A WITH STROKE +test(0x023B, 0x023C); // LATIN CAPITAL LETTER C WITH STROKE, LATIN SMALL LETTER C WITH STROKE +test(0x023C, 0x023B); // LATIN SMALL LETTER C WITH STROKE, LATIN CAPITAL LETTER C WITH STROKE +test(0x023D, 0x019A); // LATIN CAPITAL LETTER L WITH BAR, LATIN SMALL LETTER L WITH BAR (LATIN SMALL LETTER BARRED L) +test(0x023E, 0x2C66); // LATIN CAPITAL LETTER T WITH DIAGONAL STROKE, LATIN SMALL LETTER T WITH DIAGONAL STROKE +test(0x023F, 0x2C7E); // LATIN SMALL LETTER S WITH SWASH TAIL, LATIN CAPITAL LETTER S WITH SWASH TAIL +test(0x0240, 0x2C7F); // LATIN SMALL LETTER Z WITH SWASH TAIL, LATIN CAPITAL LETTER Z WITH SWASH TAIL +test(0x0241, 0x0242); // LATIN CAPITAL LETTER GLOTTAL STOP, LATIN SMALL LETTER GLOTTAL STOP +test(0x0242, 0x0241); // LATIN SMALL LETTER GLOTTAL STOP, LATIN CAPITAL LETTER GLOTTAL STOP +test(0x0243, 0x0180); // LATIN CAPITAL LETTER B WITH STROKE, LATIN SMALL LETTER B WITH STROKE (LATIN SMALL LETTER B BAR) +test(0x0244, 0x0289); // LATIN CAPITAL LETTER U BAR, LATIN SMALL LETTER U BAR +test(0x0245, 0x028C); // LATIN CAPITAL LETTER TURNED V, LATIN SMALL LETTER TURNED V +test(0x0246, 0x0247); // LATIN CAPITAL LETTER E WITH STROKE, LATIN SMALL LETTER E WITH STROKE +test(0x0247, 0x0246); // LATIN SMALL LETTER E WITH STROKE, LATIN CAPITAL LETTER E WITH STROKE +test(0x0248, 0x0249); // LATIN CAPITAL LETTER J WITH STROKE, LATIN SMALL LETTER J WITH STROKE +test(0x0249, 0x0248); // LATIN SMALL LETTER J WITH STROKE, LATIN CAPITAL LETTER J WITH STROKE +test(0x024A, 0x024B); // LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL, LATIN SMALL LETTER Q WITH HOOK TAIL +test(0x024B, 0x024A); // LATIN SMALL LETTER Q WITH HOOK TAIL, LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL +test(0x024C, 0x024D); // LATIN CAPITAL LETTER R WITH STROKE, LATIN SMALL LETTER R WITH STROKE +test(0x024D, 0x024C); // LATIN SMALL LETTER R WITH STROKE, LATIN CAPITAL LETTER R WITH STROKE +test(0x024E, 0x024F); // LATIN CAPITAL LETTER Y WITH STROKE, LATIN SMALL LETTER Y WITH STROKE +test(0x024F, 0x024E); // LATIN SMALL LETTER Y WITH STROKE, LATIN CAPITAL LETTER Y WITH STROKE +test(0x0250, 0x2C6F); // LATIN SMALL LETTER TURNED A, LATIN CAPITAL LETTER TURNED A +test(0x0251, 0x2C6D); // LATIN SMALL LETTER ALPHA (LATIN SMALL LETTER SCRIPT A), LATIN CAPITAL LETTER ALPHA +test(0x0252, 0x2C70); // LATIN SMALL LETTER TURNED ALPHA (LATIN SMALL LETTER TURNED SCRIPT A), LATIN CAPITAL LETTER TURNED ALPHA +test(0x0253, 0x0181); // LATIN SMALL LETTER B WITH HOOK (LATIN SMALL LETTER B HOOK), LATIN CAPITAL LETTER B WITH HOOK (LATIN CAPITAL LETTER B HOOK) +test(0x0254, 0x0186); // LATIN SMALL LETTER OPEN O, LATIN CAPITAL LETTER OPEN O +test(0x0256, 0x0189); // LATIN SMALL LETTER D WITH TAIL (LATIN SMALL LETTER D RETROFLEX HOOK), LATIN CAPITAL LETTER AFRICAN D +test(0x0257, 0x018A); // LATIN SMALL LETTER D WITH HOOK (LATIN SMALL LETTER D HOOK), LATIN CAPITAL LETTER D WITH HOOK (LATIN CAPITAL LETTER D HOOK) +test(0x0259, 0x018F); // LATIN SMALL LETTER SCHWA, LATIN CAPITAL LETTER SCHWA +test(0x025B, 0x0190); // LATIN SMALL LETTER OPEN E (LATIN SMALL LETTER EPSILON), LATIN CAPITAL LETTER OPEN E (LATIN CAPITAL LETTER EPSILON) +test(0x025C, 0xA7AB); // LATIN SMALL LETTER REVERSED OPEN E (LATIN SMALL LETTER REVERSED EPSILON), LATIN CAPITAL LETTER REVERSED OPEN E +test(0x0260, 0x0193); // LATIN SMALL LETTER G WITH HOOK (LATIN SMALL LETTER G HOOK), LATIN CAPITAL LETTER G WITH HOOK (LATIN CAPITAL LETTER G HOOK) +test(0x0261, 0xA7AC); // LATIN SMALL LETTER SCRIPT G, LATIN CAPITAL LETTER SCRIPT G +test(0x0263, 0x0194); // LATIN SMALL LETTER GAMMA, LATIN CAPITAL LETTER GAMMA +test(0x0265, 0xA78D); // LATIN SMALL LETTER TURNED H, LATIN CAPITAL LETTER TURNED H +test(0x0266, 0xA7AA); // LATIN SMALL LETTER H WITH HOOK (LATIN SMALL LETTER H HOOK), LATIN CAPITAL LETTER H WITH HOOK +test(0x0268, 0x0197); // LATIN SMALL LETTER I WITH STROKE (LATIN SMALL LETTER BARRED I), LATIN CAPITAL LETTER I WITH STROKE (LATIN CAPITAL LETTER BARRED I) +test(0x0269, 0x0196); // LATIN SMALL LETTER IOTA, LATIN CAPITAL LETTER IOTA +test(0x026A, 0xA7AE); // LATIN LETTER SMALL CAPITAL I, LATIN CAPITAL LETTER SMALL CAPITAL I +test(0x026B, 0x2C62); // LATIN SMALL LETTER L WITH MIDDLE TILDE, LATIN CAPITAL LETTER L WITH MIDDLE TILDE +test(0x026C, 0xA7AD); // LATIN SMALL LETTER L WITH BELT (LATIN SMALL LETTER L BELT), LATIN CAPITAL LETTER L WITH BELT +test(0x026F, 0x019C); // LATIN SMALL LETTER TURNED M, LATIN CAPITAL LETTER TURNED M +test(0x0271, 0x2C6E); // LATIN SMALL LETTER M WITH HOOK (LATIN SMALL LETTER M HOOK), LATIN CAPITAL LETTER M WITH HOOK +test(0x0272, 0x019D); // LATIN SMALL LETTER N WITH LEFT HOOK (LATIN SMALL LETTER N HOOK), LATIN CAPITAL LETTER N WITH LEFT HOOK (LATIN CAPITAL LETTER N HOOK) +test(0x0275, 0x019F); // LATIN SMALL LETTER BARRED O, LATIN CAPITAL LETTER O WITH MIDDLE TILDE (LATIN CAPITAL LETTER BARRED O) +test(0x027D, 0x2C64); // LATIN SMALL LETTER R WITH TAIL (LATIN SMALL LETTER R HOOK), LATIN CAPITAL LETTER R WITH TAIL +test(0x0280, 0x01A6); // LATIN LETTER SMALL CAPITAL R, LATIN LETTER YR (LATIN LETTER Y R) +test(0x0282, 0xA7C5); // LATIN SMALL LETTER S WITH HOOK (LATIN SMALL LETTER S HOOK), LATIN CAPITAL LETTER S WITH HOOK +test(0x0283, 0x01A9); // LATIN SMALL LETTER ESH, LATIN CAPITAL LETTER ESH +test(0x0287, 0xA7B1); // LATIN SMALL LETTER TURNED T, LATIN CAPITAL LETTER TURNED T +test(0x0288, 0x01AE); // LATIN SMALL LETTER T WITH RETROFLEX HOOK (LATIN SMALL LETTER T RETROFLEX HOOK), LATIN CAPITAL LETTER T WITH RETROFLEX HOOK (LATIN CAPITAL LETTER T RETROFLEX HOOK) +test(0x0289, 0x0244); // LATIN SMALL LETTER U BAR, LATIN CAPITAL LETTER U BAR +test(0x028A, 0x01B1); // LATIN SMALL LETTER UPSILON, LATIN CAPITAL LETTER UPSILON +test(0x028B, 0x01B2); // LATIN SMALL LETTER V WITH HOOK (LATIN SMALL LETTER SCRIPT V), LATIN CAPITAL LETTER V WITH HOOK (LATIN CAPITAL LETTER SCRIPT V) +test(0x028C, 0x0245); // LATIN SMALL LETTER TURNED V, LATIN CAPITAL LETTER TURNED V +test(0x0292, 0x01B7); // LATIN SMALL LETTER EZH (LATIN SMALL LETTER YOGH), LATIN CAPITAL LETTER EZH (LATIN CAPITAL LETTER YOGH) +test(0x029D, 0xA7B2); // LATIN SMALL LETTER J WITH CROSSED-TAIL (LATIN SMALL LETTER CROSSED-TAIL J), LATIN CAPITAL LETTER J WITH CROSSED-TAIL +test(0x029E, 0xA7B0); // LATIN SMALL LETTER TURNED K, LATIN CAPITAL LETTER TURNED K +test(0x0345, 0x03B9, 0x0399, 0x1FBE); // COMBINING GREEK YPOGEGRAMMENI (GREEK NON-SPACING IOTA BELOW), GREEK SMALL LETTER IOTA, GREEK CAPITAL LETTER IOTA, GREEK PROSGEGRAMMENI +test(0x0370, 0x0371); // GREEK CAPITAL LETTER HETA, GREEK SMALL LETTER HETA +test(0x0371, 0x0370); // GREEK SMALL LETTER HETA, GREEK CAPITAL LETTER HETA +test(0x0372, 0x0373); // GREEK CAPITAL LETTER ARCHAIC SAMPI, GREEK SMALL LETTER ARCHAIC SAMPI +test(0x0373, 0x0372); // GREEK SMALL LETTER ARCHAIC SAMPI, GREEK CAPITAL LETTER ARCHAIC SAMPI +test(0x0376, 0x0377); // GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA, GREEK SMALL LETTER PAMPHYLIAN DIGAMMA +test(0x0377, 0x0376); // GREEK SMALL LETTER PAMPHYLIAN DIGAMMA, GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA +test(0x037B, 0x03FD); // GREEK SMALL REVERSED LUNATE SIGMA SYMBOL, GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL +test(0x037C, 0x03FE); // GREEK SMALL DOTTED LUNATE SIGMA SYMBOL, GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL +test(0x037D, 0x03FF); // GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL, GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL +test(0x037F, 0x03F3); // GREEK CAPITAL LETTER YOT, GREEK LETTER YOT +test(0x0386, 0x03AC); // GREEK CAPITAL LETTER ALPHA WITH TONOS (GREEK CAPITAL LETTER ALPHA TONOS), GREEK SMALL LETTER ALPHA WITH TONOS (GREEK SMALL LETTER ALPHA TONOS) +test(0x0388, 0x03AD); // GREEK CAPITAL LETTER EPSILON WITH TONOS (GREEK CAPITAL LETTER EPSILON TONOS), GREEK SMALL LETTER EPSILON WITH TONOS (GREEK SMALL LETTER EPSILON TONOS) +test(0x0389, 0x03AE); // GREEK CAPITAL LETTER ETA WITH TONOS (GREEK CAPITAL LETTER ETA TONOS), GREEK SMALL LETTER ETA WITH TONOS (GREEK SMALL LETTER ETA TONOS) +test(0x038A, 0x03AF); // GREEK CAPITAL LETTER IOTA WITH TONOS (GREEK CAPITAL LETTER IOTA TONOS), GREEK SMALL LETTER IOTA WITH TONOS (GREEK SMALL LETTER IOTA TONOS) +test(0x038C, 0x03CC); // GREEK CAPITAL LETTER OMICRON WITH TONOS (GREEK CAPITAL LETTER OMICRON TONOS), GREEK SMALL LETTER OMICRON WITH TONOS (GREEK SMALL LETTER OMICRON TONOS) +test(0x038E, 0x03CD); // GREEK CAPITAL LETTER UPSILON WITH TONOS (GREEK CAPITAL LETTER UPSILON TONOS), GREEK SMALL LETTER UPSILON WITH TONOS (GREEK SMALL LETTER UPSILON TONOS) +test(0x038F, 0x03CE); // GREEK CAPITAL LETTER OMEGA WITH TONOS (GREEK CAPITAL LETTER OMEGA TONOS), GREEK SMALL LETTER OMEGA WITH TONOS (GREEK SMALL LETTER OMEGA TONOS) +test(0x0391, 0x03B1); // GREEK CAPITAL LETTER ALPHA, GREEK SMALL LETTER ALPHA +test(0x0392, 0x03B2, 0x03D0); // GREEK CAPITAL LETTER BETA, GREEK SMALL LETTER BETA, GREEK BETA SYMBOL (GREEK SMALL LETTER CURLED BETA) +test(0x0393, 0x03B3); // GREEK CAPITAL LETTER GAMMA, GREEK SMALL LETTER GAMMA +test(0x0394, 0x03B4); // GREEK CAPITAL LETTER DELTA, GREEK SMALL LETTER DELTA +test(0x0395, 0x03B5, 0x03F5); // GREEK CAPITAL LETTER EPSILON, GREEK SMALL LETTER EPSILON, GREEK LUNATE EPSILON SYMBOL +test(0x0396, 0x03B6); // GREEK CAPITAL LETTER ZETA, GREEK SMALL LETTER ZETA +test(0x0397, 0x03B7); // GREEK CAPITAL LETTER ETA, GREEK SMALL LETTER ETA +test(0x0398, 0x03B8, 0x03D1, 0x03F4); // GREEK CAPITAL LETTER THETA, GREEK SMALL LETTER THETA, GREEK THETA SYMBOL (GREEK SMALL LETTER SCRIPT THETA), GREEK CAPITAL THETA SYMBOL +test(0x0399, 0x03B9, 0x0345, 0x1FBE); // GREEK CAPITAL LETTER IOTA, GREEK SMALL LETTER IOTA, COMBINING GREEK YPOGEGRAMMENI (GREEK NON-SPACING IOTA BELOW), GREEK PROSGEGRAMMENI +test(0x039A, 0x03BA, 0x03F0); // GREEK CAPITAL LETTER KAPPA, GREEK SMALL LETTER KAPPA, GREEK KAPPA SYMBOL (GREEK SMALL LETTER SCRIPT KAPPA) +test(0x039B, 0x03BB); // GREEK CAPITAL LETTER LAMDA (GREEK CAPITAL LETTER LAMBDA), GREEK SMALL LETTER LAMDA (GREEK SMALL LETTER LAMBDA) +test(0x039C, 0x03BC, 0x00B5); // GREEK CAPITAL LETTER MU, GREEK SMALL LETTER MU, MICRO SIGN +test(0x039D, 0x03BD); // GREEK CAPITAL LETTER NU, GREEK SMALL LETTER NU +test(0x039E, 0x03BE); // GREEK CAPITAL LETTER XI, GREEK SMALL LETTER XI +test(0x039F, 0x03BF); // GREEK CAPITAL LETTER OMICRON, GREEK SMALL LETTER OMICRON +test(0x03A0, 0x03C0, 0x03D6); // GREEK CAPITAL LETTER PI, GREEK SMALL LETTER PI, GREEK PI SYMBOL (GREEK SMALL LETTER OMEGA PI) +test(0x03A1, 0x03C1, 0x03F1); // GREEK CAPITAL LETTER RHO, GREEK SMALL LETTER RHO, GREEK RHO SYMBOL (GREEK SMALL LETTER TAILED RHO) +test(0x03A3, 0x03C3, 0x03C2); // GREEK CAPITAL LETTER SIGMA, GREEK SMALL LETTER SIGMA, GREEK SMALL LETTER FINAL SIGMA +test(0x03A4, 0x03C4); // GREEK CAPITAL LETTER TAU, GREEK SMALL LETTER TAU +test(0x03A5, 0x03C5); // GREEK CAPITAL LETTER UPSILON, GREEK SMALL LETTER UPSILON +test(0x03A6, 0x03C6, 0x03D5); // GREEK CAPITAL LETTER PHI, GREEK SMALL LETTER PHI, GREEK PHI SYMBOL (GREEK SMALL LETTER SCRIPT PHI) +test(0x03A7, 0x03C7); // GREEK CAPITAL LETTER CHI, GREEK SMALL LETTER CHI +test(0x03A8, 0x03C8); // GREEK CAPITAL LETTER PSI, GREEK SMALL LETTER PSI +test(0x03A9, 0x03C9, 0x2126); // GREEK CAPITAL LETTER OMEGA, GREEK SMALL LETTER OMEGA, OHM SIGN (OHM) +test(0x03AA, 0x03CA); // GREEK CAPITAL LETTER IOTA WITH DIALYTIKA (GREEK CAPITAL LETTER IOTA DIAERESIS), GREEK SMALL LETTER IOTA WITH DIALYTIKA (GREEK SMALL LETTER IOTA DIAERESIS) +test(0x03AB, 0x03CB); // GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA (GREEK CAPITAL LETTER UPSILON DIAERESIS), GREEK SMALL LETTER UPSILON WITH DIALYTIKA (GREEK SMALL LETTER UPSILON DIAERESIS) +test(0x03AC, 0x0386); // GREEK SMALL LETTER ALPHA WITH TONOS (GREEK SMALL LETTER ALPHA TONOS), GREEK CAPITAL LETTER ALPHA WITH TONOS (GREEK CAPITAL LETTER ALPHA TONOS) +test(0x03AD, 0x0388); // GREEK SMALL LETTER EPSILON WITH TONOS (GREEK SMALL LETTER EPSILON TONOS), GREEK CAPITAL LETTER EPSILON WITH TONOS (GREEK CAPITAL LETTER EPSILON TONOS) +test(0x03AE, 0x0389); // GREEK SMALL LETTER ETA WITH TONOS (GREEK SMALL LETTER ETA TONOS), GREEK CAPITAL LETTER ETA WITH TONOS (GREEK CAPITAL LETTER ETA TONOS) +test(0x03AF, 0x038A); // GREEK SMALL LETTER IOTA WITH TONOS (GREEK SMALL LETTER IOTA TONOS), GREEK CAPITAL LETTER IOTA WITH TONOS (GREEK CAPITAL LETTER IOTA TONOS) +test(0x03B1, 0x0391); // GREEK SMALL LETTER ALPHA, GREEK CAPITAL LETTER ALPHA +test(0x03B2, 0x0392, 0x03D0); // GREEK SMALL LETTER BETA, GREEK CAPITAL LETTER BETA, GREEK BETA SYMBOL (GREEK SMALL LETTER CURLED BETA) +test(0x03B3, 0x0393); // GREEK SMALL LETTER GAMMA, GREEK CAPITAL LETTER GAMMA +test(0x03B4, 0x0394); // GREEK SMALL LETTER DELTA, GREEK CAPITAL LETTER DELTA +test(0x03B5, 0x0395, 0x03F5); // GREEK SMALL LETTER EPSILON, GREEK CAPITAL LETTER EPSILON, GREEK LUNATE EPSILON SYMBOL +test(0x03B6, 0x0396); // GREEK SMALL LETTER ZETA, GREEK CAPITAL LETTER ZETA +test(0x03B7, 0x0397); // GREEK SMALL LETTER ETA, GREEK CAPITAL LETTER ETA +test(0x03B8, 0x0398, 0x03D1, 0x03F4); // GREEK SMALL LETTER THETA, GREEK CAPITAL LETTER THETA, GREEK THETA SYMBOL (GREEK SMALL LETTER SCRIPT THETA), GREEK CAPITAL THETA SYMBOL +test(0x03B9, 0x0345, 0x0399, 0x1FBE); // GREEK SMALL LETTER IOTA, COMBINING GREEK YPOGEGRAMMENI (GREEK NON-SPACING IOTA BELOW), GREEK CAPITAL LETTER IOTA, GREEK PROSGEGRAMMENI +test(0x03BA, 0x039A, 0x03F0); // GREEK SMALL LETTER KAPPA, GREEK CAPITAL LETTER KAPPA, GREEK KAPPA SYMBOL (GREEK SMALL LETTER SCRIPT KAPPA) +test(0x03BB, 0x039B); // GREEK SMALL LETTER LAMDA (GREEK SMALL LETTER LAMBDA), GREEK CAPITAL LETTER LAMDA (GREEK CAPITAL LETTER LAMBDA) +test(0x03BC, 0x00B5, 0x039C); // GREEK SMALL LETTER MU, MICRO SIGN, GREEK CAPITAL LETTER MU +test(0x03BD, 0x039D); // GREEK SMALL LETTER NU, GREEK CAPITAL LETTER NU +test(0x03BE, 0x039E); // GREEK SMALL LETTER XI, GREEK CAPITAL LETTER XI +test(0x03BF, 0x039F); // GREEK SMALL LETTER OMICRON, GREEK CAPITAL LETTER OMICRON +test(0x03C0, 0x03A0, 0x03D6); // GREEK SMALL LETTER PI, GREEK CAPITAL LETTER PI, GREEK PI SYMBOL (GREEK SMALL LETTER OMEGA PI) +test(0x03C1, 0x03A1, 0x03F1); // GREEK SMALL LETTER RHO, GREEK CAPITAL LETTER RHO, GREEK RHO SYMBOL (GREEK SMALL LETTER TAILED RHO) +test(0x03C2, 0x03C3, 0x03A3); // GREEK SMALL LETTER FINAL SIGMA, GREEK SMALL LETTER SIGMA, GREEK CAPITAL LETTER SIGMA +test(0x03C3, 0x03A3, 0x03C2); // GREEK SMALL LETTER SIGMA, GREEK CAPITAL LETTER SIGMA, GREEK SMALL LETTER FINAL SIGMA +test(0x03C4, 0x03A4); // GREEK SMALL LETTER TAU, GREEK CAPITAL LETTER TAU +test(0x03C5, 0x03A5); // GREEK SMALL LETTER UPSILON, GREEK CAPITAL LETTER UPSILON +test(0x03C6, 0x03A6, 0x03D5); // GREEK SMALL LETTER PHI, GREEK CAPITAL LETTER PHI, GREEK PHI SYMBOL (GREEK SMALL LETTER SCRIPT PHI) +test(0x03C7, 0x03A7); // GREEK SMALL LETTER CHI, GREEK CAPITAL LETTER CHI +test(0x03C8, 0x03A8); // GREEK SMALL LETTER PSI, GREEK CAPITAL LETTER PSI +test(0x03C9, 0x03A9, 0x2126); // GREEK SMALL LETTER OMEGA, GREEK CAPITAL LETTER OMEGA, OHM SIGN (OHM) +test(0x03CA, 0x03AA); // GREEK SMALL LETTER IOTA WITH DIALYTIKA (GREEK SMALL LETTER IOTA DIAERESIS), GREEK CAPITAL LETTER IOTA WITH DIALYTIKA (GREEK CAPITAL LETTER IOTA DIAERESIS) +test(0x03CB, 0x03AB); // GREEK SMALL LETTER UPSILON WITH DIALYTIKA (GREEK SMALL LETTER UPSILON DIAERESIS), GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA (GREEK CAPITAL LETTER UPSILON DIAERESIS) +test(0x03CC, 0x038C); // GREEK SMALL LETTER OMICRON WITH TONOS (GREEK SMALL LETTER OMICRON TONOS), GREEK CAPITAL LETTER OMICRON WITH TONOS (GREEK CAPITAL LETTER OMICRON TONOS) +test(0x03CD, 0x038E); // GREEK SMALL LETTER UPSILON WITH TONOS (GREEK SMALL LETTER UPSILON TONOS), GREEK CAPITAL LETTER UPSILON WITH TONOS (GREEK CAPITAL LETTER UPSILON TONOS) +test(0x03CE, 0x038F); // GREEK SMALL LETTER OMEGA WITH TONOS (GREEK SMALL LETTER OMEGA TONOS), GREEK CAPITAL LETTER OMEGA WITH TONOS (GREEK CAPITAL LETTER OMEGA TONOS) +test(0x03CF, 0x03D7); // GREEK CAPITAL KAI SYMBOL, GREEK KAI SYMBOL +test(0x03D0, 0x03B2, 0x0392); // GREEK BETA SYMBOL (GREEK SMALL LETTER CURLED BETA), GREEK SMALL LETTER BETA, GREEK CAPITAL LETTER BETA +test(0x03D1, 0x03B8, 0x0398, 0x03F4); // GREEK THETA SYMBOL (GREEK SMALL LETTER SCRIPT THETA), GREEK SMALL LETTER THETA, GREEK CAPITAL LETTER THETA, GREEK CAPITAL THETA SYMBOL +test(0x03D5, 0x03C6, 0x03A6); // GREEK PHI SYMBOL (GREEK SMALL LETTER SCRIPT PHI), GREEK SMALL LETTER PHI, GREEK CAPITAL LETTER PHI +test(0x03D6, 0x03C0, 0x03A0); // GREEK PI SYMBOL (GREEK SMALL LETTER OMEGA PI), GREEK SMALL LETTER PI, GREEK CAPITAL LETTER PI +test(0x03D7, 0x03CF); // GREEK KAI SYMBOL, GREEK CAPITAL KAI SYMBOL +test(0x03D8, 0x03D9); // GREEK LETTER ARCHAIC KOPPA, GREEK SMALL LETTER ARCHAIC KOPPA +test(0x03D9, 0x03D8); // GREEK SMALL LETTER ARCHAIC KOPPA, GREEK LETTER ARCHAIC KOPPA +test(0x03DA, 0x03DB); // GREEK LETTER STIGMA (GREEK CAPITAL LETTER STIGMA), GREEK SMALL LETTER STIGMA +test(0x03DB, 0x03DA); // GREEK SMALL LETTER STIGMA, GREEK LETTER STIGMA (GREEK CAPITAL LETTER STIGMA) +test(0x03DC, 0x03DD); // GREEK LETTER DIGAMMA (GREEK CAPITAL LETTER DIGAMMA), GREEK SMALL LETTER DIGAMMA +test(0x03DD, 0x03DC); // GREEK SMALL LETTER DIGAMMA, GREEK LETTER DIGAMMA (GREEK CAPITAL LETTER DIGAMMA) +test(0x03DE, 0x03DF); // GREEK LETTER KOPPA (GREEK CAPITAL LETTER KOPPA), GREEK SMALL LETTER KOPPA +test(0x03DF, 0x03DE); // GREEK SMALL LETTER KOPPA, GREEK LETTER KOPPA (GREEK CAPITAL LETTER KOPPA) +test(0x03E0, 0x03E1); // GREEK LETTER SAMPI (GREEK CAPITAL LETTER SAMPI), GREEK SMALL LETTER SAMPI +test(0x03E1, 0x03E0); // GREEK SMALL LETTER SAMPI, GREEK LETTER SAMPI (GREEK CAPITAL LETTER SAMPI) +test(0x03E2, 0x03E3); // COPTIC CAPITAL LETTER SHEI (GREEK CAPITAL LETTER SHEI), COPTIC SMALL LETTER SHEI (GREEK SMALL LETTER SHEI) +test(0x03E3, 0x03E2); // COPTIC SMALL LETTER SHEI (GREEK SMALL LETTER SHEI), COPTIC CAPITAL LETTER SHEI (GREEK CAPITAL LETTER SHEI) +test(0x03E4, 0x03E5); // COPTIC CAPITAL LETTER FEI (GREEK CAPITAL LETTER FEI), COPTIC SMALL LETTER FEI (GREEK SMALL LETTER FEI) +test(0x03E5, 0x03E4); // COPTIC SMALL LETTER FEI (GREEK SMALL LETTER FEI), COPTIC CAPITAL LETTER FEI (GREEK CAPITAL LETTER FEI) +test(0x03E6, 0x03E7); // COPTIC CAPITAL LETTER KHEI (GREEK CAPITAL LETTER KHEI), COPTIC SMALL LETTER KHEI (GREEK SMALL LETTER KHEI) +test(0x03E7, 0x03E6); // COPTIC SMALL LETTER KHEI (GREEK SMALL LETTER KHEI), COPTIC CAPITAL LETTER KHEI (GREEK CAPITAL LETTER KHEI) +test(0x03E8, 0x03E9); // COPTIC CAPITAL LETTER HORI (GREEK CAPITAL LETTER HORI), COPTIC SMALL LETTER HORI (GREEK SMALL LETTER HORI) +test(0x03E9, 0x03E8); // COPTIC SMALL LETTER HORI (GREEK SMALL LETTER HORI), COPTIC CAPITAL LETTER HORI (GREEK CAPITAL LETTER HORI) +test(0x03EA, 0x03EB); // COPTIC CAPITAL LETTER GANGIA (GREEK CAPITAL LETTER GANGIA), COPTIC SMALL LETTER GANGIA (GREEK SMALL LETTER GANGIA) +test(0x03EB, 0x03EA); // COPTIC SMALL LETTER GANGIA (GREEK SMALL LETTER GANGIA), COPTIC CAPITAL LETTER GANGIA (GREEK CAPITAL LETTER GANGIA) +test(0x03EC, 0x03ED); // COPTIC CAPITAL LETTER SHIMA (GREEK CAPITAL LETTER SHIMA), COPTIC SMALL LETTER SHIMA (GREEK SMALL LETTER SHIMA) +test(0x03ED, 0x03EC); // COPTIC SMALL LETTER SHIMA (GREEK SMALL LETTER SHIMA), COPTIC CAPITAL LETTER SHIMA (GREEK CAPITAL LETTER SHIMA) +test(0x03EE, 0x03EF); // COPTIC CAPITAL LETTER DEI (GREEK CAPITAL LETTER DEI), COPTIC SMALL LETTER DEI (GREEK SMALL LETTER DEI) +test(0x03EF, 0x03EE); // COPTIC SMALL LETTER DEI (GREEK SMALL LETTER DEI), COPTIC CAPITAL LETTER DEI (GREEK CAPITAL LETTER DEI) +test(0x03F0, 0x03BA, 0x039A); // GREEK KAPPA SYMBOL (GREEK SMALL LETTER SCRIPT KAPPA), GREEK SMALL LETTER KAPPA, GREEK CAPITAL LETTER KAPPA +test(0x03F1, 0x03C1, 0x03A1); // GREEK RHO SYMBOL (GREEK SMALL LETTER TAILED RHO), GREEK SMALL LETTER RHO, GREEK CAPITAL LETTER RHO +test(0x03F2, 0x03F9); // GREEK LUNATE SIGMA SYMBOL (GREEK SMALL LETTER LUNATE SIGMA), GREEK CAPITAL LUNATE SIGMA SYMBOL +test(0x03F3, 0x037F); // GREEK LETTER YOT, GREEK CAPITAL LETTER YOT +test(0x03F4, 0x03B8, 0x0398, 0x03D1); // GREEK CAPITAL THETA SYMBOL, GREEK SMALL LETTER THETA, GREEK CAPITAL LETTER THETA, GREEK THETA SYMBOL (GREEK SMALL LETTER SCRIPT THETA) +test(0x03F5, 0x03B5, 0x0395); // GREEK LUNATE EPSILON SYMBOL, GREEK SMALL LETTER EPSILON, GREEK CAPITAL LETTER EPSILON +test(0x03F7, 0x03F8); // GREEK CAPITAL LETTER SHO, GREEK SMALL LETTER SHO +test(0x03F8, 0x03F7); // GREEK SMALL LETTER SHO, GREEK CAPITAL LETTER SHO +test(0x03F9, 0x03F2); // GREEK CAPITAL LUNATE SIGMA SYMBOL, GREEK LUNATE SIGMA SYMBOL (GREEK SMALL LETTER LUNATE SIGMA) +test(0x03FA, 0x03FB); // GREEK CAPITAL LETTER SAN, GREEK SMALL LETTER SAN +test(0x03FB, 0x03FA); // GREEK SMALL LETTER SAN, GREEK CAPITAL LETTER SAN +test(0x03FD, 0x037B); // GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL, GREEK SMALL REVERSED LUNATE SIGMA SYMBOL +test(0x03FE, 0x037C); // GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL, GREEK SMALL DOTTED LUNATE SIGMA SYMBOL +test(0x03FF, 0x037D); // GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL, GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL +test(0x0400, 0x0450); // CYRILLIC CAPITAL LETTER IE WITH GRAVE, CYRILLIC SMALL LETTER IE WITH GRAVE +test(0x0401, 0x0451); // CYRILLIC CAPITAL LETTER IO, CYRILLIC SMALL LETTER IO +test(0x0402, 0x0452); // CYRILLIC CAPITAL LETTER DJE, CYRILLIC SMALL LETTER DJE +test(0x0403, 0x0453); // CYRILLIC CAPITAL LETTER GJE, CYRILLIC SMALL LETTER GJE +test(0x0404, 0x0454); // CYRILLIC CAPITAL LETTER UKRAINIAN IE (CYRILLIC CAPITAL LETTER E), CYRILLIC SMALL LETTER UKRAINIAN IE (CYRILLIC SMALL LETTER E) +test(0x0405, 0x0455); // CYRILLIC CAPITAL LETTER DZE, CYRILLIC SMALL LETTER DZE +test(0x0406, 0x0456); // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I (CYRILLIC CAPITAL LETTER I), CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I (CYRILLIC SMALL LETTER I) +test(0x0407, 0x0457); // CYRILLIC CAPITAL LETTER YI, CYRILLIC SMALL LETTER YI +test(0x0408, 0x0458); // CYRILLIC CAPITAL LETTER JE, CYRILLIC SMALL LETTER JE +test(0x0409, 0x0459); // CYRILLIC CAPITAL LETTER LJE, CYRILLIC SMALL LETTER LJE +test(0x040A, 0x045A); // CYRILLIC CAPITAL LETTER NJE, CYRILLIC SMALL LETTER NJE +test(0x040B, 0x045B); // CYRILLIC CAPITAL LETTER TSHE, CYRILLIC SMALL LETTER TSHE +test(0x040C, 0x045C); // CYRILLIC CAPITAL LETTER KJE, CYRILLIC SMALL LETTER KJE +test(0x040D, 0x045D); // CYRILLIC CAPITAL LETTER I WITH GRAVE, CYRILLIC SMALL LETTER I WITH GRAVE +test(0x040E, 0x045E); // CYRILLIC CAPITAL LETTER SHORT U, CYRILLIC SMALL LETTER SHORT U +test(0x040F, 0x045F); // CYRILLIC CAPITAL LETTER DZHE, CYRILLIC SMALL LETTER DZHE +test(0x0410, 0x0430); // CYRILLIC CAPITAL LETTER A, CYRILLIC SMALL LETTER A +test(0x0411, 0x0431); // CYRILLIC CAPITAL LETTER BE, CYRILLIC SMALL LETTER BE +test(0x0412, 0x0432, 0x1C80); // CYRILLIC CAPITAL LETTER VE, CYRILLIC SMALL LETTER VE, CYRILLIC SMALL LETTER ROUNDED VE +test(0x0413, 0x0433); // CYRILLIC CAPITAL LETTER GHE (CYRILLIC CAPITAL LETTER GE), CYRILLIC SMALL LETTER GHE (CYRILLIC SMALL LETTER GE) +test(0x0414, 0x0434, 0x1C81); // CYRILLIC CAPITAL LETTER DE, CYRILLIC SMALL LETTER DE, CYRILLIC SMALL LETTER LONG-LEGGED DE +test(0x0415, 0x0435); // CYRILLIC CAPITAL LETTER IE, CYRILLIC SMALL LETTER IE +test(0x0416, 0x0436); // CYRILLIC CAPITAL LETTER ZHE, CYRILLIC SMALL LETTER ZHE +test(0x0417, 0x0437); // CYRILLIC CAPITAL LETTER ZE, CYRILLIC SMALL LETTER ZE +test(0x0418, 0x0438); // CYRILLIC CAPITAL LETTER I (CYRILLIC CAPITAL LETTER II), CYRILLIC SMALL LETTER I (CYRILLIC SMALL LETTER II) +test(0x0419, 0x0439); // CYRILLIC CAPITAL LETTER SHORT I (CYRILLIC CAPITAL LETTER SHORT II), CYRILLIC SMALL LETTER SHORT I (CYRILLIC SMALL LETTER SHORT II) +test(0x041A, 0x043A); // CYRILLIC CAPITAL LETTER KA, CYRILLIC SMALL LETTER KA +test(0x041B, 0x043B); // CYRILLIC CAPITAL LETTER EL, CYRILLIC SMALL LETTER EL +test(0x041C, 0x043C); // CYRILLIC CAPITAL LETTER EM, CYRILLIC SMALL LETTER EM +test(0x041D, 0x043D); // CYRILLIC CAPITAL LETTER EN, CYRILLIC SMALL LETTER EN +test(0x041E, 0x043E, 0x1C82); // CYRILLIC CAPITAL LETTER O, CYRILLIC SMALL LETTER O, CYRILLIC SMALL LETTER NARROW O +test(0x041F, 0x043F); // CYRILLIC CAPITAL LETTER PE, CYRILLIC SMALL LETTER PE +test(0x0420, 0x0440); // CYRILLIC CAPITAL LETTER ER, CYRILLIC SMALL LETTER ER +test(0x0421, 0x0441, 0x1C83); // CYRILLIC CAPITAL LETTER ES, CYRILLIC SMALL LETTER ES, CYRILLIC SMALL LETTER WIDE ES +test(0x0422, 0x0442, 0x1C84, 0x1C85); // CYRILLIC CAPITAL LETTER TE, CYRILLIC SMALL LETTER TE, CYRILLIC SMALL LETTER TALL TE, CYRILLIC SMALL LETTER THREE-LEGGED TE +test(0x0423, 0x0443); // CYRILLIC CAPITAL LETTER U, CYRILLIC SMALL LETTER U +test(0x0424, 0x0444); // CYRILLIC CAPITAL LETTER EF, CYRILLIC SMALL LETTER EF +test(0x0425, 0x0445); // CYRILLIC CAPITAL LETTER HA (CYRILLIC CAPITAL LETTER KHA), CYRILLIC SMALL LETTER HA (CYRILLIC SMALL LETTER KHA) +test(0x0426, 0x0446); // CYRILLIC CAPITAL LETTER TSE, CYRILLIC SMALL LETTER TSE +test(0x0427, 0x0447); // CYRILLIC CAPITAL LETTER CHE, CYRILLIC SMALL LETTER CHE +test(0x0428, 0x0448); // CYRILLIC CAPITAL LETTER SHA, CYRILLIC SMALL LETTER SHA +test(0x0429, 0x0449); // CYRILLIC CAPITAL LETTER SHCHA, CYRILLIC SMALL LETTER SHCHA +test(0x042A, 0x044A, 0x1C86); // CYRILLIC CAPITAL LETTER HARD SIGN, CYRILLIC SMALL LETTER HARD SIGN, CYRILLIC SMALL LETTER TALL HARD SIGN +test(0x042B, 0x044B); // CYRILLIC CAPITAL LETTER YERU (CYRILLIC CAPITAL LETTER YERI), CYRILLIC SMALL LETTER YERU (CYRILLIC SMALL LETTER YERI) +test(0x042C, 0x044C); // CYRILLIC CAPITAL LETTER SOFT SIGN, CYRILLIC SMALL LETTER SOFT SIGN +test(0x042D, 0x044D); // CYRILLIC CAPITAL LETTER E (CYRILLIC CAPITAL LETTER REVERSED E), CYRILLIC SMALL LETTER E (CYRILLIC SMALL LETTER REVERSED E) +test(0x042E, 0x044E); // CYRILLIC CAPITAL LETTER YU (CYRILLIC CAPITAL LETTER IU), CYRILLIC SMALL LETTER YU (CYRILLIC SMALL LETTER IU) +test(0x042F, 0x044F); // CYRILLIC CAPITAL LETTER YA (CYRILLIC CAPITAL LETTER IA), CYRILLIC SMALL LETTER YA (CYRILLIC SMALL LETTER IA) +test(0x0430, 0x0410); // CYRILLIC SMALL LETTER A, CYRILLIC CAPITAL LETTER A +test(0x0431, 0x0411); // CYRILLIC SMALL LETTER BE, CYRILLIC CAPITAL LETTER BE +test(0x0432, 0x0412, 0x1C80); // CYRILLIC SMALL LETTER VE, CYRILLIC CAPITAL LETTER VE, CYRILLIC SMALL LETTER ROUNDED VE +test(0x0433, 0x0413); // CYRILLIC SMALL LETTER GHE (CYRILLIC SMALL LETTER GE), CYRILLIC CAPITAL LETTER GHE (CYRILLIC CAPITAL LETTER GE) +test(0x0434, 0x0414, 0x1C81); // CYRILLIC SMALL LETTER DE, CYRILLIC CAPITAL LETTER DE, CYRILLIC SMALL LETTER LONG-LEGGED DE +test(0x0435, 0x0415); // CYRILLIC SMALL LETTER IE, CYRILLIC CAPITAL LETTER IE +test(0x0436, 0x0416); // CYRILLIC SMALL LETTER ZHE, CYRILLIC CAPITAL LETTER ZHE +test(0x0437, 0x0417); // CYRILLIC SMALL LETTER ZE, CYRILLIC CAPITAL LETTER ZE +test(0x0438, 0x0418); // CYRILLIC SMALL LETTER I (CYRILLIC SMALL LETTER II), CYRILLIC CAPITAL LETTER I (CYRILLIC CAPITAL LETTER II) +test(0x0439, 0x0419); // CYRILLIC SMALL LETTER SHORT I (CYRILLIC SMALL LETTER SHORT II), CYRILLIC CAPITAL LETTER SHORT I (CYRILLIC CAPITAL LETTER SHORT II) +test(0x043A, 0x041A); // CYRILLIC SMALL LETTER KA, CYRILLIC CAPITAL LETTER KA +test(0x043B, 0x041B); // CYRILLIC SMALL LETTER EL, CYRILLIC CAPITAL LETTER EL +test(0x043C, 0x041C); // CYRILLIC SMALL LETTER EM, CYRILLIC CAPITAL LETTER EM +test(0x043D, 0x041D); // CYRILLIC SMALL LETTER EN, CYRILLIC CAPITAL LETTER EN +test(0x043E, 0x041E, 0x1C82); // CYRILLIC SMALL LETTER O, CYRILLIC CAPITAL LETTER O, CYRILLIC SMALL LETTER NARROW O +test(0x043F, 0x041F); // CYRILLIC SMALL LETTER PE, CYRILLIC CAPITAL LETTER PE +test(0x0440, 0x0420); // CYRILLIC SMALL LETTER ER, CYRILLIC CAPITAL LETTER ER +test(0x0441, 0x0421, 0x1C83); // CYRILLIC SMALL LETTER ES, CYRILLIC CAPITAL LETTER ES, CYRILLIC SMALL LETTER WIDE ES +test(0x0442, 0x0422, 0x1C84, 0x1C85); // CYRILLIC SMALL LETTER TE, CYRILLIC CAPITAL LETTER TE, CYRILLIC SMALL LETTER TALL TE, CYRILLIC SMALL LETTER THREE-LEGGED TE +test(0x0443, 0x0423); // CYRILLIC SMALL LETTER U, CYRILLIC CAPITAL LETTER U +test(0x0444, 0x0424); // CYRILLIC SMALL LETTER EF, CYRILLIC CAPITAL LETTER EF +test(0x0445, 0x0425); // CYRILLIC SMALL LETTER HA (CYRILLIC SMALL LETTER KHA), CYRILLIC CAPITAL LETTER HA (CYRILLIC CAPITAL LETTER KHA) +test(0x0446, 0x0426); // CYRILLIC SMALL LETTER TSE, CYRILLIC CAPITAL LETTER TSE +test(0x0447, 0x0427); // CYRILLIC SMALL LETTER CHE, CYRILLIC CAPITAL LETTER CHE +test(0x0448, 0x0428); // CYRILLIC SMALL LETTER SHA, CYRILLIC CAPITAL LETTER SHA +test(0x0449, 0x0429); // CYRILLIC SMALL LETTER SHCHA, CYRILLIC CAPITAL LETTER SHCHA +test(0x044A, 0x042A, 0x1C86); // CYRILLIC SMALL LETTER HARD SIGN, CYRILLIC CAPITAL LETTER HARD SIGN, CYRILLIC SMALL LETTER TALL HARD SIGN +test(0x044B, 0x042B); // CYRILLIC SMALL LETTER YERU (CYRILLIC SMALL LETTER YERI), CYRILLIC CAPITAL LETTER YERU (CYRILLIC CAPITAL LETTER YERI) +test(0x044C, 0x042C); // CYRILLIC SMALL LETTER SOFT SIGN, CYRILLIC CAPITAL LETTER SOFT SIGN +test(0x044D, 0x042D); // CYRILLIC SMALL LETTER E (CYRILLIC SMALL LETTER REVERSED E), CYRILLIC CAPITAL LETTER E (CYRILLIC CAPITAL LETTER REVERSED E) +test(0x044E, 0x042E); // CYRILLIC SMALL LETTER YU (CYRILLIC SMALL LETTER IU), CYRILLIC CAPITAL LETTER YU (CYRILLIC CAPITAL LETTER IU) +test(0x044F, 0x042F); // CYRILLIC SMALL LETTER YA (CYRILLIC SMALL LETTER IA), CYRILLIC CAPITAL LETTER YA (CYRILLIC CAPITAL LETTER IA) +test(0x0450, 0x0400); // CYRILLIC SMALL LETTER IE WITH GRAVE, CYRILLIC CAPITAL LETTER IE WITH GRAVE +test(0x0451, 0x0401); // CYRILLIC SMALL LETTER IO, CYRILLIC CAPITAL LETTER IO +test(0x0452, 0x0402); // CYRILLIC SMALL LETTER DJE, CYRILLIC CAPITAL LETTER DJE +test(0x0453, 0x0403); // CYRILLIC SMALL LETTER GJE, CYRILLIC CAPITAL LETTER GJE +test(0x0454, 0x0404); // CYRILLIC SMALL LETTER UKRAINIAN IE (CYRILLIC SMALL LETTER E), CYRILLIC CAPITAL LETTER UKRAINIAN IE (CYRILLIC CAPITAL LETTER E) +test(0x0455, 0x0405); // CYRILLIC SMALL LETTER DZE, CYRILLIC CAPITAL LETTER DZE +test(0x0456, 0x0406); // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I (CYRILLIC SMALL LETTER I), CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I (CYRILLIC CAPITAL LETTER I) +test(0x0457, 0x0407); // CYRILLIC SMALL LETTER YI, CYRILLIC CAPITAL LETTER YI +test(0x0458, 0x0408); // CYRILLIC SMALL LETTER JE, CYRILLIC CAPITAL LETTER JE +test(0x0459, 0x0409); // CYRILLIC SMALL LETTER LJE, CYRILLIC CAPITAL LETTER LJE +test(0x045A, 0x040A); // CYRILLIC SMALL LETTER NJE, CYRILLIC CAPITAL LETTER NJE +test(0x045B, 0x040B); // CYRILLIC SMALL LETTER TSHE, CYRILLIC CAPITAL LETTER TSHE +test(0x045C, 0x040C); // CYRILLIC SMALL LETTER KJE, CYRILLIC CAPITAL LETTER KJE +test(0x045D, 0x040D); // CYRILLIC SMALL LETTER I WITH GRAVE, CYRILLIC CAPITAL LETTER I WITH GRAVE +test(0x045E, 0x040E); // CYRILLIC SMALL LETTER SHORT U, CYRILLIC CAPITAL LETTER SHORT U +test(0x045F, 0x040F); // CYRILLIC SMALL LETTER DZHE, CYRILLIC CAPITAL LETTER DZHE +test(0x0460, 0x0461); // CYRILLIC CAPITAL LETTER OMEGA, CYRILLIC SMALL LETTER OMEGA +test(0x0461, 0x0460); // CYRILLIC SMALL LETTER OMEGA, CYRILLIC CAPITAL LETTER OMEGA +test(0x0462, 0x0463, 0x1C87); // CYRILLIC CAPITAL LETTER YAT, CYRILLIC SMALL LETTER YAT, CYRILLIC SMALL LETTER TALL YAT +test(0x0463, 0x0462, 0x1C87); // CYRILLIC SMALL LETTER YAT, CYRILLIC CAPITAL LETTER YAT, CYRILLIC SMALL LETTER TALL YAT +test(0x0464, 0x0465); // CYRILLIC CAPITAL LETTER IOTIFIED E, CYRILLIC SMALL LETTER IOTIFIED E +test(0x0465, 0x0464); // CYRILLIC SMALL LETTER IOTIFIED E, CYRILLIC CAPITAL LETTER IOTIFIED E +test(0x0466, 0x0467); // CYRILLIC CAPITAL LETTER LITTLE YUS, CYRILLIC SMALL LETTER LITTLE YUS +test(0x0467, 0x0466); // CYRILLIC SMALL LETTER LITTLE YUS, CYRILLIC CAPITAL LETTER LITTLE YUS +test(0x0468, 0x0469); // CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS, CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS +test(0x0469, 0x0468); // CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS, CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS +test(0x046A, 0x046B); // CYRILLIC CAPITAL LETTER BIG YUS, CYRILLIC SMALL LETTER BIG YUS +test(0x046B, 0x046A); // CYRILLIC SMALL LETTER BIG YUS, CYRILLIC CAPITAL LETTER BIG YUS +test(0x046C, 0x046D); // CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS, CYRILLIC SMALL LETTER IOTIFIED BIG YUS +test(0x046D, 0x046C); // CYRILLIC SMALL LETTER IOTIFIED BIG YUS, CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS +test(0x046E, 0x046F); // CYRILLIC CAPITAL LETTER KSI, CYRILLIC SMALL LETTER KSI +test(0x046F, 0x046E); // CYRILLIC SMALL LETTER KSI, CYRILLIC CAPITAL LETTER KSI +test(0x0470, 0x0471); // CYRILLIC CAPITAL LETTER PSI, CYRILLIC SMALL LETTER PSI +test(0x0471, 0x0470); // CYRILLIC SMALL LETTER PSI, CYRILLIC CAPITAL LETTER PSI +test(0x0472, 0x0473); // CYRILLIC CAPITAL LETTER FITA, CYRILLIC SMALL LETTER FITA +test(0x0473, 0x0472); // CYRILLIC SMALL LETTER FITA, CYRILLIC CAPITAL LETTER FITA +test(0x0474, 0x0475); // CYRILLIC CAPITAL LETTER IZHITSA, CYRILLIC SMALL LETTER IZHITSA +test(0x0475, 0x0474); // CYRILLIC SMALL LETTER IZHITSA, CYRILLIC CAPITAL LETTER IZHITSA +test(0x0476, 0x0477); // CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT (CYRILLIC CAPITAL LETTER IZHITSA DOUBLE GRAVE), CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT (CYRILLIC SMALL LETTER IZHITSA DOUBLE GRAVE) +test(0x0477, 0x0476); // CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT (CYRILLIC SMALL LETTER IZHITSA DOUBLE GRAVE), CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT (CYRILLIC CAPITAL LETTER IZHITSA DOUBLE GRAVE) +test(0x0478, 0x0479); // CYRILLIC CAPITAL LETTER UK (CYRILLIC CAPITAL LETTER UK DIGRAPH), CYRILLIC SMALL LETTER UK (CYRILLIC SMALL LETTER UK DIGRAPH) +test(0x0479, 0x0478); // CYRILLIC SMALL LETTER UK (CYRILLIC SMALL LETTER UK DIGRAPH), CYRILLIC CAPITAL LETTER UK (CYRILLIC CAPITAL LETTER UK DIGRAPH) +test(0x047A, 0x047B); // CYRILLIC CAPITAL LETTER ROUND OMEGA, CYRILLIC SMALL LETTER ROUND OMEGA +test(0x047B, 0x047A); // CYRILLIC SMALL LETTER ROUND OMEGA, CYRILLIC CAPITAL LETTER ROUND OMEGA +test(0x047C, 0x047D); // CYRILLIC CAPITAL LETTER OMEGA WITH TITLO (CYRILLIC CAPITAL LETTER OMEGA TITLO), CYRILLIC SMALL LETTER OMEGA WITH TITLO (CYRILLIC SMALL LETTER OMEGA TITLO) +test(0x047D, 0x047C); // CYRILLIC SMALL LETTER OMEGA WITH TITLO (CYRILLIC SMALL LETTER OMEGA TITLO), CYRILLIC CAPITAL LETTER OMEGA WITH TITLO (CYRILLIC CAPITAL LETTER OMEGA TITLO) +test(0x047E, 0x047F); // CYRILLIC CAPITAL LETTER OT, CYRILLIC SMALL LETTER OT +test(0x047F, 0x047E); // CYRILLIC SMALL LETTER OT, CYRILLIC CAPITAL LETTER OT +test(0x0480, 0x0481); // CYRILLIC CAPITAL LETTER KOPPA, CYRILLIC SMALL LETTER KOPPA +test(0x0481, 0x0480); // CYRILLIC SMALL LETTER KOPPA, CYRILLIC CAPITAL LETTER KOPPA +test(0x048A, 0x048B); // CYRILLIC CAPITAL LETTER SHORT I WITH TAIL, CYRILLIC SMALL LETTER SHORT I WITH TAIL +test(0x048B, 0x048A); // CYRILLIC SMALL LETTER SHORT I WITH TAIL, CYRILLIC CAPITAL LETTER SHORT I WITH TAIL +test(0x048C, 0x048D); // CYRILLIC CAPITAL LETTER SEMISOFT SIGN, CYRILLIC SMALL LETTER SEMISOFT SIGN +test(0x048D, 0x048C); // CYRILLIC SMALL LETTER SEMISOFT SIGN, CYRILLIC CAPITAL LETTER SEMISOFT SIGN +test(0x048E, 0x048F); // CYRILLIC CAPITAL LETTER ER WITH TICK, CYRILLIC SMALL LETTER ER WITH TICK +test(0x048F, 0x048E); // CYRILLIC SMALL LETTER ER WITH TICK, CYRILLIC CAPITAL LETTER ER WITH TICK +test(0x0490, 0x0491); // CYRILLIC CAPITAL LETTER GHE WITH UPTURN (CYRILLIC CAPITAL LETTER GE WITH UPTURN), CYRILLIC SMALL LETTER GHE WITH UPTURN (CYRILLIC SMALL LETTER GE WITH UPTURN) +test(0x0491, 0x0490); // CYRILLIC SMALL LETTER GHE WITH UPTURN (CYRILLIC SMALL LETTER GE WITH UPTURN), CYRILLIC CAPITAL LETTER GHE WITH UPTURN (CYRILLIC CAPITAL LETTER GE WITH UPTURN) +test(0x0492, 0x0493); // CYRILLIC CAPITAL LETTER GHE WITH STROKE (CYRILLIC CAPITAL LETTER GE BAR), CYRILLIC SMALL LETTER GHE WITH STROKE (CYRILLIC SMALL LETTER GE BAR) +test(0x0493, 0x0492); // CYRILLIC SMALL LETTER GHE WITH STROKE (CYRILLIC SMALL LETTER GE BAR), CYRILLIC CAPITAL LETTER GHE WITH STROKE (CYRILLIC CAPITAL LETTER GE BAR) +test(0x0494, 0x0495); // CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK (CYRILLIC CAPITAL LETTER GE HOOK), CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK (CYRILLIC SMALL LETTER GE HOOK) +test(0x0495, 0x0494); // CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK (CYRILLIC SMALL LETTER GE HOOK), CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK (CYRILLIC CAPITAL LETTER GE HOOK) +test(0x0496, 0x0497); // CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER (CYRILLIC CAPITAL LETTER ZHE WITH RIGHT DESCENDER), CYRILLIC SMALL LETTER ZHE WITH DESCENDER (CYRILLIC SMALL LETTER ZHE WITH RIGHT DESCENDER) +test(0x0497, 0x0496); // CYRILLIC SMALL LETTER ZHE WITH DESCENDER (CYRILLIC SMALL LETTER ZHE WITH RIGHT DESCENDER), CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER (CYRILLIC CAPITAL LETTER ZHE WITH RIGHT DESCENDER) +test(0x0498, 0x0499); // CYRILLIC CAPITAL LETTER ZE WITH DESCENDER (CYRILLIC CAPITAL LETTER ZE CEDILLA), CYRILLIC SMALL LETTER ZE WITH DESCENDER (CYRILLIC SMALL LETTER ZE CEDILLA) +test(0x0499, 0x0498); // CYRILLIC SMALL LETTER ZE WITH DESCENDER (CYRILLIC SMALL LETTER ZE CEDILLA), CYRILLIC CAPITAL LETTER ZE WITH DESCENDER (CYRILLIC CAPITAL LETTER ZE CEDILLA) +test(0x049A, 0x049B); // CYRILLIC CAPITAL LETTER KA WITH DESCENDER (CYRILLIC CAPITAL LETTER KA WITH RIGHT DESCENDER), CYRILLIC SMALL LETTER KA WITH DESCENDER (CYRILLIC SMALL LETTER KA WITH RIGHT DESCENDER) +test(0x049B, 0x049A); // CYRILLIC SMALL LETTER KA WITH DESCENDER (CYRILLIC SMALL LETTER KA WITH RIGHT DESCENDER), CYRILLIC CAPITAL LETTER KA WITH DESCENDER (CYRILLIC CAPITAL LETTER KA WITH RIGHT DESCENDER) +test(0x049C, 0x049D); // CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE (CYRILLIC CAPITAL LETTER KA VERTICAL BAR), CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE (CYRILLIC SMALL LETTER KA VERTICAL BAR) +test(0x049D, 0x049C); // CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE (CYRILLIC SMALL LETTER KA VERTICAL BAR), CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE (CYRILLIC CAPITAL LETTER KA VERTICAL BAR) +test(0x049E, 0x049F); // CYRILLIC CAPITAL LETTER KA WITH STROKE (CYRILLIC CAPITAL LETTER KA BAR), CYRILLIC SMALL LETTER KA WITH STROKE (CYRILLIC SMALL LETTER KA BAR) +test(0x049F, 0x049E); // CYRILLIC SMALL LETTER KA WITH STROKE (CYRILLIC SMALL LETTER KA BAR), CYRILLIC CAPITAL LETTER KA WITH STROKE (CYRILLIC CAPITAL LETTER KA BAR) +test(0x04A0, 0x04A1); // CYRILLIC CAPITAL LETTER BASHKIR KA (CYRILLIC CAPITAL LETTER REVERSED GE KA), CYRILLIC SMALL LETTER BASHKIR KA (CYRILLIC SMALL LETTER REVERSED GE KA) +test(0x04A1, 0x04A0); // CYRILLIC SMALL LETTER BASHKIR KA (CYRILLIC SMALL LETTER REVERSED GE KA), CYRILLIC CAPITAL LETTER BASHKIR KA (CYRILLIC CAPITAL LETTER REVERSED GE KA) +test(0x04A2, 0x04A3); // CYRILLIC CAPITAL LETTER EN WITH DESCENDER (CYRILLIC CAPITAL LETTER EN WITH RIGHT DESCENDER), CYRILLIC SMALL LETTER EN WITH DESCENDER (CYRILLIC SMALL LETTER EN WITH RIGHT DESCENDER) +test(0x04A3, 0x04A2); // CYRILLIC SMALL LETTER EN WITH DESCENDER (CYRILLIC SMALL LETTER EN WITH RIGHT DESCENDER), CYRILLIC CAPITAL LETTER EN WITH DESCENDER (CYRILLIC CAPITAL LETTER EN WITH RIGHT DESCENDER) +test(0x04A4, 0x04A5); // CYRILLIC CAPITAL LIGATURE EN GHE (CYRILLIC CAPITAL LETTER EN GE), CYRILLIC SMALL LIGATURE EN GHE (CYRILLIC SMALL LETTER EN GE) +test(0x04A5, 0x04A4); // CYRILLIC SMALL LIGATURE EN GHE (CYRILLIC SMALL LETTER EN GE), CYRILLIC CAPITAL LIGATURE EN GHE (CYRILLIC CAPITAL LETTER EN GE) +test(0x04A6, 0x04A7); // CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK (CYRILLIC CAPITAL LETTER PE HOOK), CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK (CYRILLIC SMALL LETTER PE HOOK) +test(0x04A7, 0x04A6); // CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK (CYRILLIC SMALL LETTER PE HOOK), CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK (CYRILLIC CAPITAL LETTER PE HOOK) +test(0x04A8, 0x04A9); // CYRILLIC CAPITAL LETTER ABKHASIAN HA (CYRILLIC CAPITAL LETTER O HOOK), CYRILLIC SMALL LETTER ABKHASIAN HA (CYRILLIC SMALL LETTER O HOOK) +test(0x04A9, 0x04A8); // CYRILLIC SMALL LETTER ABKHASIAN HA (CYRILLIC SMALL LETTER O HOOK), CYRILLIC CAPITAL LETTER ABKHASIAN HA (CYRILLIC CAPITAL LETTER O HOOK) +test(0x04AA, 0x04AB); // CYRILLIC CAPITAL LETTER ES WITH DESCENDER (CYRILLIC CAPITAL LETTER ES CEDILLA), CYRILLIC SMALL LETTER ES WITH DESCENDER (CYRILLIC SMALL LETTER ES CEDILLA) +test(0x04AB, 0x04AA); // CYRILLIC SMALL LETTER ES WITH DESCENDER (CYRILLIC SMALL LETTER ES CEDILLA), CYRILLIC CAPITAL LETTER ES WITH DESCENDER (CYRILLIC CAPITAL LETTER ES CEDILLA) +test(0x04AC, 0x04AD); // CYRILLIC CAPITAL LETTER TE WITH DESCENDER (CYRILLIC CAPITAL LETTER TE WITH RIGHT DESCENDER), CYRILLIC SMALL LETTER TE WITH DESCENDER (CYRILLIC SMALL LETTER TE WITH RIGHT DESCENDER) +test(0x04AD, 0x04AC); // CYRILLIC SMALL LETTER TE WITH DESCENDER (CYRILLIC SMALL LETTER TE WITH RIGHT DESCENDER), CYRILLIC CAPITAL LETTER TE WITH DESCENDER (CYRILLIC CAPITAL LETTER TE WITH RIGHT DESCENDER) +test(0x04AE, 0x04AF); // CYRILLIC CAPITAL LETTER STRAIGHT U, CYRILLIC SMALL LETTER STRAIGHT U +test(0x04AF, 0x04AE); // CYRILLIC SMALL LETTER STRAIGHT U, CYRILLIC CAPITAL LETTER STRAIGHT U +test(0x04B0, 0x04B1); // CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE (CYRILLIC CAPITAL LETTER STRAIGHT U BAR), CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE (CYRILLIC SMALL LETTER STRAIGHT U BAR) +test(0x04B1, 0x04B0); // CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE (CYRILLIC SMALL LETTER STRAIGHT U BAR), CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE (CYRILLIC CAPITAL LETTER STRAIGHT U BAR) +test(0x04B2, 0x04B3); // CYRILLIC CAPITAL LETTER HA WITH DESCENDER (CYRILLIC CAPITAL LETTER KHA WITH RIGHT DESCENDER), CYRILLIC SMALL LETTER HA WITH DESCENDER (CYRILLIC SMALL LETTER KHA WITH RIGHT DESCENDER) +test(0x04B3, 0x04B2); // CYRILLIC SMALL LETTER HA WITH DESCENDER (CYRILLIC SMALL LETTER KHA WITH RIGHT DESCENDER), CYRILLIC CAPITAL LETTER HA WITH DESCENDER (CYRILLIC CAPITAL LETTER KHA WITH RIGHT DESCENDER) +test(0x04B4, 0x04B5); // CYRILLIC CAPITAL LIGATURE TE TSE (CYRILLIC CAPITAL LETTER TE TSE), CYRILLIC SMALL LIGATURE TE TSE (CYRILLIC SMALL LETTER TE TSE) +test(0x04B5, 0x04B4); // CYRILLIC SMALL LIGATURE TE TSE (CYRILLIC SMALL LETTER TE TSE), CYRILLIC CAPITAL LIGATURE TE TSE (CYRILLIC CAPITAL LETTER TE TSE) +test(0x04B6, 0x04B7); // CYRILLIC CAPITAL LETTER CHE WITH DESCENDER (CYRILLIC CAPITAL LETTER CHE WITH RIGHT DESCENDER), CYRILLIC SMALL LETTER CHE WITH DESCENDER (CYRILLIC SMALL LETTER CHE WITH RIGHT DESCENDER) +test(0x04B7, 0x04B6); // CYRILLIC SMALL LETTER CHE WITH DESCENDER (CYRILLIC SMALL LETTER CHE WITH RIGHT DESCENDER), CYRILLIC CAPITAL LETTER CHE WITH DESCENDER (CYRILLIC CAPITAL LETTER CHE WITH RIGHT DESCENDER) +test(0x04B8, 0x04B9); // CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE (CYRILLIC CAPITAL LETTER CHE VERTICAL BAR), CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE (CYRILLIC SMALL LETTER CHE VERTICAL BAR) +test(0x04B9, 0x04B8); // CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE (CYRILLIC SMALL LETTER CHE VERTICAL BAR), CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE (CYRILLIC CAPITAL LETTER CHE VERTICAL BAR) +test(0x04BA, 0x04BB); // CYRILLIC CAPITAL LETTER SHHA (CYRILLIC CAPITAL LETTER H), CYRILLIC SMALL LETTER SHHA (CYRILLIC SMALL LETTER H) +test(0x04BB, 0x04BA); // CYRILLIC SMALL LETTER SHHA (CYRILLIC SMALL LETTER H), CYRILLIC CAPITAL LETTER SHHA (CYRILLIC CAPITAL LETTER H) +test(0x04BC, 0x04BD); // CYRILLIC CAPITAL LETTER ABKHASIAN CHE (CYRILLIC CAPITAL LETTER IE HOOK), CYRILLIC SMALL LETTER ABKHASIAN CHE (CYRILLIC SMALL LETTER IE HOOK) +test(0x04BD, 0x04BC); // CYRILLIC SMALL LETTER ABKHASIAN CHE (CYRILLIC SMALL LETTER IE HOOK), CYRILLIC CAPITAL LETTER ABKHASIAN CHE (CYRILLIC CAPITAL LETTER IE HOOK) +test(0x04BE, 0x04BF); // CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER (CYRILLIC CAPITAL LETTER IE HOOK OGONEK), CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER (CYRILLIC SMALL LETTER IE HOOK OGONEK) +test(0x04BF, 0x04BE); // CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER (CYRILLIC SMALL LETTER IE HOOK OGONEK), CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER (CYRILLIC CAPITAL LETTER IE HOOK OGONEK) +test(0x04C0, 0x04CF); // CYRILLIC LETTER PALOCHKA (CYRILLIC LETTER I), CYRILLIC SMALL LETTER PALOCHKA +test(0x04C1, 0x04C2); // CYRILLIC CAPITAL LETTER ZHE WITH BREVE (CYRILLIC CAPITAL LETTER SHORT ZHE), CYRILLIC SMALL LETTER ZHE WITH BREVE (CYRILLIC SMALL LETTER SHORT ZHE) +test(0x04C2, 0x04C1); // CYRILLIC SMALL LETTER ZHE WITH BREVE (CYRILLIC SMALL LETTER SHORT ZHE), CYRILLIC CAPITAL LETTER ZHE WITH BREVE (CYRILLIC CAPITAL LETTER SHORT ZHE) +test(0x04C3, 0x04C4); // CYRILLIC CAPITAL LETTER KA WITH HOOK (CYRILLIC CAPITAL LETTER KA HOOK), CYRILLIC SMALL LETTER KA WITH HOOK (CYRILLIC SMALL LETTER KA HOOK) +test(0x04C4, 0x04C3); // CYRILLIC SMALL LETTER KA WITH HOOK (CYRILLIC SMALL LETTER KA HOOK), CYRILLIC CAPITAL LETTER KA WITH HOOK (CYRILLIC CAPITAL LETTER KA HOOK) +test(0x04C5, 0x04C6); // CYRILLIC CAPITAL LETTER EL WITH TAIL, CYRILLIC SMALL LETTER EL WITH TAIL +test(0x04C6, 0x04C5); // CYRILLIC SMALL LETTER EL WITH TAIL, CYRILLIC CAPITAL LETTER EL WITH TAIL +test(0x04C7, 0x04C8); // CYRILLIC CAPITAL LETTER EN WITH HOOK (CYRILLIC CAPITAL LETTER EN HOOK), CYRILLIC SMALL LETTER EN WITH HOOK (CYRILLIC SMALL LETTER EN HOOK) +test(0x04C8, 0x04C7); // CYRILLIC SMALL LETTER EN WITH HOOK (CYRILLIC SMALL LETTER EN HOOK), CYRILLIC CAPITAL LETTER EN WITH HOOK (CYRILLIC CAPITAL LETTER EN HOOK) +test(0x04C9, 0x04CA); // CYRILLIC CAPITAL LETTER EN WITH TAIL, CYRILLIC SMALL LETTER EN WITH TAIL +test(0x04CA, 0x04C9); // CYRILLIC SMALL LETTER EN WITH TAIL, CYRILLIC CAPITAL LETTER EN WITH TAIL +test(0x04CB, 0x04CC); // CYRILLIC CAPITAL LETTER KHAKASSIAN CHE (CYRILLIC CAPITAL LETTER CHE WITH LEFT DESCENDER), CYRILLIC SMALL LETTER KHAKASSIAN CHE (CYRILLIC SMALL LETTER CHE WITH LEFT DESCENDER) +test(0x04CC, 0x04CB); // CYRILLIC SMALL LETTER KHAKASSIAN CHE (CYRILLIC SMALL LETTER CHE WITH LEFT DESCENDER), CYRILLIC CAPITAL LETTER KHAKASSIAN CHE (CYRILLIC CAPITAL LETTER CHE WITH LEFT DESCENDER) +test(0x04CD, 0x04CE); // CYRILLIC CAPITAL LETTER EM WITH TAIL, CYRILLIC SMALL LETTER EM WITH TAIL +test(0x04CE, 0x04CD); // CYRILLIC SMALL LETTER EM WITH TAIL, CYRILLIC CAPITAL LETTER EM WITH TAIL +test(0x04CF, 0x04C0); // CYRILLIC SMALL LETTER PALOCHKA, CYRILLIC LETTER PALOCHKA (CYRILLIC LETTER I) +test(0x04D0, 0x04D1); // CYRILLIC CAPITAL LETTER A WITH BREVE, CYRILLIC SMALL LETTER A WITH BREVE +test(0x04D1, 0x04D0); // CYRILLIC SMALL LETTER A WITH BREVE, CYRILLIC CAPITAL LETTER A WITH BREVE +test(0x04D2, 0x04D3); // CYRILLIC CAPITAL LETTER A WITH DIAERESIS, CYRILLIC SMALL LETTER A WITH DIAERESIS +test(0x04D3, 0x04D2); // CYRILLIC SMALL LETTER A WITH DIAERESIS, CYRILLIC CAPITAL LETTER A WITH DIAERESIS +test(0x04D4, 0x04D5); // CYRILLIC CAPITAL LIGATURE A IE, CYRILLIC SMALL LIGATURE A IE +test(0x04D5, 0x04D4); // CYRILLIC SMALL LIGATURE A IE, CYRILLIC CAPITAL LIGATURE A IE +test(0x04D6, 0x04D7); // CYRILLIC CAPITAL LETTER IE WITH BREVE, CYRILLIC SMALL LETTER IE WITH BREVE +test(0x04D7, 0x04D6); // CYRILLIC SMALL LETTER IE WITH BREVE, CYRILLIC CAPITAL LETTER IE WITH BREVE +test(0x04D8, 0x04D9); // CYRILLIC CAPITAL LETTER SCHWA, CYRILLIC SMALL LETTER SCHWA +test(0x04D9, 0x04D8); // CYRILLIC SMALL LETTER SCHWA, CYRILLIC CAPITAL LETTER SCHWA +test(0x04DA, 0x04DB); // CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS, CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS +test(0x04DB, 0x04DA); // CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS, CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS +test(0x04DC, 0x04DD); // CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS, CYRILLIC SMALL LETTER ZHE WITH DIAERESIS +test(0x04DD, 0x04DC); // CYRILLIC SMALL LETTER ZHE WITH DIAERESIS, CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS +test(0x04DE, 0x04DF); // CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS, CYRILLIC SMALL LETTER ZE WITH DIAERESIS +test(0x04DF, 0x04DE); // CYRILLIC SMALL LETTER ZE WITH DIAERESIS, CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS +test(0x04E0, 0x04E1); // CYRILLIC CAPITAL LETTER ABKHASIAN DZE, CYRILLIC SMALL LETTER ABKHASIAN DZE +test(0x04E1, 0x04E0); // CYRILLIC SMALL LETTER ABKHASIAN DZE, CYRILLIC CAPITAL LETTER ABKHASIAN DZE +test(0x04E2, 0x04E3); // CYRILLIC CAPITAL LETTER I WITH MACRON, CYRILLIC SMALL LETTER I WITH MACRON +test(0x04E3, 0x04E2); // CYRILLIC SMALL LETTER I WITH MACRON, CYRILLIC CAPITAL LETTER I WITH MACRON +test(0x04E4, 0x04E5); // CYRILLIC CAPITAL LETTER I WITH DIAERESIS, CYRILLIC SMALL LETTER I WITH DIAERESIS +test(0x04E5, 0x04E4); // CYRILLIC SMALL LETTER I WITH DIAERESIS, CYRILLIC CAPITAL LETTER I WITH DIAERESIS +test(0x04E6, 0x04E7); // CYRILLIC CAPITAL LETTER O WITH DIAERESIS, CYRILLIC SMALL LETTER O WITH DIAERESIS +test(0x04E7, 0x04E6); // CYRILLIC SMALL LETTER O WITH DIAERESIS, CYRILLIC CAPITAL LETTER O WITH DIAERESIS +test(0x04E8, 0x04E9); // CYRILLIC CAPITAL LETTER BARRED O, CYRILLIC SMALL LETTER BARRED O +test(0x04E9, 0x04E8); // CYRILLIC SMALL LETTER BARRED O, CYRILLIC CAPITAL LETTER BARRED O +test(0x04EA, 0x04EB); // CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS, CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS +test(0x04EB, 0x04EA); // CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS, CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS +test(0x04EC, 0x04ED); // CYRILLIC CAPITAL LETTER E WITH DIAERESIS, CYRILLIC SMALL LETTER E WITH DIAERESIS +test(0x04ED, 0x04EC); // CYRILLIC SMALL LETTER E WITH DIAERESIS, CYRILLIC CAPITAL LETTER E WITH DIAERESIS +test(0x04EE, 0x04EF); // CYRILLIC CAPITAL LETTER U WITH MACRON, CYRILLIC SMALL LETTER U WITH MACRON +test(0x04EF, 0x04EE); // CYRILLIC SMALL LETTER U WITH MACRON, CYRILLIC CAPITAL LETTER U WITH MACRON +test(0x04F0, 0x04F1); // CYRILLIC CAPITAL LETTER U WITH DIAERESIS, CYRILLIC SMALL LETTER U WITH DIAERESIS +test(0x04F1, 0x04F0); // CYRILLIC SMALL LETTER U WITH DIAERESIS, CYRILLIC CAPITAL LETTER U WITH DIAERESIS +test(0x04F2, 0x04F3); // CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE, CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE +test(0x04F3, 0x04F2); // CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE, CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE +test(0x04F4, 0x04F5); // CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS, CYRILLIC SMALL LETTER CHE WITH DIAERESIS +test(0x04F5, 0x04F4); // CYRILLIC SMALL LETTER CHE WITH DIAERESIS, CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS +test(0x04F6, 0x04F7); // CYRILLIC CAPITAL LETTER GHE WITH DESCENDER, CYRILLIC SMALL LETTER GHE WITH DESCENDER +test(0x04F7, 0x04F6); // CYRILLIC SMALL LETTER GHE WITH DESCENDER, CYRILLIC CAPITAL LETTER GHE WITH DESCENDER +test(0x04F8, 0x04F9); // CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS, CYRILLIC SMALL LETTER YERU WITH DIAERESIS +test(0x04F9, 0x04F8); // CYRILLIC SMALL LETTER YERU WITH DIAERESIS, CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS +test(0x04FA, 0x04FB); // CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK, CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK +test(0x04FB, 0x04FA); // CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK, CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK +test(0x04FC, 0x04FD); // CYRILLIC CAPITAL LETTER HA WITH HOOK, CYRILLIC SMALL LETTER HA WITH HOOK +test(0x04FD, 0x04FC); // CYRILLIC SMALL LETTER HA WITH HOOK, CYRILLIC CAPITAL LETTER HA WITH HOOK +test(0x04FE, 0x04FF); // CYRILLIC CAPITAL LETTER HA WITH STROKE, CYRILLIC SMALL LETTER HA WITH STROKE +test(0x04FF, 0x04FE); // CYRILLIC SMALL LETTER HA WITH STROKE, CYRILLIC CAPITAL LETTER HA WITH STROKE +test(0x0500, 0x0501); // CYRILLIC CAPITAL LETTER KOMI DE, CYRILLIC SMALL LETTER KOMI DE +test(0x0501, 0x0500); // CYRILLIC SMALL LETTER KOMI DE, CYRILLIC CAPITAL LETTER KOMI DE +test(0x0502, 0x0503); // CYRILLIC CAPITAL LETTER KOMI DJE, CYRILLIC SMALL LETTER KOMI DJE +test(0x0503, 0x0502); // CYRILLIC SMALL LETTER KOMI DJE, CYRILLIC CAPITAL LETTER KOMI DJE +test(0x0504, 0x0505); // CYRILLIC CAPITAL LETTER KOMI ZJE, CYRILLIC SMALL LETTER KOMI ZJE +test(0x0505, 0x0504); // CYRILLIC SMALL LETTER KOMI ZJE, CYRILLIC CAPITAL LETTER KOMI ZJE +test(0x0506, 0x0507); // CYRILLIC CAPITAL LETTER KOMI DZJE, CYRILLIC SMALL LETTER KOMI DZJE +test(0x0507, 0x0506); // CYRILLIC SMALL LETTER KOMI DZJE, CYRILLIC CAPITAL LETTER KOMI DZJE +test(0x0508, 0x0509); // CYRILLIC CAPITAL LETTER KOMI LJE, CYRILLIC SMALL LETTER KOMI LJE +test(0x0509, 0x0508); // CYRILLIC SMALL LETTER KOMI LJE, CYRILLIC CAPITAL LETTER KOMI LJE +test(0x050A, 0x050B); // CYRILLIC CAPITAL LETTER KOMI NJE, CYRILLIC SMALL LETTER KOMI NJE +test(0x050B, 0x050A); // CYRILLIC SMALL LETTER KOMI NJE, CYRILLIC CAPITAL LETTER KOMI NJE +test(0x050C, 0x050D); // CYRILLIC CAPITAL LETTER KOMI SJE, CYRILLIC SMALL LETTER KOMI SJE +test(0x050D, 0x050C); // CYRILLIC SMALL LETTER KOMI SJE, CYRILLIC CAPITAL LETTER KOMI SJE +test(0x050E, 0x050F); // CYRILLIC CAPITAL LETTER KOMI TJE, CYRILLIC SMALL LETTER KOMI TJE +test(0x050F, 0x050E); // CYRILLIC SMALL LETTER KOMI TJE, CYRILLIC CAPITAL LETTER KOMI TJE +test(0x0510, 0x0511); // CYRILLIC CAPITAL LETTER REVERSED ZE, CYRILLIC SMALL LETTER REVERSED ZE +test(0x0511, 0x0510); // CYRILLIC SMALL LETTER REVERSED ZE, CYRILLIC CAPITAL LETTER REVERSED ZE +test(0x0512, 0x0513); // CYRILLIC CAPITAL LETTER EL WITH HOOK, CYRILLIC SMALL LETTER EL WITH HOOK +test(0x0513, 0x0512); // CYRILLIC SMALL LETTER EL WITH HOOK, CYRILLIC CAPITAL LETTER EL WITH HOOK +test(0x0514, 0x0515); // CYRILLIC CAPITAL LETTER LHA, CYRILLIC SMALL LETTER LHA +test(0x0515, 0x0514); // CYRILLIC SMALL LETTER LHA, CYRILLIC CAPITAL LETTER LHA +test(0x0516, 0x0517); // CYRILLIC CAPITAL LETTER RHA, CYRILLIC SMALL LETTER RHA +test(0x0517, 0x0516); // CYRILLIC SMALL LETTER RHA, CYRILLIC CAPITAL LETTER RHA +test(0x0518, 0x0519); // CYRILLIC CAPITAL LETTER YAE, CYRILLIC SMALL LETTER YAE +test(0x0519, 0x0518); // CYRILLIC SMALL LETTER YAE, CYRILLIC CAPITAL LETTER YAE +test(0x051A, 0x051B); // CYRILLIC CAPITAL LETTER QA, CYRILLIC SMALL LETTER QA +test(0x051B, 0x051A); // CYRILLIC SMALL LETTER QA, CYRILLIC CAPITAL LETTER QA +test(0x051C, 0x051D); // CYRILLIC CAPITAL LETTER WE, CYRILLIC SMALL LETTER WE +test(0x051D, 0x051C); // CYRILLIC SMALL LETTER WE, CYRILLIC CAPITAL LETTER WE +test(0x051E, 0x051F); // CYRILLIC CAPITAL LETTER ALEUT KA, CYRILLIC SMALL LETTER ALEUT KA +test(0x051F, 0x051E); // CYRILLIC SMALL LETTER ALEUT KA, CYRILLIC CAPITAL LETTER ALEUT KA +test(0x0520, 0x0521); // CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK, CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK +test(0x0521, 0x0520); // CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK, CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK +test(0x0522, 0x0523); // CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK, CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK +test(0x0523, 0x0522); // CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK, CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK +test(0x0524, 0x0525); // CYRILLIC CAPITAL LETTER PE WITH DESCENDER, CYRILLIC SMALL LETTER PE WITH DESCENDER +test(0x0525, 0x0524); // CYRILLIC SMALL LETTER PE WITH DESCENDER, CYRILLIC CAPITAL LETTER PE WITH DESCENDER +test(0x0526, 0x0527); // CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER, CYRILLIC SMALL LETTER SHHA WITH DESCENDER +test(0x0527, 0x0526); // CYRILLIC SMALL LETTER SHHA WITH DESCENDER, CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER +test(0x0528, 0x0529); // CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK, CYRILLIC SMALL LETTER EN WITH LEFT HOOK +test(0x0529, 0x0528); // CYRILLIC SMALL LETTER EN WITH LEFT HOOK, CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK +test(0x052A, 0x052B); // CYRILLIC CAPITAL LETTER DZZHE, CYRILLIC SMALL LETTER DZZHE +test(0x052B, 0x052A); // CYRILLIC SMALL LETTER DZZHE, CYRILLIC CAPITAL LETTER DZZHE +test(0x052C, 0x052D); // CYRILLIC CAPITAL LETTER DCHE, CYRILLIC SMALL LETTER DCHE +test(0x052D, 0x052C); // CYRILLIC SMALL LETTER DCHE, CYRILLIC CAPITAL LETTER DCHE +test(0x052E, 0x052F); // CYRILLIC CAPITAL LETTER EL WITH DESCENDER, CYRILLIC SMALL LETTER EL WITH DESCENDER +test(0x052F, 0x052E); // CYRILLIC SMALL LETTER EL WITH DESCENDER, CYRILLIC CAPITAL LETTER EL WITH DESCENDER +test(0x0531, 0x0561); // ARMENIAN CAPITAL LETTER AYB, ARMENIAN SMALL LETTER AYB +test(0x0532, 0x0562); // ARMENIAN CAPITAL LETTER BEN, ARMENIAN SMALL LETTER BEN +test(0x0533, 0x0563); // ARMENIAN CAPITAL LETTER GIM, ARMENIAN SMALL LETTER GIM +test(0x0534, 0x0564); // ARMENIAN CAPITAL LETTER DA, ARMENIAN SMALL LETTER DA +test(0x0535, 0x0565); // ARMENIAN CAPITAL LETTER ECH, ARMENIAN SMALL LETTER ECH +test(0x0536, 0x0566); // ARMENIAN CAPITAL LETTER ZA, ARMENIAN SMALL LETTER ZA +test(0x0537, 0x0567); // ARMENIAN CAPITAL LETTER EH, ARMENIAN SMALL LETTER EH +test(0x0538, 0x0568); // ARMENIAN CAPITAL LETTER ET, ARMENIAN SMALL LETTER ET +test(0x0539, 0x0569); // ARMENIAN CAPITAL LETTER TO, ARMENIAN SMALL LETTER TO +test(0x053A, 0x056A); // ARMENIAN CAPITAL LETTER ZHE, ARMENIAN SMALL LETTER ZHE +test(0x053B, 0x056B); // ARMENIAN CAPITAL LETTER INI, ARMENIAN SMALL LETTER INI +test(0x053C, 0x056C); // ARMENIAN CAPITAL LETTER LIWN, ARMENIAN SMALL LETTER LIWN +test(0x053D, 0x056D); // ARMENIAN CAPITAL LETTER XEH, ARMENIAN SMALL LETTER XEH +test(0x053E, 0x056E); // ARMENIAN CAPITAL LETTER CA, ARMENIAN SMALL LETTER CA +test(0x053F, 0x056F); // ARMENIAN CAPITAL LETTER KEN, ARMENIAN SMALL LETTER KEN +test(0x0540, 0x0570); // ARMENIAN CAPITAL LETTER HO, ARMENIAN SMALL LETTER HO +test(0x0541, 0x0571); // ARMENIAN CAPITAL LETTER JA, ARMENIAN SMALL LETTER JA +test(0x0542, 0x0572); // ARMENIAN CAPITAL LETTER GHAD (ARMENIAN CAPITAL LETTER LAD), ARMENIAN SMALL LETTER GHAD (ARMENIAN SMALL LETTER LAD) +test(0x0543, 0x0573); // ARMENIAN CAPITAL LETTER CHEH, ARMENIAN SMALL LETTER CHEH +test(0x0544, 0x0574); // ARMENIAN CAPITAL LETTER MEN, ARMENIAN SMALL LETTER MEN +test(0x0545, 0x0575); // ARMENIAN CAPITAL LETTER YI, ARMENIAN SMALL LETTER YI +test(0x0546, 0x0576); // ARMENIAN CAPITAL LETTER NOW, ARMENIAN SMALL LETTER NOW +test(0x0547, 0x0577); // ARMENIAN CAPITAL LETTER SHA, ARMENIAN SMALL LETTER SHA +test(0x0548, 0x0578); // ARMENIAN CAPITAL LETTER VO, ARMENIAN SMALL LETTER VO +test(0x0549, 0x0579); // ARMENIAN CAPITAL LETTER CHA, ARMENIAN SMALL LETTER CHA +test(0x054A, 0x057A); // ARMENIAN CAPITAL LETTER PEH, ARMENIAN SMALL LETTER PEH +test(0x054B, 0x057B); // ARMENIAN CAPITAL LETTER JHEH, ARMENIAN SMALL LETTER JHEH +test(0x054C, 0x057C); // ARMENIAN CAPITAL LETTER RA, ARMENIAN SMALL LETTER RA +test(0x054D, 0x057D); // ARMENIAN CAPITAL LETTER SEH, ARMENIAN SMALL LETTER SEH +test(0x054E, 0x057E); // ARMENIAN CAPITAL LETTER VEW, ARMENIAN SMALL LETTER VEW +test(0x054F, 0x057F); // ARMENIAN CAPITAL LETTER TIWN, ARMENIAN SMALL LETTER TIWN +test(0x0550, 0x0580); // ARMENIAN CAPITAL LETTER REH, ARMENIAN SMALL LETTER REH +test(0x0551, 0x0581); // ARMENIAN CAPITAL LETTER CO, ARMENIAN SMALL LETTER CO +test(0x0552, 0x0582); // ARMENIAN CAPITAL LETTER YIWN, ARMENIAN SMALL LETTER YIWN +test(0x0553, 0x0583); // ARMENIAN CAPITAL LETTER PIWR, ARMENIAN SMALL LETTER PIWR +test(0x0554, 0x0584); // ARMENIAN CAPITAL LETTER KEH, ARMENIAN SMALL LETTER KEH +test(0x0555, 0x0585); // ARMENIAN CAPITAL LETTER OH, ARMENIAN SMALL LETTER OH +test(0x0556, 0x0586); // ARMENIAN CAPITAL LETTER FEH, ARMENIAN SMALL LETTER FEH +test(0x0561, 0x0531); // ARMENIAN SMALL LETTER AYB, ARMENIAN CAPITAL LETTER AYB +test(0x0562, 0x0532); // ARMENIAN SMALL LETTER BEN, ARMENIAN CAPITAL LETTER BEN +test(0x0563, 0x0533); // ARMENIAN SMALL LETTER GIM, ARMENIAN CAPITAL LETTER GIM +test(0x0564, 0x0534); // ARMENIAN SMALL LETTER DA, ARMENIAN CAPITAL LETTER DA +test(0x0565, 0x0535); // ARMENIAN SMALL LETTER ECH, ARMENIAN CAPITAL LETTER ECH +test(0x0566, 0x0536); // ARMENIAN SMALL LETTER ZA, ARMENIAN CAPITAL LETTER ZA +test(0x0567, 0x0537); // ARMENIAN SMALL LETTER EH, ARMENIAN CAPITAL LETTER EH +test(0x0568, 0x0538); // ARMENIAN SMALL LETTER ET, ARMENIAN CAPITAL LETTER ET +test(0x0569, 0x0539); // ARMENIAN SMALL LETTER TO, ARMENIAN CAPITAL LETTER TO +test(0x056A, 0x053A); // ARMENIAN SMALL LETTER ZHE, ARMENIAN CAPITAL LETTER ZHE +test(0x056B, 0x053B); // ARMENIAN SMALL LETTER INI, ARMENIAN CAPITAL LETTER INI +test(0x056C, 0x053C); // ARMENIAN SMALL LETTER LIWN, ARMENIAN CAPITAL LETTER LIWN +test(0x056D, 0x053D); // ARMENIAN SMALL LETTER XEH, ARMENIAN CAPITAL LETTER XEH +test(0x056E, 0x053E); // ARMENIAN SMALL LETTER CA, ARMENIAN CAPITAL LETTER CA +test(0x056F, 0x053F); // ARMENIAN SMALL LETTER KEN, ARMENIAN CAPITAL LETTER KEN +test(0x0570, 0x0540); // ARMENIAN SMALL LETTER HO, ARMENIAN CAPITAL LETTER HO +test(0x0571, 0x0541); // ARMENIAN SMALL LETTER JA, ARMENIAN CAPITAL LETTER JA +test(0x0572, 0x0542); // ARMENIAN SMALL LETTER GHAD (ARMENIAN SMALL LETTER LAD), ARMENIAN CAPITAL LETTER GHAD (ARMENIAN CAPITAL LETTER LAD) +test(0x0573, 0x0543); // ARMENIAN SMALL LETTER CHEH, ARMENIAN CAPITAL LETTER CHEH +test(0x0574, 0x0544); // ARMENIAN SMALL LETTER MEN, ARMENIAN CAPITAL LETTER MEN +test(0x0575, 0x0545); // ARMENIAN SMALL LETTER YI, ARMENIAN CAPITAL LETTER YI +test(0x0576, 0x0546); // ARMENIAN SMALL LETTER NOW, ARMENIAN CAPITAL LETTER NOW +test(0x0577, 0x0547); // ARMENIAN SMALL LETTER SHA, ARMENIAN CAPITAL LETTER SHA +test(0x0578, 0x0548); // ARMENIAN SMALL LETTER VO, ARMENIAN CAPITAL LETTER VO +test(0x0579, 0x0549); // ARMENIAN SMALL LETTER CHA, ARMENIAN CAPITAL LETTER CHA +test(0x057A, 0x054A); // ARMENIAN SMALL LETTER PEH, ARMENIAN CAPITAL LETTER PEH +test(0x057B, 0x054B); // ARMENIAN SMALL LETTER JHEH, ARMENIAN CAPITAL LETTER JHEH +test(0x057C, 0x054C); // ARMENIAN SMALL LETTER RA, ARMENIAN CAPITAL LETTER RA +test(0x057D, 0x054D); // ARMENIAN SMALL LETTER SEH, ARMENIAN CAPITAL LETTER SEH +test(0x057E, 0x054E); // ARMENIAN SMALL LETTER VEW, ARMENIAN CAPITAL LETTER VEW +test(0x057F, 0x054F); // ARMENIAN SMALL LETTER TIWN, ARMENIAN CAPITAL LETTER TIWN +test(0x0580, 0x0550); // ARMENIAN SMALL LETTER REH, ARMENIAN CAPITAL LETTER REH +test(0x0581, 0x0551); // ARMENIAN SMALL LETTER CO, ARMENIAN CAPITAL LETTER CO +test(0x0582, 0x0552); // ARMENIAN SMALL LETTER YIWN, ARMENIAN CAPITAL LETTER YIWN +test(0x0583, 0x0553); // ARMENIAN SMALL LETTER PIWR, ARMENIAN CAPITAL LETTER PIWR +test(0x0584, 0x0554); // ARMENIAN SMALL LETTER KEH, ARMENIAN CAPITAL LETTER KEH +test(0x0585, 0x0555); // ARMENIAN SMALL LETTER OH, ARMENIAN CAPITAL LETTER OH +test(0x0586, 0x0556); // ARMENIAN SMALL LETTER FEH, ARMENIAN CAPITAL LETTER FEH +test(0x10A0, 0x2D00); // GEORGIAN CAPITAL LETTER AN, GEORGIAN SMALL LETTER AN +test(0x10A1, 0x2D01); // GEORGIAN CAPITAL LETTER BAN, GEORGIAN SMALL LETTER BAN +test(0x10A2, 0x2D02); // GEORGIAN CAPITAL LETTER GAN, GEORGIAN SMALL LETTER GAN +test(0x10A3, 0x2D03); // GEORGIAN CAPITAL LETTER DON, GEORGIAN SMALL LETTER DON +test(0x10A4, 0x2D04); // GEORGIAN CAPITAL LETTER EN, GEORGIAN SMALL LETTER EN +test(0x10A5, 0x2D05); // GEORGIAN CAPITAL LETTER VIN, GEORGIAN SMALL LETTER VIN +test(0x10A6, 0x2D06); // GEORGIAN CAPITAL LETTER ZEN, GEORGIAN SMALL LETTER ZEN +test(0x10A7, 0x2D07); // GEORGIAN CAPITAL LETTER TAN, GEORGIAN SMALL LETTER TAN +test(0x10A8, 0x2D08); // GEORGIAN CAPITAL LETTER IN, GEORGIAN SMALL LETTER IN +test(0x10A9, 0x2D09); // GEORGIAN CAPITAL LETTER KAN, GEORGIAN SMALL LETTER KAN +test(0x10AA, 0x2D0A); // GEORGIAN CAPITAL LETTER LAS, GEORGIAN SMALL LETTER LAS +test(0x10AB, 0x2D0B); // GEORGIAN CAPITAL LETTER MAN, GEORGIAN SMALL LETTER MAN +test(0x10AC, 0x2D0C); // GEORGIAN CAPITAL LETTER NAR, GEORGIAN SMALL LETTER NAR +test(0x10AD, 0x2D0D); // GEORGIAN CAPITAL LETTER ON, GEORGIAN SMALL LETTER ON +test(0x10AE, 0x2D0E); // GEORGIAN CAPITAL LETTER PAR, GEORGIAN SMALL LETTER PAR +test(0x10AF, 0x2D0F); // GEORGIAN CAPITAL LETTER ZHAR, GEORGIAN SMALL LETTER ZHAR +test(0x10B0, 0x2D10); // GEORGIAN CAPITAL LETTER RAE, GEORGIAN SMALL LETTER RAE +test(0x10B1, 0x2D11); // GEORGIAN CAPITAL LETTER SAN, GEORGIAN SMALL LETTER SAN +test(0x10B2, 0x2D12); // GEORGIAN CAPITAL LETTER TAR, GEORGIAN SMALL LETTER TAR +test(0x10B3, 0x2D13); // GEORGIAN CAPITAL LETTER UN, GEORGIAN SMALL LETTER UN +test(0x10B4, 0x2D14); // GEORGIAN CAPITAL LETTER PHAR, GEORGIAN SMALL LETTER PHAR +test(0x10B5, 0x2D15); // GEORGIAN CAPITAL LETTER KHAR, GEORGIAN SMALL LETTER KHAR +test(0x10B6, 0x2D16); // GEORGIAN CAPITAL LETTER GHAN, GEORGIAN SMALL LETTER GHAN +test(0x10B7, 0x2D17); // GEORGIAN CAPITAL LETTER QAR, GEORGIAN SMALL LETTER QAR +test(0x10B8, 0x2D18); // GEORGIAN CAPITAL LETTER SHIN, GEORGIAN SMALL LETTER SHIN +test(0x10B9, 0x2D19); // GEORGIAN CAPITAL LETTER CHIN, GEORGIAN SMALL LETTER CHIN +test(0x10BA, 0x2D1A); // GEORGIAN CAPITAL LETTER CAN, GEORGIAN SMALL LETTER CAN +test(0x10BB, 0x2D1B); // GEORGIAN CAPITAL LETTER JIL, GEORGIAN SMALL LETTER JIL +test(0x10BC, 0x2D1C); // GEORGIAN CAPITAL LETTER CIL, GEORGIAN SMALL LETTER CIL +test(0x10BD, 0x2D1D); // GEORGIAN CAPITAL LETTER CHAR, GEORGIAN SMALL LETTER CHAR +test(0x10BE, 0x2D1E); // GEORGIAN CAPITAL LETTER XAN, GEORGIAN SMALL LETTER XAN +test(0x10BF, 0x2D1F); // GEORGIAN CAPITAL LETTER JHAN, GEORGIAN SMALL LETTER JHAN +test(0x10C0, 0x2D20); // GEORGIAN CAPITAL LETTER HAE, GEORGIAN SMALL LETTER HAE +test(0x10C1, 0x2D21); // GEORGIAN CAPITAL LETTER HE, GEORGIAN SMALL LETTER HE +test(0x10C2, 0x2D22); // GEORGIAN CAPITAL LETTER HIE, GEORGIAN SMALL LETTER HIE +test(0x10C3, 0x2D23); // GEORGIAN CAPITAL LETTER WE, GEORGIAN SMALL LETTER WE +test(0x10C4, 0x2D24); // GEORGIAN CAPITAL LETTER HAR, GEORGIAN SMALL LETTER HAR +test(0x10C5, 0x2D25); // GEORGIAN CAPITAL LETTER HOE, GEORGIAN SMALL LETTER HOE +test(0x10C7, 0x2D27); // GEORGIAN CAPITAL LETTER YN, GEORGIAN SMALL LETTER YN +test(0x10CD, 0x2D2D); // GEORGIAN CAPITAL LETTER AEN, GEORGIAN SMALL LETTER AEN +test(0x10D0, 0x1C90); // GEORGIAN LETTER AN (GEORGIAN SMALL LETTER AN), GEORGIAN MTAVRULI CAPITAL LETTER AN +test(0x10D1, 0x1C91); // GEORGIAN LETTER BAN (GEORGIAN SMALL LETTER BAN), GEORGIAN MTAVRULI CAPITAL LETTER BAN +test(0x10D2, 0x1C92); // GEORGIAN LETTER GAN (GEORGIAN SMALL LETTER GAN), GEORGIAN MTAVRULI CAPITAL LETTER GAN +test(0x10D3, 0x1C93); // GEORGIAN LETTER DON (GEORGIAN SMALL LETTER DON), GEORGIAN MTAVRULI CAPITAL LETTER DON +test(0x10D4, 0x1C94); // GEORGIAN LETTER EN (GEORGIAN SMALL LETTER EN), GEORGIAN MTAVRULI CAPITAL LETTER EN +test(0x10D5, 0x1C95); // GEORGIAN LETTER VIN (GEORGIAN SMALL LETTER VIN), GEORGIAN MTAVRULI CAPITAL LETTER VIN +test(0x10D6, 0x1C96); // GEORGIAN LETTER ZEN (GEORGIAN SMALL LETTER ZEN), GEORGIAN MTAVRULI CAPITAL LETTER ZEN +test(0x10D7, 0x1C97); // GEORGIAN LETTER TAN (GEORGIAN SMALL LETTER TAN), GEORGIAN MTAVRULI CAPITAL LETTER TAN +test(0x10D8, 0x1C98); // GEORGIAN LETTER IN (GEORGIAN SMALL LETTER IN), GEORGIAN MTAVRULI CAPITAL LETTER IN +test(0x10D9, 0x1C99); // GEORGIAN LETTER KAN (GEORGIAN SMALL LETTER KAN), GEORGIAN MTAVRULI CAPITAL LETTER KAN +test(0x10DA, 0x1C9A); // GEORGIAN LETTER LAS (GEORGIAN SMALL LETTER LAS), GEORGIAN MTAVRULI CAPITAL LETTER LAS +test(0x10DB, 0x1C9B); // GEORGIAN LETTER MAN (GEORGIAN SMALL LETTER MAN), GEORGIAN MTAVRULI CAPITAL LETTER MAN +test(0x10DC, 0x1C9C); // GEORGIAN LETTER NAR (GEORGIAN SMALL LETTER NAR), GEORGIAN MTAVRULI CAPITAL LETTER NAR +test(0x10DD, 0x1C9D); // GEORGIAN LETTER ON (GEORGIAN SMALL LETTER ON), GEORGIAN MTAVRULI CAPITAL LETTER ON +test(0x10DE, 0x1C9E); // GEORGIAN LETTER PAR (GEORGIAN SMALL LETTER PAR), GEORGIAN MTAVRULI CAPITAL LETTER PAR +test(0x10DF, 0x1C9F); // GEORGIAN LETTER ZHAR (GEORGIAN SMALL LETTER ZHAR), GEORGIAN MTAVRULI CAPITAL LETTER ZHAR +test(0x10E0, 0x1CA0); // GEORGIAN LETTER RAE (GEORGIAN SMALL LETTER RAE), GEORGIAN MTAVRULI CAPITAL LETTER RAE +test(0x10E1, 0x1CA1); // GEORGIAN LETTER SAN (GEORGIAN SMALL LETTER SAN), GEORGIAN MTAVRULI CAPITAL LETTER SAN +test(0x10E2, 0x1CA2); // GEORGIAN LETTER TAR (GEORGIAN SMALL LETTER TAR), GEORGIAN MTAVRULI CAPITAL LETTER TAR +test(0x10E3, 0x1CA3); // GEORGIAN LETTER UN (GEORGIAN SMALL LETTER UN), GEORGIAN MTAVRULI CAPITAL LETTER UN +test(0x10E4, 0x1CA4); // GEORGIAN LETTER PHAR (GEORGIAN SMALL LETTER PHAR), GEORGIAN MTAVRULI CAPITAL LETTER PHAR +test(0x10E5, 0x1CA5); // GEORGIAN LETTER KHAR (GEORGIAN SMALL LETTER KHAR), GEORGIAN MTAVRULI CAPITAL LETTER KHAR +test(0x10E6, 0x1CA6); // GEORGIAN LETTER GHAN (GEORGIAN SMALL LETTER GHAN), GEORGIAN MTAVRULI CAPITAL LETTER GHAN +test(0x10E7, 0x1CA7); // GEORGIAN LETTER QAR (GEORGIAN SMALL LETTER QAR), GEORGIAN MTAVRULI CAPITAL LETTER QAR +test(0x10E8, 0x1CA8); // GEORGIAN LETTER SHIN (GEORGIAN SMALL LETTER SHIN), GEORGIAN MTAVRULI CAPITAL LETTER SHIN +test(0x10E9, 0x1CA9); // GEORGIAN LETTER CHIN (GEORGIAN SMALL LETTER CHIN), GEORGIAN MTAVRULI CAPITAL LETTER CHIN +test(0x10EA, 0x1CAA); // GEORGIAN LETTER CAN (GEORGIAN SMALL LETTER CAN), GEORGIAN MTAVRULI CAPITAL LETTER CAN +test(0x10EB, 0x1CAB); // GEORGIAN LETTER JIL (GEORGIAN SMALL LETTER JIL), GEORGIAN MTAVRULI CAPITAL LETTER JIL +test(0x10EC, 0x1CAC); // GEORGIAN LETTER CIL (GEORGIAN SMALL LETTER CIL), GEORGIAN MTAVRULI CAPITAL LETTER CIL +test(0x10ED, 0x1CAD); // GEORGIAN LETTER CHAR (GEORGIAN SMALL LETTER CHAR), GEORGIAN MTAVRULI CAPITAL LETTER CHAR +test(0x10EE, 0x1CAE); // GEORGIAN LETTER XAN (GEORGIAN SMALL LETTER XAN), GEORGIAN MTAVRULI CAPITAL LETTER XAN +test(0x10EF, 0x1CAF); // GEORGIAN LETTER JHAN (GEORGIAN SMALL LETTER JHAN), GEORGIAN MTAVRULI CAPITAL LETTER JHAN +test(0x10F0, 0x1CB0); // GEORGIAN LETTER HAE (GEORGIAN SMALL LETTER HAE), GEORGIAN MTAVRULI CAPITAL LETTER HAE +test(0x10F1, 0x1CB1); // GEORGIAN LETTER HE (GEORGIAN SMALL LETTER HE), GEORGIAN MTAVRULI CAPITAL LETTER HE +test(0x10F2, 0x1CB2); // GEORGIAN LETTER HIE (GEORGIAN SMALL LETTER HIE), GEORGIAN MTAVRULI CAPITAL LETTER HIE +test(0x10F3, 0x1CB3); // GEORGIAN LETTER WE (GEORGIAN SMALL LETTER WE), GEORGIAN MTAVRULI CAPITAL LETTER WE +test(0x10F4, 0x1CB4); // GEORGIAN LETTER HAR (GEORGIAN SMALL LETTER HAR), GEORGIAN MTAVRULI CAPITAL LETTER HAR +test(0x10F5, 0x1CB5); // GEORGIAN LETTER HOE (GEORGIAN SMALL LETTER HOE), GEORGIAN MTAVRULI CAPITAL LETTER HOE +test(0x10F6, 0x1CB6); // GEORGIAN LETTER FI (GEORGIAN SMALL LETTER FI), GEORGIAN MTAVRULI CAPITAL LETTER FI +test(0x10F7, 0x1CB7); // GEORGIAN LETTER YN, GEORGIAN MTAVRULI CAPITAL LETTER YN +test(0x10F8, 0x1CB8); // GEORGIAN LETTER ELIFI, GEORGIAN MTAVRULI CAPITAL LETTER ELIFI +test(0x10F9, 0x1CB9); // GEORGIAN LETTER TURNED GAN, GEORGIAN MTAVRULI CAPITAL LETTER TURNED GAN +test(0x10FA, 0x1CBA); // GEORGIAN LETTER AIN, GEORGIAN MTAVRULI CAPITAL LETTER AIN +test(0x10FD, 0x1CBD); // GEORGIAN LETTER AEN, GEORGIAN MTAVRULI CAPITAL LETTER AEN +test(0x10FE, 0x1CBE); // GEORGIAN LETTER HARD SIGN, GEORGIAN MTAVRULI CAPITAL LETTER HARD SIGN +test(0x10FF, 0x1CBF); // GEORGIAN LETTER LABIAL SIGN, GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN +test(0x13A0, 0xAB70); // CHEROKEE LETTER A, CHEROKEE SMALL LETTER A +test(0x13A1, 0xAB71); // CHEROKEE LETTER E, CHEROKEE SMALL LETTER E +test(0x13A2, 0xAB72); // CHEROKEE LETTER I, CHEROKEE SMALL LETTER I +test(0x13A3, 0xAB73); // CHEROKEE LETTER O, CHEROKEE SMALL LETTER O +test(0x13A4, 0xAB74); // CHEROKEE LETTER U, CHEROKEE SMALL LETTER U +test(0x13A5, 0xAB75); // CHEROKEE LETTER V, CHEROKEE SMALL LETTER V +test(0x13A6, 0xAB76); // CHEROKEE LETTER GA, CHEROKEE SMALL LETTER GA +test(0x13A7, 0xAB77); // CHEROKEE LETTER KA, CHEROKEE SMALL LETTER KA +test(0x13A8, 0xAB78); // CHEROKEE LETTER GE, CHEROKEE SMALL LETTER GE +test(0x13A9, 0xAB79); // CHEROKEE LETTER GI, CHEROKEE SMALL LETTER GI +test(0x13AA, 0xAB7A); // CHEROKEE LETTER GO, CHEROKEE SMALL LETTER GO +test(0x13AB, 0xAB7B); // CHEROKEE LETTER GU, CHEROKEE SMALL LETTER GU +test(0x13AC, 0xAB7C); // CHEROKEE LETTER GV, CHEROKEE SMALL LETTER GV +test(0x13AD, 0xAB7D); // CHEROKEE LETTER HA, CHEROKEE SMALL LETTER HA +test(0x13AE, 0xAB7E); // CHEROKEE LETTER HE, CHEROKEE SMALL LETTER HE +test(0x13AF, 0xAB7F); // CHEROKEE LETTER HI, CHEROKEE SMALL LETTER HI +test(0x13B0, 0xAB80); // CHEROKEE LETTER HO, CHEROKEE SMALL LETTER HO +test(0x13B1, 0xAB81); // CHEROKEE LETTER HU, CHEROKEE SMALL LETTER HU +test(0x13B2, 0xAB82); // CHEROKEE LETTER HV, CHEROKEE SMALL LETTER HV +test(0x13B3, 0xAB83); // CHEROKEE LETTER LA, CHEROKEE SMALL LETTER LA +test(0x13B4, 0xAB84); // CHEROKEE LETTER LE, CHEROKEE SMALL LETTER LE +test(0x13B5, 0xAB85); // CHEROKEE LETTER LI, CHEROKEE SMALL LETTER LI +test(0x13B6, 0xAB86); // CHEROKEE LETTER LO, CHEROKEE SMALL LETTER LO +test(0x13B7, 0xAB87); // CHEROKEE LETTER LU, CHEROKEE SMALL LETTER LU +test(0x13B8, 0xAB88); // CHEROKEE LETTER LV, CHEROKEE SMALL LETTER LV +test(0x13B9, 0xAB89); // CHEROKEE LETTER MA, CHEROKEE SMALL LETTER MA +test(0x13BA, 0xAB8A); // CHEROKEE LETTER ME, CHEROKEE SMALL LETTER ME +test(0x13BB, 0xAB8B); // CHEROKEE LETTER MI, CHEROKEE SMALL LETTER MI +test(0x13BC, 0xAB8C); // CHEROKEE LETTER MO, CHEROKEE SMALL LETTER MO +test(0x13BD, 0xAB8D); // CHEROKEE LETTER MU, CHEROKEE SMALL LETTER MU +test(0x13BE, 0xAB8E); // CHEROKEE LETTER NA, CHEROKEE SMALL LETTER NA +test(0x13BF, 0xAB8F); // CHEROKEE LETTER HNA, CHEROKEE SMALL LETTER HNA +test(0x13C0, 0xAB90); // CHEROKEE LETTER NAH, CHEROKEE SMALL LETTER NAH +test(0x13C1, 0xAB91); // CHEROKEE LETTER NE, CHEROKEE SMALL LETTER NE +test(0x13C2, 0xAB92); // CHEROKEE LETTER NI, CHEROKEE SMALL LETTER NI +test(0x13C3, 0xAB93); // CHEROKEE LETTER NO, CHEROKEE SMALL LETTER NO +test(0x13C4, 0xAB94); // CHEROKEE LETTER NU, CHEROKEE SMALL LETTER NU +test(0x13C5, 0xAB95); // CHEROKEE LETTER NV, CHEROKEE SMALL LETTER NV +test(0x13C6, 0xAB96); // CHEROKEE LETTER QUA, CHEROKEE SMALL LETTER QUA +test(0x13C7, 0xAB97); // CHEROKEE LETTER QUE, CHEROKEE SMALL LETTER QUE +test(0x13C8, 0xAB98); // CHEROKEE LETTER QUI, CHEROKEE SMALL LETTER QUI +test(0x13C9, 0xAB99); // CHEROKEE LETTER QUO, CHEROKEE SMALL LETTER QUO +test(0x13CA, 0xAB9A); // CHEROKEE LETTER QUU, CHEROKEE SMALL LETTER QUU +test(0x13CB, 0xAB9B); // CHEROKEE LETTER QUV, CHEROKEE SMALL LETTER QUV +test(0x13CC, 0xAB9C); // CHEROKEE LETTER SA, CHEROKEE SMALL LETTER SA +test(0x13CD, 0xAB9D); // CHEROKEE LETTER S, CHEROKEE SMALL LETTER S +test(0x13CE, 0xAB9E); // CHEROKEE LETTER SE, CHEROKEE SMALL LETTER SE +test(0x13CF, 0xAB9F); // CHEROKEE LETTER SI, CHEROKEE SMALL LETTER SI +test(0x13D0, 0xABA0); // CHEROKEE LETTER SO, CHEROKEE SMALL LETTER SO +test(0x13D1, 0xABA1); // CHEROKEE LETTER SU, CHEROKEE SMALL LETTER SU +test(0x13D2, 0xABA2); // CHEROKEE LETTER SV, CHEROKEE SMALL LETTER SV +test(0x13D3, 0xABA3); // CHEROKEE LETTER DA, CHEROKEE SMALL LETTER DA +test(0x13D4, 0xABA4); // CHEROKEE LETTER TA, CHEROKEE SMALL LETTER TA +test(0x13D5, 0xABA5); // CHEROKEE LETTER DE, CHEROKEE SMALL LETTER DE +test(0x13D6, 0xABA6); // CHEROKEE LETTER TE, CHEROKEE SMALL LETTER TE +test(0x13D7, 0xABA7); // CHEROKEE LETTER DI, CHEROKEE SMALL LETTER DI +test(0x13D8, 0xABA8); // CHEROKEE LETTER TI, CHEROKEE SMALL LETTER TI +test(0x13D9, 0xABA9); // CHEROKEE LETTER DO, CHEROKEE SMALL LETTER DO +test(0x13DA, 0xABAA); // CHEROKEE LETTER DU, CHEROKEE SMALL LETTER DU +test(0x13DB, 0xABAB); // CHEROKEE LETTER DV, CHEROKEE SMALL LETTER DV +test(0x13DC, 0xABAC); // CHEROKEE LETTER DLA, CHEROKEE SMALL LETTER DLA +test(0x13DD, 0xABAD); // CHEROKEE LETTER TLA, CHEROKEE SMALL LETTER TLA +test(0x13DE, 0xABAE); // CHEROKEE LETTER TLE, CHEROKEE SMALL LETTER TLE +test(0x13DF, 0xABAF); // CHEROKEE LETTER TLI, CHEROKEE SMALL LETTER TLI +test(0x13E0, 0xABB0); // CHEROKEE LETTER TLO, CHEROKEE SMALL LETTER TLO +test(0x13E1, 0xABB1); // CHEROKEE LETTER TLU, CHEROKEE SMALL LETTER TLU +test(0x13E2, 0xABB2); // CHEROKEE LETTER TLV, CHEROKEE SMALL LETTER TLV +test(0x13E3, 0xABB3); // CHEROKEE LETTER TSA, CHEROKEE SMALL LETTER TSA +test(0x13E4, 0xABB4); // CHEROKEE LETTER TSE, CHEROKEE SMALL LETTER TSE +test(0x13E5, 0xABB5); // CHEROKEE LETTER TSI, CHEROKEE SMALL LETTER TSI +test(0x13E6, 0xABB6); // CHEROKEE LETTER TSO, CHEROKEE SMALL LETTER TSO +test(0x13E7, 0xABB7); // CHEROKEE LETTER TSU, CHEROKEE SMALL LETTER TSU +test(0x13E8, 0xABB8); // CHEROKEE LETTER TSV, CHEROKEE SMALL LETTER TSV +test(0x13E9, 0xABB9); // CHEROKEE LETTER WA, CHEROKEE SMALL LETTER WA +test(0x13EA, 0xABBA); // CHEROKEE LETTER WE, CHEROKEE SMALL LETTER WE +test(0x13EB, 0xABBB); // CHEROKEE LETTER WI, CHEROKEE SMALL LETTER WI +test(0x13EC, 0xABBC); // CHEROKEE LETTER WO, CHEROKEE SMALL LETTER WO +test(0x13ED, 0xABBD); // CHEROKEE LETTER WU, CHEROKEE SMALL LETTER WU +test(0x13EE, 0xABBE); // CHEROKEE LETTER WV, CHEROKEE SMALL LETTER WV +test(0x13EF, 0xABBF); // CHEROKEE LETTER YA, CHEROKEE SMALL LETTER YA +test(0x13F0, 0x13F8); // CHEROKEE LETTER YE, CHEROKEE SMALL LETTER YE +test(0x13F1, 0x13F9); // CHEROKEE LETTER YI, CHEROKEE SMALL LETTER YI +test(0x13F2, 0x13FA); // CHEROKEE LETTER YO, CHEROKEE SMALL LETTER YO +test(0x13F3, 0x13FB); // CHEROKEE LETTER YU, CHEROKEE SMALL LETTER YU +test(0x13F4, 0x13FC); // CHEROKEE LETTER YV, CHEROKEE SMALL LETTER YV +test(0x13F5, 0x13FD); // CHEROKEE LETTER MV, CHEROKEE SMALL LETTER MV +test(0x13F8, 0x13F0); // CHEROKEE SMALL LETTER YE, CHEROKEE LETTER YE +test(0x13F9, 0x13F1); // CHEROKEE SMALL LETTER YI, CHEROKEE LETTER YI +test(0x13FA, 0x13F2); // CHEROKEE SMALL LETTER YO, CHEROKEE LETTER YO +test(0x13FB, 0x13F3); // CHEROKEE SMALL LETTER YU, CHEROKEE LETTER YU +test(0x13FC, 0x13F4); // CHEROKEE SMALL LETTER YV, CHEROKEE LETTER YV +test(0x13FD, 0x13F5); // CHEROKEE SMALL LETTER MV, CHEROKEE LETTER MV +test(0x1C80, 0x0432, 0x0412); // CYRILLIC SMALL LETTER ROUNDED VE, CYRILLIC SMALL LETTER VE, CYRILLIC CAPITAL LETTER VE +test(0x1C81, 0x0434, 0x0414); // CYRILLIC SMALL LETTER LONG-LEGGED DE, CYRILLIC SMALL LETTER DE, CYRILLIC CAPITAL LETTER DE +test(0x1C82, 0x043E, 0x041E); // CYRILLIC SMALL LETTER NARROW O, CYRILLIC SMALL LETTER O, CYRILLIC CAPITAL LETTER O +test(0x1C83, 0x0441, 0x0421); // CYRILLIC SMALL LETTER WIDE ES, CYRILLIC SMALL LETTER ES, CYRILLIC CAPITAL LETTER ES +test(0x1C84, 0x0442, 0x0422, 0x1C85); // CYRILLIC SMALL LETTER TALL TE, CYRILLIC SMALL LETTER TE, CYRILLIC CAPITAL LETTER TE, CYRILLIC SMALL LETTER THREE-LEGGED TE +test(0x1C85, 0x0442, 0x0422, 0x1C84); // CYRILLIC SMALL LETTER THREE-LEGGED TE, CYRILLIC SMALL LETTER TE, CYRILLIC CAPITAL LETTER TE, CYRILLIC SMALL LETTER TALL TE +test(0x1C86, 0x044A, 0x042A); // CYRILLIC SMALL LETTER TALL HARD SIGN, CYRILLIC SMALL LETTER HARD SIGN, CYRILLIC CAPITAL LETTER HARD SIGN +test(0x1C87, 0x0463, 0x0462); // CYRILLIC SMALL LETTER TALL YAT, CYRILLIC SMALL LETTER YAT, CYRILLIC CAPITAL LETTER YAT +test(0x1C88, 0xA64B, 0xA64A); // CYRILLIC SMALL LETTER UNBLENDED UK, CYRILLIC SMALL LETTER MONOGRAPH UK, CYRILLIC CAPITAL LETTER MONOGRAPH UK +test(0x1C90, 0x10D0); // GEORGIAN MTAVRULI CAPITAL LETTER AN, GEORGIAN LETTER AN (GEORGIAN SMALL LETTER AN) +test(0x1C91, 0x10D1); // GEORGIAN MTAVRULI CAPITAL LETTER BAN, GEORGIAN LETTER BAN (GEORGIAN SMALL LETTER BAN) +test(0x1C92, 0x10D2); // GEORGIAN MTAVRULI CAPITAL LETTER GAN, GEORGIAN LETTER GAN (GEORGIAN SMALL LETTER GAN) +test(0x1C93, 0x10D3); // GEORGIAN MTAVRULI CAPITAL LETTER DON, GEORGIAN LETTER DON (GEORGIAN SMALL LETTER DON) +test(0x1C94, 0x10D4); // GEORGIAN MTAVRULI CAPITAL LETTER EN, GEORGIAN LETTER EN (GEORGIAN SMALL LETTER EN) +test(0x1C95, 0x10D5); // GEORGIAN MTAVRULI CAPITAL LETTER VIN, GEORGIAN LETTER VIN (GEORGIAN SMALL LETTER VIN) +test(0x1C96, 0x10D6); // GEORGIAN MTAVRULI CAPITAL LETTER ZEN, GEORGIAN LETTER ZEN (GEORGIAN SMALL LETTER ZEN) +test(0x1C97, 0x10D7); // GEORGIAN MTAVRULI CAPITAL LETTER TAN, GEORGIAN LETTER TAN (GEORGIAN SMALL LETTER TAN) +test(0x1C98, 0x10D8); // GEORGIAN MTAVRULI CAPITAL LETTER IN, GEORGIAN LETTER IN (GEORGIAN SMALL LETTER IN) +test(0x1C99, 0x10D9); // GEORGIAN MTAVRULI CAPITAL LETTER KAN, GEORGIAN LETTER KAN (GEORGIAN SMALL LETTER KAN) +test(0x1C9A, 0x10DA); // GEORGIAN MTAVRULI CAPITAL LETTER LAS, GEORGIAN LETTER LAS (GEORGIAN SMALL LETTER LAS) +test(0x1C9B, 0x10DB); // GEORGIAN MTAVRULI CAPITAL LETTER MAN, GEORGIAN LETTER MAN (GEORGIAN SMALL LETTER MAN) +test(0x1C9C, 0x10DC); // GEORGIAN MTAVRULI CAPITAL LETTER NAR, GEORGIAN LETTER NAR (GEORGIAN SMALL LETTER NAR) +test(0x1C9D, 0x10DD); // GEORGIAN MTAVRULI CAPITAL LETTER ON, GEORGIAN LETTER ON (GEORGIAN SMALL LETTER ON) +test(0x1C9E, 0x10DE); // GEORGIAN MTAVRULI CAPITAL LETTER PAR, GEORGIAN LETTER PAR (GEORGIAN SMALL LETTER PAR) +test(0x1C9F, 0x10DF); // GEORGIAN MTAVRULI CAPITAL LETTER ZHAR, GEORGIAN LETTER ZHAR (GEORGIAN SMALL LETTER ZHAR) +test(0x1CA0, 0x10E0); // GEORGIAN MTAVRULI CAPITAL LETTER RAE, GEORGIAN LETTER RAE (GEORGIAN SMALL LETTER RAE) +test(0x1CA1, 0x10E1); // GEORGIAN MTAVRULI CAPITAL LETTER SAN, GEORGIAN LETTER SAN (GEORGIAN SMALL LETTER SAN) +test(0x1CA2, 0x10E2); // GEORGIAN MTAVRULI CAPITAL LETTER TAR, GEORGIAN LETTER TAR (GEORGIAN SMALL LETTER TAR) +test(0x1CA3, 0x10E3); // GEORGIAN MTAVRULI CAPITAL LETTER UN, GEORGIAN LETTER UN (GEORGIAN SMALL LETTER UN) +test(0x1CA4, 0x10E4); // GEORGIAN MTAVRULI CAPITAL LETTER PHAR, GEORGIAN LETTER PHAR (GEORGIAN SMALL LETTER PHAR) +test(0x1CA5, 0x10E5); // GEORGIAN MTAVRULI CAPITAL LETTER KHAR, GEORGIAN LETTER KHAR (GEORGIAN SMALL LETTER KHAR) +test(0x1CA6, 0x10E6); // GEORGIAN MTAVRULI CAPITAL LETTER GHAN, GEORGIAN LETTER GHAN (GEORGIAN SMALL LETTER GHAN) +test(0x1CA7, 0x10E7); // GEORGIAN MTAVRULI CAPITAL LETTER QAR, GEORGIAN LETTER QAR (GEORGIAN SMALL LETTER QAR) +test(0x1CA8, 0x10E8); // GEORGIAN MTAVRULI CAPITAL LETTER SHIN, GEORGIAN LETTER SHIN (GEORGIAN SMALL LETTER SHIN) +test(0x1CA9, 0x10E9); // GEORGIAN MTAVRULI CAPITAL LETTER CHIN, GEORGIAN LETTER CHIN (GEORGIAN SMALL LETTER CHIN) +test(0x1CAA, 0x10EA); // GEORGIAN MTAVRULI CAPITAL LETTER CAN, GEORGIAN LETTER CAN (GEORGIAN SMALL LETTER CAN) +test(0x1CAB, 0x10EB); // GEORGIAN MTAVRULI CAPITAL LETTER JIL, GEORGIAN LETTER JIL (GEORGIAN SMALL LETTER JIL) +test(0x1CAC, 0x10EC); // GEORGIAN MTAVRULI CAPITAL LETTER CIL, GEORGIAN LETTER CIL (GEORGIAN SMALL LETTER CIL) +test(0x1CAD, 0x10ED); // GEORGIAN MTAVRULI CAPITAL LETTER CHAR, GEORGIAN LETTER CHAR (GEORGIAN SMALL LETTER CHAR) +test(0x1CAE, 0x10EE); // GEORGIAN MTAVRULI CAPITAL LETTER XAN, GEORGIAN LETTER XAN (GEORGIAN SMALL LETTER XAN) +test(0x1CAF, 0x10EF); // GEORGIAN MTAVRULI CAPITAL LETTER JHAN, GEORGIAN LETTER JHAN (GEORGIAN SMALL LETTER JHAN) +test(0x1CB0, 0x10F0); // GEORGIAN MTAVRULI CAPITAL LETTER HAE, GEORGIAN LETTER HAE (GEORGIAN SMALL LETTER HAE) +test(0x1CB1, 0x10F1); // GEORGIAN MTAVRULI CAPITAL LETTER HE, GEORGIAN LETTER HE (GEORGIAN SMALL LETTER HE) +test(0x1CB2, 0x10F2); // GEORGIAN MTAVRULI CAPITAL LETTER HIE, GEORGIAN LETTER HIE (GEORGIAN SMALL LETTER HIE) +test(0x1CB3, 0x10F3); // GEORGIAN MTAVRULI CAPITAL LETTER WE, GEORGIAN LETTER WE (GEORGIAN SMALL LETTER WE) +test(0x1CB4, 0x10F4); // GEORGIAN MTAVRULI CAPITAL LETTER HAR, GEORGIAN LETTER HAR (GEORGIAN SMALL LETTER HAR) +test(0x1CB5, 0x10F5); // GEORGIAN MTAVRULI CAPITAL LETTER HOE, GEORGIAN LETTER HOE (GEORGIAN SMALL LETTER HOE) +test(0x1CB6, 0x10F6); // GEORGIAN MTAVRULI CAPITAL LETTER FI, GEORGIAN LETTER FI (GEORGIAN SMALL LETTER FI) +test(0x1CB7, 0x10F7); // GEORGIAN MTAVRULI CAPITAL LETTER YN, GEORGIAN LETTER YN +test(0x1CB8, 0x10F8); // GEORGIAN MTAVRULI CAPITAL LETTER ELIFI, GEORGIAN LETTER ELIFI +test(0x1CB9, 0x10F9); // GEORGIAN MTAVRULI CAPITAL LETTER TURNED GAN, GEORGIAN LETTER TURNED GAN +test(0x1CBA, 0x10FA); // GEORGIAN MTAVRULI CAPITAL LETTER AIN, GEORGIAN LETTER AIN +test(0x1CBD, 0x10FD); // GEORGIAN MTAVRULI CAPITAL LETTER AEN, GEORGIAN LETTER AEN +test(0x1CBE, 0x10FE); // GEORGIAN MTAVRULI CAPITAL LETTER HARD SIGN, GEORGIAN LETTER HARD SIGN +test(0x1CBF, 0x10FF); // GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN, GEORGIAN LETTER LABIAL SIGN +test(0x1D79, 0xA77D); // LATIN SMALL LETTER INSULAR G, LATIN CAPITAL LETTER INSULAR G +test(0x1D7D, 0x2C63); // LATIN SMALL LETTER P WITH STROKE, LATIN CAPITAL LETTER P WITH STROKE +test(0x1D8E, 0xA7C6); // LATIN SMALL LETTER Z WITH PALATAL HOOK, LATIN CAPITAL LETTER Z WITH PALATAL HOOK +test(0x1E00, 0x1E01); // LATIN CAPITAL LETTER A WITH RING BELOW, LATIN SMALL LETTER A WITH RING BELOW +test(0x1E01, 0x1E00); // LATIN SMALL LETTER A WITH RING BELOW, LATIN CAPITAL LETTER A WITH RING BELOW +test(0x1E02, 0x1E03); // LATIN CAPITAL LETTER B WITH DOT ABOVE, LATIN SMALL LETTER B WITH DOT ABOVE +test(0x1E03, 0x1E02); // LATIN SMALL LETTER B WITH DOT ABOVE, LATIN CAPITAL LETTER B WITH DOT ABOVE +test(0x1E04, 0x1E05); // LATIN CAPITAL LETTER B WITH DOT BELOW, LATIN SMALL LETTER B WITH DOT BELOW +test(0x1E05, 0x1E04); // LATIN SMALL LETTER B WITH DOT BELOW, LATIN CAPITAL LETTER B WITH DOT BELOW +test(0x1E06, 0x1E07); // LATIN CAPITAL LETTER B WITH LINE BELOW, LATIN SMALL LETTER B WITH LINE BELOW +test(0x1E07, 0x1E06); // LATIN SMALL LETTER B WITH LINE BELOW, LATIN CAPITAL LETTER B WITH LINE BELOW +test(0x1E08, 0x1E09); // LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE, LATIN SMALL LETTER C WITH CEDILLA AND ACUTE +test(0x1E09, 0x1E08); // LATIN SMALL LETTER C WITH CEDILLA AND ACUTE, LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE +test(0x1E0A, 0x1E0B); // LATIN CAPITAL LETTER D WITH DOT ABOVE, LATIN SMALL LETTER D WITH DOT ABOVE +test(0x1E0B, 0x1E0A); // LATIN SMALL LETTER D WITH DOT ABOVE, LATIN CAPITAL LETTER D WITH DOT ABOVE +test(0x1E0C, 0x1E0D); // LATIN CAPITAL LETTER D WITH DOT BELOW, LATIN SMALL LETTER D WITH DOT BELOW +test(0x1E0D, 0x1E0C); // LATIN SMALL LETTER D WITH DOT BELOW, LATIN CAPITAL LETTER D WITH DOT BELOW +test(0x1E0E, 0x1E0F); // LATIN CAPITAL LETTER D WITH LINE BELOW, LATIN SMALL LETTER D WITH LINE BELOW +test(0x1E0F, 0x1E0E); // LATIN SMALL LETTER D WITH LINE BELOW, LATIN CAPITAL LETTER D WITH LINE BELOW +test(0x1E10, 0x1E11); // LATIN CAPITAL LETTER D WITH CEDILLA, LATIN SMALL LETTER D WITH CEDILLA +test(0x1E11, 0x1E10); // LATIN SMALL LETTER D WITH CEDILLA, LATIN CAPITAL LETTER D WITH CEDILLA +test(0x1E12, 0x1E13); // LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW, LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW +test(0x1E13, 0x1E12); // LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW, LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW +test(0x1E14, 0x1E15); // LATIN CAPITAL LETTER E WITH MACRON AND GRAVE, LATIN SMALL LETTER E WITH MACRON AND GRAVE +test(0x1E15, 0x1E14); // LATIN SMALL LETTER E WITH MACRON AND GRAVE, LATIN CAPITAL LETTER E WITH MACRON AND GRAVE +test(0x1E16, 0x1E17); // LATIN CAPITAL LETTER E WITH MACRON AND ACUTE, LATIN SMALL LETTER E WITH MACRON AND ACUTE +test(0x1E17, 0x1E16); // LATIN SMALL LETTER E WITH MACRON AND ACUTE, LATIN CAPITAL LETTER E WITH MACRON AND ACUTE +test(0x1E18, 0x1E19); // LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW, LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW +test(0x1E19, 0x1E18); // LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW, LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW +test(0x1E1A, 0x1E1B); // LATIN CAPITAL LETTER E WITH TILDE BELOW, LATIN SMALL LETTER E WITH TILDE BELOW +test(0x1E1B, 0x1E1A); // LATIN SMALL LETTER E WITH TILDE BELOW, LATIN CAPITAL LETTER E WITH TILDE BELOW +test(0x1E1C, 0x1E1D); // LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE, LATIN SMALL LETTER E WITH CEDILLA AND BREVE +test(0x1E1D, 0x1E1C); // LATIN SMALL LETTER E WITH CEDILLA AND BREVE, LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE +test(0x1E1E, 0x1E1F); // LATIN CAPITAL LETTER F WITH DOT ABOVE, LATIN SMALL LETTER F WITH DOT ABOVE +test(0x1E1F, 0x1E1E); // LATIN SMALL LETTER F WITH DOT ABOVE, LATIN CAPITAL LETTER F WITH DOT ABOVE +test(0x1E20, 0x1E21); // LATIN CAPITAL LETTER G WITH MACRON, LATIN SMALL LETTER G WITH MACRON +test(0x1E21, 0x1E20); // LATIN SMALL LETTER G WITH MACRON, LATIN CAPITAL LETTER G WITH MACRON +test(0x1E22, 0x1E23); // LATIN CAPITAL LETTER H WITH DOT ABOVE, LATIN SMALL LETTER H WITH DOT ABOVE +test(0x1E23, 0x1E22); // LATIN SMALL LETTER H WITH DOT ABOVE, LATIN CAPITAL LETTER H WITH DOT ABOVE +test(0x1E24, 0x1E25); // LATIN CAPITAL LETTER H WITH DOT BELOW, LATIN SMALL LETTER H WITH DOT BELOW +test(0x1E25, 0x1E24); // LATIN SMALL LETTER H WITH DOT BELOW, LATIN CAPITAL LETTER H WITH DOT BELOW +test(0x1E26, 0x1E27); // LATIN CAPITAL LETTER H WITH DIAERESIS, LATIN SMALL LETTER H WITH DIAERESIS +test(0x1E27, 0x1E26); // LATIN SMALL LETTER H WITH DIAERESIS, LATIN CAPITAL LETTER H WITH DIAERESIS +test(0x1E28, 0x1E29); // LATIN CAPITAL LETTER H WITH CEDILLA, LATIN SMALL LETTER H WITH CEDILLA +test(0x1E29, 0x1E28); // LATIN SMALL LETTER H WITH CEDILLA, LATIN CAPITAL LETTER H WITH CEDILLA +test(0x1E2A, 0x1E2B); // LATIN CAPITAL LETTER H WITH BREVE BELOW, LATIN SMALL LETTER H WITH BREVE BELOW +test(0x1E2B, 0x1E2A); // LATIN SMALL LETTER H WITH BREVE BELOW, LATIN CAPITAL LETTER H WITH BREVE BELOW +test(0x1E2C, 0x1E2D); // LATIN CAPITAL LETTER I WITH TILDE BELOW, LATIN SMALL LETTER I WITH TILDE BELOW +test(0x1E2D, 0x1E2C); // LATIN SMALL LETTER I WITH TILDE BELOW, LATIN CAPITAL LETTER I WITH TILDE BELOW +test(0x1E2E, 0x1E2F); // LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE, LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE +test(0x1E2F, 0x1E2E); // LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE, LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE +test(0x1E30, 0x1E31); // LATIN CAPITAL LETTER K WITH ACUTE, LATIN SMALL LETTER K WITH ACUTE +test(0x1E31, 0x1E30); // LATIN SMALL LETTER K WITH ACUTE, LATIN CAPITAL LETTER K WITH ACUTE +test(0x1E32, 0x1E33); // LATIN CAPITAL LETTER K WITH DOT BELOW, LATIN SMALL LETTER K WITH DOT BELOW +test(0x1E33, 0x1E32); // LATIN SMALL LETTER K WITH DOT BELOW, LATIN CAPITAL LETTER K WITH DOT BELOW +test(0x1E34, 0x1E35); // LATIN CAPITAL LETTER K WITH LINE BELOW, LATIN SMALL LETTER K WITH LINE BELOW +test(0x1E35, 0x1E34); // LATIN SMALL LETTER K WITH LINE BELOW, LATIN CAPITAL LETTER K WITH LINE BELOW +test(0x1E36, 0x1E37); // LATIN CAPITAL LETTER L WITH DOT BELOW, LATIN SMALL LETTER L WITH DOT BELOW +test(0x1E37, 0x1E36); // LATIN SMALL LETTER L WITH DOT BELOW, LATIN CAPITAL LETTER L WITH DOT BELOW +test(0x1E38, 0x1E39); // LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON, LATIN SMALL LETTER L WITH DOT BELOW AND MACRON +test(0x1E39, 0x1E38); // LATIN SMALL LETTER L WITH DOT BELOW AND MACRON, LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON +test(0x1E3A, 0x1E3B); // LATIN CAPITAL LETTER L WITH LINE BELOW, LATIN SMALL LETTER L WITH LINE BELOW +test(0x1E3B, 0x1E3A); // LATIN SMALL LETTER L WITH LINE BELOW, LATIN CAPITAL LETTER L WITH LINE BELOW +test(0x1E3C, 0x1E3D); // LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW, LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW +test(0x1E3D, 0x1E3C); // LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW, LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW +test(0x1E3E, 0x1E3F); // LATIN CAPITAL LETTER M WITH ACUTE, LATIN SMALL LETTER M WITH ACUTE +test(0x1E3F, 0x1E3E); // LATIN SMALL LETTER M WITH ACUTE, LATIN CAPITAL LETTER M WITH ACUTE +test(0x1E40, 0x1E41); // LATIN CAPITAL LETTER M WITH DOT ABOVE, LATIN SMALL LETTER M WITH DOT ABOVE +test(0x1E41, 0x1E40); // LATIN SMALL LETTER M WITH DOT ABOVE, LATIN CAPITAL LETTER M WITH DOT ABOVE +test(0x1E42, 0x1E43); // LATIN CAPITAL LETTER M WITH DOT BELOW, LATIN SMALL LETTER M WITH DOT BELOW +test(0x1E43, 0x1E42); // LATIN SMALL LETTER M WITH DOT BELOW, LATIN CAPITAL LETTER M WITH DOT BELOW +test(0x1E44, 0x1E45); // LATIN CAPITAL LETTER N WITH DOT ABOVE, LATIN SMALL LETTER N WITH DOT ABOVE +test(0x1E45, 0x1E44); // LATIN SMALL LETTER N WITH DOT ABOVE, LATIN CAPITAL LETTER N WITH DOT ABOVE +test(0x1E46, 0x1E47); // LATIN CAPITAL LETTER N WITH DOT BELOW, LATIN SMALL LETTER N WITH DOT BELOW +test(0x1E47, 0x1E46); // LATIN SMALL LETTER N WITH DOT BELOW, LATIN CAPITAL LETTER N WITH DOT BELOW +test(0x1E48, 0x1E49); // LATIN CAPITAL LETTER N WITH LINE BELOW, LATIN SMALL LETTER N WITH LINE BELOW +test(0x1E49, 0x1E48); // LATIN SMALL LETTER N WITH LINE BELOW, LATIN CAPITAL LETTER N WITH LINE BELOW +test(0x1E4A, 0x1E4B); // LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW, LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW +test(0x1E4B, 0x1E4A); // LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW, LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW +test(0x1E4C, 0x1E4D); // LATIN CAPITAL LETTER O WITH TILDE AND ACUTE, LATIN SMALL LETTER O WITH TILDE AND ACUTE +test(0x1E4D, 0x1E4C); // LATIN SMALL LETTER O WITH TILDE AND ACUTE, LATIN CAPITAL LETTER O WITH TILDE AND ACUTE +test(0x1E4E, 0x1E4F); // LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS, LATIN SMALL LETTER O WITH TILDE AND DIAERESIS +test(0x1E4F, 0x1E4E); // LATIN SMALL LETTER O WITH TILDE AND DIAERESIS, LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS +test(0x1E50, 0x1E51); // LATIN CAPITAL LETTER O WITH MACRON AND GRAVE, LATIN SMALL LETTER O WITH MACRON AND GRAVE +test(0x1E51, 0x1E50); // LATIN SMALL LETTER O WITH MACRON AND GRAVE, LATIN CAPITAL LETTER O WITH MACRON AND GRAVE +test(0x1E52, 0x1E53); // LATIN CAPITAL LETTER O WITH MACRON AND ACUTE, LATIN SMALL LETTER O WITH MACRON AND ACUTE +test(0x1E53, 0x1E52); // LATIN SMALL LETTER O WITH MACRON AND ACUTE, LATIN CAPITAL LETTER O WITH MACRON AND ACUTE +test(0x1E54, 0x1E55); // LATIN CAPITAL LETTER P WITH ACUTE, LATIN SMALL LETTER P WITH ACUTE +test(0x1E55, 0x1E54); // LATIN SMALL LETTER P WITH ACUTE, LATIN CAPITAL LETTER P WITH ACUTE +test(0x1E56, 0x1E57); // LATIN CAPITAL LETTER P WITH DOT ABOVE, LATIN SMALL LETTER P WITH DOT ABOVE +test(0x1E57, 0x1E56); // LATIN SMALL LETTER P WITH DOT ABOVE, LATIN CAPITAL LETTER P WITH DOT ABOVE +test(0x1E58, 0x1E59); // LATIN CAPITAL LETTER R WITH DOT ABOVE, LATIN SMALL LETTER R WITH DOT ABOVE +test(0x1E59, 0x1E58); // LATIN SMALL LETTER R WITH DOT ABOVE, LATIN CAPITAL LETTER R WITH DOT ABOVE +test(0x1E5A, 0x1E5B); // LATIN CAPITAL LETTER R WITH DOT BELOW, LATIN SMALL LETTER R WITH DOT BELOW +test(0x1E5B, 0x1E5A); // LATIN SMALL LETTER R WITH DOT BELOW, LATIN CAPITAL LETTER R WITH DOT BELOW +test(0x1E5C, 0x1E5D); // LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON, LATIN SMALL LETTER R WITH DOT BELOW AND MACRON +test(0x1E5D, 0x1E5C); // LATIN SMALL LETTER R WITH DOT BELOW AND MACRON, LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON +test(0x1E5E, 0x1E5F); // LATIN CAPITAL LETTER R WITH LINE BELOW, LATIN SMALL LETTER R WITH LINE BELOW +test(0x1E5F, 0x1E5E); // LATIN SMALL LETTER R WITH LINE BELOW, LATIN CAPITAL LETTER R WITH LINE BELOW +test(0x1E60, 0x1E61, 0x1E9B); // LATIN CAPITAL LETTER S WITH DOT ABOVE, LATIN SMALL LETTER S WITH DOT ABOVE, LATIN SMALL LETTER LONG S WITH DOT ABOVE +test(0x1E61, 0x1E60, 0x1E9B); // LATIN SMALL LETTER S WITH DOT ABOVE, LATIN CAPITAL LETTER S WITH DOT ABOVE, LATIN SMALL LETTER LONG S WITH DOT ABOVE +test(0x1E62, 0x1E63); // LATIN CAPITAL LETTER S WITH DOT BELOW, LATIN SMALL LETTER S WITH DOT BELOW +test(0x1E63, 0x1E62); // LATIN SMALL LETTER S WITH DOT BELOW, LATIN CAPITAL LETTER S WITH DOT BELOW +test(0x1E64, 0x1E65); // LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE, LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE +test(0x1E65, 0x1E64); // LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE, LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE +test(0x1E66, 0x1E67); // LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE, LATIN SMALL LETTER S WITH CARON AND DOT ABOVE +test(0x1E67, 0x1E66); // LATIN SMALL LETTER S WITH CARON AND DOT ABOVE, LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE +test(0x1E68, 0x1E69); // LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE, LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE +test(0x1E69, 0x1E68); // LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE, LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE +test(0x1E6A, 0x1E6B); // LATIN CAPITAL LETTER T WITH DOT ABOVE, LATIN SMALL LETTER T WITH DOT ABOVE +test(0x1E6B, 0x1E6A); // LATIN SMALL LETTER T WITH DOT ABOVE, LATIN CAPITAL LETTER T WITH DOT ABOVE +test(0x1E6C, 0x1E6D); // LATIN CAPITAL LETTER T WITH DOT BELOW, LATIN SMALL LETTER T WITH DOT BELOW +test(0x1E6D, 0x1E6C); // LATIN SMALL LETTER T WITH DOT BELOW, LATIN CAPITAL LETTER T WITH DOT BELOW +test(0x1E6E, 0x1E6F); // LATIN CAPITAL LETTER T WITH LINE BELOW, LATIN SMALL LETTER T WITH LINE BELOW +test(0x1E6F, 0x1E6E); // LATIN SMALL LETTER T WITH LINE BELOW, LATIN CAPITAL LETTER T WITH LINE BELOW +test(0x1E70, 0x1E71); // LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW, LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW +test(0x1E71, 0x1E70); // LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW, LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW +test(0x1E72, 0x1E73); // LATIN CAPITAL LETTER U WITH DIAERESIS BELOW, LATIN SMALL LETTER U WITH DIAERESIS BELOW +test(0x1E73, 0x1E72); // LATIN SMALL LETTER U WITH DIAERESIS BELOW, LATIN CAPITAL LETTER U WITH DIAERESIS BELOW +test(0x1E74, 0x1E75); // LATIN CAPITAL LETTER U WITH TILDE BELOW, LATIN SMALL LETTER U WITH TILDE BELOW +test(0x1E75, 0x1E74); // LATIN SMALL LETTER U WITH TILDE BELOW, LATIN CAPITAL LETTER U WITH TILDE BELOW +test(0x1E76, 0x1E77); // LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW, LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW +test(0x1E77, 0x1E76); // LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW, LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW +test(0x1E78, 0x1E79); // LATIN CAPITAL LETTER U WITH TILDE AND ACUTE, LATIN SMALL LETTER U WITH TILDE AND ACUTE +test(0x1E79, 0x1E78); // LATIN SMALL LETTER U WITH TILDE AND ACUTE, LATIN CAPITAL LETTER U WITH TILDE AND ACUTE +test(0x1E7A, 0x1E7B); // LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS, LATIN SMALL LETTER U WITH MACRON AND DIAERESIS +test(0x1E7B, 0x1E7A); // LATIN SMALL LETTER U WITH MACRON AND DIAERESIS, LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS +test(0x1E7C, 0x1E7D); // LATIN CAPITAL LETTER V WITH TILDE, LATIN SMALL LETTER V WITH TILDE +test(0x1E7D, 0x1E7C); // LATIN SMALL LETTER V WITH TILDE, LATIN CAPITAL LETTER V WITH TILDE +test(0x1E7E, 0x1E7F); // LATIN CAPITAL LETTER V WITH DOT BELOW, LATIN SMALL LETTER V WITH DOT BELOW +test(0x1E7F, 0x1E7E); // LATIN SMALL LETTER V WITH DOT BELOW, LATIN CAPITAL LETTER V WITH DOT BELOW +test(0x1E80, 0x1E81); // LATIN CAPITAL LETTER W WITH GRAVE, LATIN SMALL LETTER W WITH GRAVE +test(0x1E81, 0x1E80); // LATIN SMALL LETTER W WITH GRAVE, LATIN CAPITAL LETTER W WITH GRAVE +test(0x1E82, 0x1E83); // LATIN CAPITAL LETTER W WITH ACUTE, LATIN SMALL LETTER W WITH ACUTE +test(0x1E83, 0x1E82); // LATIN SMALL LETTER W WITH ACUTE, LATIN CAPITAL LETTER W WITH ACUTE +test(0x1E84, 0x1E85); // LATIN CAPITAL LETTER W WITH DIAERESIS, LATIN SMALL LETTER W WITH DIAERESIS +test(0x1E85, 0x1E84); // LATIN SMALL LETTER W WITH DIAERESIS, LATIN CAPITAL LETTER W WITH DIAERESIS +test(0x1E86, 0x1E87); // LATIN CAPITAL LETTER W WITH DOT ABOVE, LATIN SMALL LETTER W WITH DOT ABOVE +test(0x1E87, 0x1E86); // LATIN SMALL LETTER W WITH DOT ABOVE, LATIN CAPITAL LETTER W WITH DOT ABOVE +test(0x1E88, 0x1E89); // LATIN CAPITAL LETTER W WITH DOT BELOW, LATIN SMALL LETTER W WITH DOT BELOW +test(0x1E89, 0x1E88); // LATIN SMALL LETTER W WITH DOT BELOW, LATIN CAPITAL LETTER W WITH DOT BELOW +test(0x1E8A, 0x1E8B); // LATIN CAPITAL LETTER X WITH DOT ABOVE, LATIN SMALL LETTER X WITH DOT ABOVE +test(0x1E8B, 0x1E8A); // LATIN SMALL LETTER X WITH DOT ABOVE, LATIN CAPITAL LETTER X WITH DOT ABOVE +test(0x1E8C, 0x1E8D); // LATIN CAPITAL LETTER X WITH DIAERESIS, LATIN SMALL LETTER X WITH DIAERESIS +test(0x1E8D, 0x1E8C); // LATIN SMALL LETTER X WITH DIAERESIS, LATIN CAPITAL LETTER X WITH DIAERESIS +test(0x1E8E, 0x1E8F); // LATIN CAPITAL LETTER Y WITH DOT ABOVE, LATIN SMALL LETTER Y WITH DOT ABOVE +test(0x1E8F, 0x1E8E); // LATIN SMALL LETTER Y WITH DOT ABOVE, LATIN CAPITAL LETTER Y WITH DOT ABOVE +test(0x1E90, 0x1E91); // LATIN CAPITAL LETTER Z WITH CIRCUMFLEX, LATIN SMALL LETTER Z WITH CIRCUMFLEX +test(0x1E91, 0x1E90); // LATIN SMALL LETTER Z WITH CIRCUMFLEX, LATIN CAPITAL LETTER Z WITH CIRCUMFLEX +test(0x1E92, 0x1E93); // LATIN CAPITAL LETTER Z WITH DOT BELOW, LATIN SMALL LETTER Z WITH DOT BELOW +test(0x1E93, 0x1E92); // LATIN SMALL LETTER Z WITH DOT BELOW, LATIN CAPITAL LETTER Z WITH DOT BELOW +test(0x1E94, 0x1E95); // LATIN CAPITAL LETTER Z WITH LINE BELOW, LATIN SMALL LETTER Z WITH LINE BELOW +test(0x1E95, 0x1E94); // LATIN SMALL LETTER Z WITH LINE BELOW, LATIN CAPITAL LETTER Z WITH LINE BELOW +test(0x1E9B, 0x1E61, 0x1E60); // LATIN SMALL LETTER LONG S WITH DOT ABOVE, LATIN SMALL LETTER S WITH DOT ABOVE, LATIN CAPITAL LETTER S WITH DOT ABOVE +test(0x1E9E, 0x00DF); // LATIN CAPITAL LETTER SHARP S, LATIN SMALL LETTER SHARP S +test(0x1EA0, 0x1EA1); // LATIN CAPITAL LETTER A WITH DOT BELOW, LATIN SMALL LETTER A WITH DOT BELOW +test(0x1EA1, 0x1EA0); // LATIN SMALL LETTER A WITH DOT BELOW, LATIN CAPITAL LETTER A WITH DOT BELOW +test(0x1EA2, 0x1EA3); // LATIN CAPITAL LETTER A WITH HOOK ABOVE, LATIN SMALL LETTER A WITH HOOK ABOVE +test(0x1EA3, 0x1EA2); // LATIN SMALL LETTER A WITH HOOK ABOVE, LATIN CAPITAL LETTER A WITH HOOK ABOVE +test(0x1EA4, 0x1EA5); // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE, LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE +test(0x1EA5, 0x1EA4); // LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE, LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE +test(0x1EA6, 0x1EA7); // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE, LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE +test(0x1EA7, 0x1EA6); // LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE, LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE +test(0x1EA8, 0x1EA9); // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE, LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +test(0x1EA9, 0x1EA8); // LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE, LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE +test(0x1EAA, 0x1EAB); // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE, LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE +test(0x1EAB, 0x1EAA); // LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE, LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE +test(0x1EAC, 0x1EAD); // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW, LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW +test(0x1EAD, 0x1EAC); // LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW, LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW +test(0x1EAE, 0x1EAF); // LATIN CAPITAL LETTER A WITH BREVE AND ACUTE, LATIN SMALL LETTER A WITH BREVE AND ACUTE +test(0x1EAF, 0x1EAE); // LATIN SMALL LETTER A WITH BREVE AND ACUTE, LATIN CAPITAL LETTER A WITH BREVE AND ACUTE +test(0x1EB0, 0x1EB1); // LATIN CAPITAL LETTER A WITH BREVE AND GRAVE, LATIN SMALL LETTER A WITH BREVE AND GRAVE +test(0x1EB1, 0x1EB0); // LATIN SMALL LETTER A WITH BREVE AND GRAVE, LATIN CAPITAL LETTER A WITH BREVE AND GRAVE +test(0x1EB2, 0x1EB3); // LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE, LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE +test(0x1EB3, 0x1EB2); // LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE, LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE +test(0x1EB4, 0x1EB5); // LATIN CAPITAL LETTER A WITH BREVE AND TILDE, LATIN SMALL LETTER A WITH BREVE AND TILDE +test(0x1EB5, 0x1EB4); // LATIN SMALL LETTER A WITH BREVE AND TILDE, LATIN CAPITAL LETTER A WITH BREVE AND TILDE +test(0x1EB6, 0x1EB7); // LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW, LATIN SMALL LETTER A WITH BREVE AND DOT BELOW +test(0x1EB7, 0x1EB6); // LATIN SMALL LETTER A WITH BREVE AND DOT BELOW, LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW +test(0x1EB8, 0x1EB9); // LATIN CAPITAL LETTER E WITH DOT BELOW, LATIN SMALL LETTER E WITH DOT BELOW +test(0x1EB9, 0x1EB8); // LATIN SMALL LETTER E WITH DOT BELOW, LATIN CAPITAL LETTER E WITH DOT BELOW +test(0x1EBA, 0x1EBB); // LATIN CAPITAL LETTER E WITH HOOK ABOVE, LATIN SMALL LETTER E WITH HOOK ABOVE +test(0x1EBB, 0x1EBA); // LATIN SMALL LETTER E WITH HOOK ABOVE, LATIN CAPITAL LETTER E WITH HOOK ABOVE +test(0x1EBC, 0x1EBD); // LATIN CAPITAL LETTER E WITH TILDE, LATIN SMALL LETTER E WITH TILDE +test(0x1EBD, 0x1EBC); // LATIN SMALL LETTER E WITH TILDE, LATIN CAPITAL LETTER E WITH TILDE +test(0x1EBE, 0x1EBF); // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE, LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE +test(0x1EBF, 0x1EBE); // LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE, LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE +test(0x1EC0, 0x1EC1); // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE, LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE +test(0x1EC1, 0x1EC0); // LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE, LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE +test(0x1EC2, 0x1EC3); // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE, LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +test(0x1EC3, 0x1EC2); // LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE, LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE +test(0x1EC4, 0x1EC5); // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE, LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE +test(0x1EC5, 0x1EC4); // LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE, LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE +test(0x1EC6, 0x1EC7); // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW, LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW +test(0x1EC7, 0x1EC6); // LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW, LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW +test(0x1EC8, 0x1EC9); // LATIN CAPITAL LETTER I WITH HOOK ABOVE, LATIN SMALL LETTER I WITH HOOK ABOVE +test(0x1EC9, 0x1EC8); // LATIN SMALL LETTER I WITH HOOK ABOVE, LATIN CAPITAL LETTER I WITH HOOK ABOVE +test(0x1ECA, 0x1ECB); // LATIN CAPITAL LETTER I WITH DOT BELOW, LATIN SMALL LETTER I WITH DOT BELOW +test(0x1ECB, 0x1ECA); // LATIN SMALL LETTER I WITH DOT BELOW, LATIN CAPITAL LETTER I WITH DOT BELOW +test(0x1ECC, 0x1ECD); // LATIN CAPITAL LETTER O WITH DOT BELOW, LATIN SMALL LETTER O WITH DOT BELOW +test(0x1ECD, 0x1ECC); // LATIN SMALL LETTER O WITH DOT BELOW, LATIN CAPITAL LETTER O WITH DOT BELOW +test(0x1ECE, 0x1ECF); // LATIN CAPITAL LETTER O WITH HOOK ABOVE, LATIN SMALL LETTER O WITH HOOK ABOVE +test(0x1ECF, 0x1ECE); // LATIN SMALL LETTER O WITH HOOK ABOVE, LATIN CAPITAL LETTER O WITH HOOK ABOVE +test(0x1ED0, 0x1ED1); // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE, LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE +test(0x1ED1, 0x1ED0); // LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE, LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE +test(0x1ED2, 0x1ED3); // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE, LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE +test(0x1ED3, 0x1ED2); // LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE, LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE +test(0x1ED4, 0x1ED5); // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE, LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +test(0x1ED5, 0x1ED4); // LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE, LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE +test(0x1ED6, 0x1ED7); // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE, LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE +test(0x1ED7, 0x1ED6); // LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE, LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE +test(0x1ED8, 0x1ED9); // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW, LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW +test(0x1ED9, 0x1ED8); // LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW, LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW +test(0x1EDA, 0x1EDB); // LATIN CAPITAL LETTER O WITH HORN AND ACUTE, LATIN SMALL LETTER O WITH HORN AND ACUTE +test(0x1EDB, 0x1EDA); // LATIN SMALL LETTER O WITH HORN AND ACUTE, LATIN CAPITAL LETTER O WITH HORN AND ACUTE +test(0x1EDC, 0x1EDD); // LATIN CAPITAL LETTER O WITH HORN AND GRAVE, LATIN SMALL LETTER O WITH HORN AND GRAVE +test(0x1EDD, 0x1EDC); // LATIN SMALL LETTER O WITH HORN AND GRAVE, LATIN CAPITAL LETTER O WITH HORN AND GRAVE +test(0x1EDE, 0x1EDF); // LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE, LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE +test(0x1EDF, 0x1EDE); // LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE, LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE +test(0x1EE0, 0x1EE1); // LATIN CAPITAL LETTER O WITH HORN AND TILDE, LATIN SMALL LETTER O WITH HORN AND TILDE +test(0x1EE1, 0x1EE0); // LATIN SMALL LETTER O WITH HORN AND TILDE, LATIN CAPITAL LETTER O WITH HORN AND TILDE +test(0x1EE2, 0x1EE3); // LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW, LATIN SMALL LETTER O WITH HORN AND DOT BELOW +test(0x1EE3, 0x1EE2); // LATIN SMALL LETTER O WITH HORN AND DOT BELOW, LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW +test(0x1EE4, 0x1EE5); // LATIN CAPITAL LETTER U WITH DOT BELOW, LATIN SMALL LETTER U WITH DOT BELOW +test(0x1EE5, 0x1EE4); // LATIN SMALL LETTER U WITH DOT BELOW, LATIN CAPITAL LETTER U WITH DOT BELOW +test(0x1EE6, 0x1EE7); // LATIN CAPITAL LETTER U WITH HOOK ABOVE, LATIN SMALL LETTER U WITH HOOK ABOVE +test(0x1EE7, 0x1EE6); // LATIN SMALL LETTER U WITH HOOK ABOVE, LATIN CAPITAL LETTER U WITH HOOK ABOVE +test(0x1EE8, 0x1EE9); // LATIN CAPITAL LETTER U WITH HORN AND ACUTE, LATIN SMALL LETTER U WITH HORN AND ACUTE +test(0x1EE9, 0x1EE8); // LATIN SMALL LETTER U WITH HORN AND ACUTE, LATIN CAPITAL LETTER U WITH HORN AND ACUTE +test(0x1EEA, 0x1EEB); // LATIN CAPITAL LETTER U WITH HORN AND GRAVE, LATIN SMALL LETTER U WITH HORN AND GRAVE +test(0x1EEB, 0x1EEA); // LATIN SMALL LETTER U WITH HORN AND GRAVE, LATIN CAPITAL LETTER U WITH HORN AND GRAVE +test(0x1EEC, 0x1EED); // LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE, LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE +test(0x1EED, 0x1EEC); // LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE, LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE +test(0x1EEE, 0x1EEF); // LATIN CAPITAL LETTER U WITH HORN AND TILDE, LATIN SMALL LETTER U WITH HORN AND TILDE +test(0x1EEF, 0x1EEE); // LATIN SMALL LETTER U WITH HORN AND TILDE, LATIN CAPITAL LETTER U WITH HORN AND TILDE +test(0x1EF0, 0x1EF1); // LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW, LATIN SMALL LETTER U WITH HORN AND DOT BELOW +test(0x1EF1, 0x1EF0); // LATIN SMALL LETTER U WITH HORN AND DOT BELOW, LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW +test(0x1EF2, 0x1EF3); // LATIN CAPITAL LETTER Y WITH GRAVE, LATIN SMALL LETTER Y WITH GRAVE +test(0x1EF3, 0x1EF2); // LATIN SMALL LETTER Y WITH GRAVE, LATIN CAPITAL LETTER Y WITH GRAVE +test(0x1EF4, 0x1EF5); // LATIN CAPITAL LETTER Y WITH DOT BELOW, LATIN SMALL LETTER Y WITH DOT BELOW +test(0x1EF5, 0x1EF4); // LATIN SMALL LETTER Y WITH DOT BELOW, LATIN CAPITAL LETTER Y WITH DOT BELOW +test(0x1EF6, 0x1EF7); // LATIN CAPITAL LETTER Y WITH HOOK ABOVE, LATIN SMALL LETTER Y WITH HOOK ABOVE +test(0x1EF7, 0x1EF6); // LATIN SMALL LETTER Y WITH HOOK ABOVE, LATIN CAPITAL LETTER Y WITH HOOK ABOVE +test(0x1EF8, 0x1EF9); // LATIN CAPITAL LETTER Y WITH TILDE, LATIN SMALL LETTER Y WITH TILDE +test(0x1EF9, 0x1EF8); // LATIN SMALL LETTER Y WITH TILDE, LATIN CAPITAL LETTER Y WITH TILDE +test(0x1EFA, 0x1EFB); // LATIN CAPITAL LETTER MIDDLE-WELSH LL, LATIN SMALL LETTER MIDDLE-WELSH LL +test(0x1EFB, 0x1EFA); // LATIN SMALL LETTER MIDDLE-WELSH LL, LATIN CAPITAL LETTER MIDDLE-WELSH LL +test(0x1EFC, 0x1EFD); // LATIN CAPITAL LETTER MIDDLE-WELSH V, LATIN SMALL LETTER MIDDLE-WELSH V +test(0x1EFD, 0x1EFC); // LATIN SMALL LETTER MIDDLE-WELSH V, LATIN CAPITAL LETTER MIDDLE-WELSH V +test(0x1EFE, 0x1EFF); // LATIN CAPITAL LETTER Y WITH LOOP, LATIN SMALL LETTER Y WITH LOOP +test(0x1EFF, 0x1EFE); // LATIN SMALL LETTER Y WITH LOOP, LATIN CAPITAL LETTER Y WITH LOOP +test(0x1F00, 0x1F08); // GREEK SMALL LETTER ALPHA WITH PSILI, GREEK CAPITAL LETTER ALPHA WITH PSILI +test(0x1F01, 0x1F09); // GREEK SMALL LETTER ALPHA WITH DASIA, GREEK CAPITAL LETTER ALPHA WITH DASIA +test(0x1F02, 0x1F0A); // GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA, GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA +test(0x1F03, 0x1F0B); // GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA, GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA +test(0x1F04, 0x1F0C); // GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA, GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA +test(0x1F05, 0x1F0D); // GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA, GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA +test(0x1F06, 0x1F0E); // GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI, GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI +test(0x1F07, 0x1F0F); // GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI, GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI +test(0x1F08, 0x1F00); // GREEK CAPITAL LETTER ALPHA WITH PSILI, GREEK SMALL LETTER ALPHA WITH PSILI +test(0x1F09, 0x1F01); // GREEK CAPITAL LETTER ALPHA WITH DASIA, GREEK SMALL LETTER ALPHA WITH DASIA +test(0x1F0A, 0x1F02); // GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA, GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA +test(0x1F0B, 0x1F03); // GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA, GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA +test(0x1F0C, 0x1F04); // GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA, GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA +test(0x1F0D, 0x1F05); // GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA, GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA +test(0x1F0E, 0x1F06); // GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI, GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI +test(0x1F0F, 0x1F07); // GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI, GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI +test(0x1F10, 0x1F18); // GREEK SMALL LETTER EPSILON WITH PSILI, GREEK CAPITAL LETTER EPSILON WITH PSILI +test(0x1F11, 0x1F19); // GREEK SMALL LETTER EPSILON WITH DASIA, GREEK CAPITAL LETTER EPSILON WITH DASIA +test(0x1F12, 0x1F1A); // GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA, GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA +test(0x1F13, 0x1F1B); // GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA, GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA +test(0x1F14, 0x1F1C); // GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA, GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA +test(0x1F15, 0x1F1D); // GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA, GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA +test(0x1F18, 0x1F10); // GREEK CAPITAL LETTER EPSILON WITH PSILI, GREEK SMALL LETTER EPSILON WITH PSILI +test(0x1F19, 0x1F11); // GREEK CAPITAL LETTER EPSILON WITH DASIA, GREEK SMALL LETTER EPSILON WITH DASIA +test(0x1F1A, 0x1F12); // GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA, GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA +test(0x1F1B, 0x1F13); // GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA, GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA +test(0x1F1C, 0x1F14); // GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA, GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA +test(0x1F1D, 0x1F15); // GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA, GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA +test(0x1F20, 0x1F28); // GREEK SMALL LETTER ETA WITH PSILI, GREEK CAPITAL LETTER ETA WITH PSILI +test(0x1F21, 0x1F29); // GREEK SMALL LETTER ETA WITH DASIA, GREEK CAPITAL LETTER ETA WITH DASIA +test(0x1F22, 0x1F2A); // GREEK SMALL LETTER ETA WITH PSILI AND VARIA, GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA +test(0x1F23, 0x1F2B); // GREEK SMALL LETTER ETA WITH DASIA AND VARIA, GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA +test(0x1F24, 0x1F2C); // GREEK SMALL LETTER ETA WITH PSILI AND OXIA, GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA +test(0x1F25, 0x1F2D); // GREEK SMALL LETTER ETA WITH DASIA AND OXIA, GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA +test(0x1F26, 0x1F2E); // GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI, GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI +test(0x1F27, 0x1F2F); // GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI, GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI +test(0x1F28, 0x1F20); // GREEK CAPITAL LETTER ETA WITH PSILI, GREEK SMALL LETTER ETA WITH PSILI +test(0x1F29, 0x1F21); // GREEK CAPITAL LETTER ETA WITH DASIA, GREEK SMALL LETTER ETA WITH DASIA +test(0x1F2A, 0x1F22); // GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA, GREEK SMALL LETTER ETA WITH PSILI AND VARIA +test(0x1F2B, 0x1F23); // GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA, GREEK SMALL LETTER ETA WITH DASIA AND VARIA +test(0x1F2C, 0x1F24); // GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA, GREEK SMALL LETTER ETA WITH PSILI AND OXIA +test(0x1F2D, 0x1F25); // GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA, GREEK SMALL LETTER ETA WITH DASIA AND OXIA +test(0x1F2E, 0x1F26); // GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI, GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI +test(0x1F2F, 0x1F27); // GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI, GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI +test(0x1F30, 0x1F38); // GREEK SMALL LETTER IOTA WITH PSILI, GREEK CAPITAL LETTER IOTA WITH PSILI +test(0x1F31, 0x1F39); // GREEK SMALL LETTER IOTA WITH DASIA, GREEK CAPITAL LETTER IOTA WITH DASIA +test(0x1F32, 0x1F3A); // GREEK SMALL LETTER IOTA WITH PSILI AND VARIA, GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA +test(0x1F33, 0x1F3B); // GREEK SMALL LETTER IOTA WITH DASIA AND VARIA, GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA +test(0x1F34, 0x1F3C); // GREEK SMALL LETTER IOTA WITH PSILI AND OXIA, GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA +test(0x1F35, 0x1F3D); // GREEK SMALL LETTER IOTA WITH DASIA AND OXIA, GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA +test(0x1F36, 0x1F3E); // GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI, GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI +test(0x1F37, 0x1F3F); // GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI, GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI +test(0x1F38, 0x1F30); // GREEK CAPITAL LETTER IOTA WITH PSILI, GREEK SMALL LETTER IOTA WITH PSILI +test(0x1F39, 0x1F31); // GREEK CAPITAL LETTER IOTA WITH DASIA, GREEK SMALL LETTER IOTA WITH DASIA +test(0x1F3A, 0x1F32); // GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA, GREEK SMALL LETTER IOTA WITH PSILI AND VARIA +test(0x1F3B, 0x1F33); // GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA, GREEK SMALL LETTER IOTA WITH DASIA AND VARIA +test(0x1F3C, 0x1F34); // GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA, GREEK SMALL LETTER IOTA WITH PSILI AND OXIA +test(0x1F3D, 0x1F35); // GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA, GREEK SMALL LETTER IOTA WITH DASIA AND OXIA +test(0x1F3E, 0x1F36); // GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI, GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI +test(0x1F3F, 0x1F37); // GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI, GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI +test(0x1F40, 0x1F48); // GREEK SMALL LETTER OMICRON WITH PSILI, GREEK CAPITAL LETTER OMICRON WITH PSILI +test(0x1F41, 0x1F49); // GREEK SMALL LETTER OMICRON WITH DASIA, GREEK CAPITAL LETTER OMICRON WITH DASIA +test(0x1F42, 0x1F4A); // GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA, GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA +test(0x1F43, 0x1F4B); // GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA, GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA +test(0x1F44, 0x1F4C); // GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA, GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA +test(0x1F45, 0x1F4D); // GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA, GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA +test(0x1F48, 0x1F40); // GREEK CAPITAL LETTER OMICRON WITH PSILI, GREEK SMALL LETTER OMICRON WITH PSILI +test(0x1F49, 0x1F41); // GREEK CAPITAL LETTER OMICRON WITH DASIA, GREEK SMALL LETTER OMICRON WITH DASIA +test(0x1F4A, 0x1F42); // GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA, GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA +test(0x1F4B, 0x1F43); // GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA, GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA +test(0x1F4C, 0x1F44); // GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA, GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA +test(0x1F4D, 0x1F45); // GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA, GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA +test(0x1F51, 0x1F59); // GREEK SMALL LETTER UPSILON WITH DASIA, GREEK CAPITAL LETTER UPSILON WITH DASIA +test(0x1F53, 0x1F5B); // GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA, GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA +test(0x1F55, 0x1F5D); // GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA, GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA +test(0x1F57, 0x1F5F); // GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI, GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI +test(0x1F59, 0x1F51); // GREEK CAPITAL LETTER UPSILON WITH DASIA, GREEK SMALL LETTER UPSILON WITH DASIA +test(0x1F5B, 0x1F53); // GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA, GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA +test(0x1F5D, 0x1F55); // GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA, GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA +test(0x1F5F, 0x1F57); // GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI, GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI +test(0x1F60, 0x1F68); // GREEK SMALL LETTER OMEGA WITH PSILI, GREEK CAPITAL LETTER OMEGA WITH PSILI +test(0x1F61, 0x1F69); // GREEK SMALL LETTER OMEGA WITH DASIA, GREEK CAPITAL LETTER OMEGA WITH DASIA +test(0x1F62, 0x1F6A); // GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA, GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA +test(0x1F63, 0x1F6B); // GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA, GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA +test(0x1F64, 0x1F6C); // GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA, GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA +test(0x1F65, 0x1F6D); // GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA, GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA +test(0x1F66, 0x1F6E); // GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI, GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI +test(0x1F67, 0x1F6F); // GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI, GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI +test(0x1F68, 0x1F60); // GREEK CAPITAL LETTER OMEGA WITH PSILI, GREEK SMALL LETTER OMEGA WITH PSILI +test(0x1F69, 0x1F61); // GREEK CAPITAL LETTER OMEGA WITH DASIA, GREEK SMALL LETTER OMEGA WITH DASIA +test(0x1F6A, 0x1F62); // GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA, GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA +test(0x1F6B, 0x1F63); // GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA, GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA +test(0x1F6C, 0x1F64); // GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA, GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA +test(0x1F6D, 0x1F65); // GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA, GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA +test(0x1F6E, 0x1F66); // GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI, GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI +test(0x1F6F, 0x1F67); // GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI, GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI +test(0x1F70, 0x1FBA); // GREEK SMALL LETTER ALPHA WITH VARIA, GREEK CAPITAL LETTER ALPHA WITH VARIA +test(0x1F71, 0x1FBB); // GREEK SMALL LETTER ALPHA WITH OXIA, GREEK CAPITAL LETTER ALPHA WITH OXIA +test(0x1F72, 0x1FC8); // GREEK SMALL LETTER EPSILON WITH VARIA, GREEK CAPITAL LETTER EPSILON WITH VARIA +test(0x1F73, 0x1FC9); // GREEK SMALL LETTER EPSILON WITH OXIA, GREEK CAPITAL LETTER EPSILON WITH OXIA +test(0x1F74, 0x1FCA); // GREEK SMALL LETTER ETA WITH VARIA, GREEK CAPITAL LETTER ETA WITH VARIA +test(0x1F75, 0x1FCB); // GREEK SMALL LETTER ETA WITH OXIA, GREEK CAPITAL LETTER ETA WITH OXIA +test(0x1F76, 0x1FDA); // GREEK SMALL LETTER IOTA WITH VARIA, GREEK CAPITAL LETTER IOTA WITH VARIA +test(0x1F77, 0x1FDB); // GREEK SMALL LETTER IOTA WITH OXIA, GREEK CAPITAL LETTER IOTA WITH OXIA +test(0x1F78, 0x1FF8); // GREEK SMALL LETTER OMICRON WITH VARIA, GREEK CAPITAL LETTER OMICRON WITH VARIA +test(0x1F79, 0x1FF9); // GREEK SMALL LETTER OMICRON WITH OXIA, GREEK CAPITAL LETTER OMICRON WITH OXIA +test(0x1F7A, 0x1FEA); // GREEK SMALL LETTER UPSILON WITH VARIA, GREEK CAPITAL LETTER UPSILON WITH VARIA +test(0x1F7B, 0x1FEB); // GREEK SMALL LETTER UPSILON WITH OXIA, GREEK CAPITAL LETTER UPSILON WITH OXIA +test(0x1F7C, 0x1FFA); // GREEK SMALL LETTER OMEGA WITH VARIA, GREEK CAPITAL LETTER OMEGA WITH VARIA +test(0x1F7D, 0x1FFB); // GREEK SMALL LETTER OMEGA WITH OXIA, GREEK CAPITAL LETTER OMEGA WITH OXIA +test(0x1F80, 0x1F88); // GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI +test(0x1F81, 0x1F89); // GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI +test(0x1F82, 0x1F8A); // GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI +test(0x1F83, 0x1F8B); // GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI +test(0x1F84, 0x1F8C); // GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI +test(0x1F85, 0x1F8D); // GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI +test(0x1F86, 0x1F8E); // GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +test(0x1F87, 0x1F8F); // GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +test(0x1F88, 0x1F80); // GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI, GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI +test(0x1F89, 0x1F81); // GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI, GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI +test(0x1F8A, 0x1F82); // GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI, GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI +test(0x1F8B, 0x1F83); // GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI, GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI +test(0x1F8C, 0x1F84); // GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI, GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI +test(0x1F8D, 0x1F85); // GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI, GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI +test(0x1F8E, 0x1F86); // GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI, GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +test(0x1F8F, 0x1F87); // GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI, GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +test(0x1F90, 0x1F98); // GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI +test(0x1F91, 0x1F99); // GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI +test(0x1F92, 0x1F9A); // GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI +test(0x1F93, 0x1F9B); // GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI +test(0x1F94, 0x1F9C); // GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI +test(0x1F95, 0x1F9D); // GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI +test(0x1F96, 0x1F9E); // GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +test(0x1F97, 0x1F9F); // GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI, GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +test(0x1F98, 0x1F90); // GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI, GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI +test(0x1F99, 0x1F91); // GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI, GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI +test(0x1F9A, 0x1F92); // GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI, GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI +test(0x1F9B, 0x1F93); // GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI, GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI +test(0x1F9C, 0x1F94); // GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI, GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI +test(0x1F9D, 0x1F95); // GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI, GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI +test(0x1F9E, 0x1F96); // GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI, GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +test(0x1F9F, 0x1F97); // GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI, GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +test(0x1FA0, 0x1FA8); // GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI, GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI +test(0x1FA1, 0x1FA9); // GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI, GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI +test(0x1FA2, 0x1FAA); // GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI, GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI +test(0x1FA3, 0x1FAB); // GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI, GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI +test(0x1FA4, 0x1FAC); // GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI, GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI +test(0x1FA5, 0x1FAD); // GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI, GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI +test(0x1FA6, 0x1FAE); // GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI, GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI +test(0x1FA7, 0x1FAF); // GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI, GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI +test(0x1FA8, 0x1FA0); // GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI, GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI +test(0x1FA9, 0x1FA1); // GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI, GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI +test(0x1FAA, 0x1FA2); // GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI, GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI +test(0x1FAB, 0x1FA3); // GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI, GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI +test(0x1FAC, 0x1FA4); // GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI, GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI +test(0x1FAD, 0x1FA5); // GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI, GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI +test(0x1FAE, 0x1FA6); // GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI, GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI +test(0x1FAF, 0x1FA7); // GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI, GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI +test(0x1FB0, 0x1FB8); // GREEK SMALL LETTER ALPHA WITH VRACHY, GREEK CAPITAL LETTER ALPHA WITH VRACHY +test(0x1FB1, 0x1FB9); // GREEK SMALL LETTER ALPHA WITH MACRON, GREEK CAPITAL LETTER ALPHA WITH MACRON +test(0x1FB3, 0x1FBC); // GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI +test(0x1FB8, 0x1FB0); // GREEK CAPITAL LETTER ALPHA WITH VRACHY, GREEK SMALL LETTER ALPHA WITH VRACHY +test(0x1FB9, 0x1FB1); // GREEK CAPITAL LETTER ALPHA WITH MACRON, GREEK SMALL LETTER ALPHA WITH MACRON +test(0x1FBA, 0x1F70); // GREEK CAPITAL LETTER ALPHA WITH VARIA, GREEK SMALL LETTER ALPHA WITH VARIA +test(0x1FBB, 0x1F71); // GREEK CAPITAL LETTER ALPHA WITH OXIA, GREEK SMALL LETTER ALPHA WITH OXIA +test(0x1FBC, 0x1FB3); // GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI +test(0x1FBE, 0x03B9, 0x0345, 0x0399); // GREEK PROSGEGRAMMENI, GREEK SMALL LETTER IOTA, COMBINING GREEK YPOGEGRAMMENI (GREEK NON-SPACING IOTA BELOW), GREEK CAPITAL LETTER IOTA +test(0x1FC3, 0x1FCC); // GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI +test(0x1FC8, 0x1F72); // GREEK CAPITAL LETTER EPSILON WITH VARIA, GREEK SMALL LETTER EPSILON WITH VARIA +test(0x1FC9, 0x1F73); // GREEK CAPITAL LETTER EPSILON WITH OXIA, GREEK SMALL LETTER EPSILON WITH OXIA +test(0x1FCA, 0x1F74); // GREEK CAPITAL LETTER ETA WITH VARIA, GREEK SMALL LETTER ETA WITH VARIA +test(0x1FCB, 0x1F75); // GREEK CAPITAL LETTER ETA WITH OXIA, GREEK SMALL LETTER ETA WITH OXIA +test(0x1FCC, 0x1FC3); // GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI +test(0x1FD0, 0x1FD8); // GREEK SMALL LETTER IOTA WITH VRACHY, GREEK CAPITAL LETTER IOTA WITH VRACHY +test(0x1FD1, 0x1FD9); // GREEK SMALL LETTER IOTA WITH MACRON, GREEK CAPITAL LETTER IOTA WITH MACRON +test(0x1FD8, 0x1FD0); // GREEK CAPITAL LETTER IOTA WITH VRACHY, GREEK SMALL LETTER IOTA WITH VRACHY +test(0x1FD9, 0x1FD1); // GREEK CAPITAL LETTER IOTA WITH MACRON, GREEK SMALL LETTER IOTA WITH MACRON +test(0x1FDA, 0x1F76); // GREEK CAPITAL LETTER IOTA WITH VARIA, GREEK SMALL LETTER IOTA WITH VARIA +test(0x1FDB, 0x1F77); // GREEK CAPITAL LETTER IOTA WITH OXIA, GREEK SMALL LETTER IOTA WITH OXIA +test(0x1FE0, 0x1FE8); // GREEK SMALL LETTER UPSILON WITH VRACHY, GREEK CAPITAL LETTER UPSILON WITH VRACHY +test(0x1FE1, 0x1FE9); // GREEK SMALL LETTER UPSILON WITH MACRON, GREEK CAPITAL LETTER UPSILON WITH MACRON +test(0x1FE5, 0x1FEC); // GREEK SMALL LETTER RHO WITH DASIA, GREEK CAPITAL LETTER RHO WITH DASIA +test(0x1FE8, 0x1FE0); // GREEK CAPITAL LETTER UPSILON WITH VRACHY, GREEK SMALL LETTER UPSILON WITH VRACHY +test(0x1FE9, 0x1FE1); // GREEK CAPITAL LETTER UPSILON WITH MACRON, GREEK SMALL LETTER UPSILON WITH MACRON +test(0x1FEA, 0x1F7A); // GREEK CAPITAL LETTER UPSILON WITH VARIA, GREEK SMALL LETTER UPSILON WITH VARIA +test(0x1FEB, 0x1F7B); // GREEK CAPITAL LETTER UPSILON WITH OXIA, GREEK SMALL LETTER UPSILON WITH OXIA +test(0x1FEC, 0x1FE5); // GREEK CAPITAL LETTER RHO WITH DASIA, GREEK SMALL LETTER RHO WITH DASIA +test(0x1FF3, 0x1FFC); // GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI +test(0x1FF8, 0x1F78); // GREEK CAPITAL LETTER OMICRON WITH VARIA, GREEK SMALL LETTER OMICRON WITH VARIA +test(0x1FF9, 0x1F79); // GREEK CAPITAL LETTER OMICRON WITH OXIA, GREEK SMALL LETTER OMICRON WITH OXIA +test(0x1FFA, 0x1F7C); // GREEK CAPITAL LETTER OMEGA WITH VARIA, GREEK SMALL LETTER OMEGA WITH VARIA +test(0x1FFB, 0x1F7D); // GREEK CAPITAL LETTER OMEGA WITH OXIA, GREEK SMALL LETTER OMEGA WITH OXIA +test(0x1FFC, 0x1FF3); // GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI +test(0x2126, 0x03C9, 0x03A9); // OHM SIGN (OHM), GREEK SMALL LETTER OMEGA, GREEK CAPITAL LETTER OMEGA +test(0x212A, 0x006B, 0x004B); // KELVIN SIGN (DEGREES KELVIN), LATIN SMALL LETTER K, LATIN CAPITAL LETTER K +test(0x212B, 0x00E5, 0x00C5); // ANGSTROM SIGN (ANGSTROM UNIT), LATIN SMALL LETTER A WITH RING ABOVE (LATIN SMALL LETTER A RING), LATIN CAPITAL LETTER A WITH RING ABOVE (LATIN CAPITAL LETTER A RING) +test(0x2132, 0x214E); // TURNED CAPITAL F (TURNED F), TURNED SMALL F +test(0x214E, 0x2132); // TURNED SMALL F, TURNED CAPITAL F (TURNED F) +test(0x2160, 0x2170); // ROMAN NUMERAL ONE, SMALL ROMAN NUMERAL ONE +test(0x2161, 0x2171); // ROMAN NUMERAL TWO, SMALL ROMAN NUMERAL TWO +test(0x2162, 0x2172); // ROMAN NUMERAL THREE, SMALL ROMAN NUMERAL THREE +test(0x2163, 0x2173); // ROMAN NUMERAL FOUR, SMALL ROMAN NUMERAL FOUR +test(0x2164, 0x2174); // ROMAN NUMERAL FIVE, SMALL ROMAN NUMERAL FIVE +test(0x2165, 0x2175); // ROMAN NUMERAL SIX, SMALL ROMAN NUMERAL SIX +test(0x2166, 0x2176); // ROMAN NUMERAL SEVEN, SMALL ROMAN NUMERAL SEVEN +test(0x2167, 0x2177); // ROMAN NUMERAL EIGHT, SMALL ROMAN NUMERAL EIGHT +test(0x2168, 0x2178); // ROMAN NUMERAL NINE, SMALL ROMAN NUMERAL NINE +test(0x2169, 0x2179); // ROMAN NUMERAL TEN, SMALL ROMAN NUMERAL TEN +test(0x216A, 0x217A); // ROMAN NUMERAL ELEVEN, SMALL ROMAN NUMERAL ELEVEN +test(0x216B, 0x217B); // ROMAN NUMERAL TWELVE, SMALL ROMAN NUMERAL TWELVE +test(0x216C, 0x217C); // ROMAN NUMERAL FIFTY, SMALL ROMAN NUMERAL FIFTY +test(0x216D, 0x217D); // ROMAN NUMERAL ONE HUNDRED, SMALL ROMAN NUMERAL ONE HUNDRED +test(0x216E, 0x217E); // ROMAN NUMERAL FIVE HUNDRED, SMALL ROMAN NUMERAL FIVE HUNDRED +test(0x216F, 0x217F); // ROMAN NUMERAL ONE THOUSAND, SMALL ROMAN NUMERAL ONE THOUSAND +test(0x2170, 0x2160); // SMALL ROMAN NUMERAL ONE, ROMAN NUMERAL ONE +test(0x2171, 0x2161); // SMALL ROMAN NUMERAL TWO, ROMAN NUMERAL TWO +test(0x2172, 0x2162); // SMALL ROMAN NUMERAL THREE, ROMAN NUMERAL THREE +test(0x2173, 0x2163); // SMALL ROMAN NUMERAL FOUR, ROMAN NUMERAL FOUR +test(0x2174, 0x2164); // SMALL ROMAN NUMERAL FIVE, ROMAN NUMERAL FIVE +test(0x2175, 0x2165); // SMALL ROMAN NUMERAL SIX, ROMAN NUMERAL SIX +test(0x2176, 0x2166); // SMALL ROMAN NUMERAL SEVEN, ROMAN NUMERAL SEVEN +test(0x2177, 0x2167); // SMALL ROMAN NUMERAL EIGHT, ROMAN NUMERAL EIGHT +test(0x2178, 0x2168); // SMALL ROMAN NUMERAL NINE, ROMAN NUMERAL NINE +test(0x2179, 0x2169); // SMALL ROMAN NUMERAL TEN, ROMAN NUMERAL TEN +test(0x217A, 0x216A); // SMALL ROMAN NUMERAL ELEVEN, ROMAN NUMERAL ELEVEN +test(0x217B, 0x216B); // SMALL ROMAN NUMERAL TWELVE, ROMAN NUMERAL TWELVE +test(0x217C, 0x216C); // SMALL ROMAN NUMERAL FIFTY, ROMAN NUMERAL FIFTY +test(0x217D, 0x216D); // SMALL ROMAN NUMERAL ONE HUNDRED, ROMAN NUMERAL ONE HUNDRED +test(0x217E, 0x216E); // SMALL ROMAN NUMERAL FIVE HUNDRED, ROMAN NUMERAL FIVE HUNDRED +test(0x217F, 0x216F); // SMALL ROMAN NUMERAL ONE THOUSAND, ROMAN NUMERAL ONE THOUSAND +test(0x2183, 0x2184); // ROMAN NUMERAL REVERSED ONE HUNDRED, LATIN SMALL LETTER REVERSED C +test(0x2184, 0x2183); // LATIN SMALL LETTER REVERSED C, ROMAN NUMERAL REVERSED ONE HUNDRED +test(0x24B6, 0x24D0); // CIRCLED LATIN CAPITAL LETTER A, CIRCLED LATIN SMALL LETTER A +test(0x24B7, 0x24D1); // CIRCLED LATIN CAPITAL LETTER B, CIRCLED LATIN SMALL LETTER B +test(0x24B8, 0x24D2); // CIRCLED LATIN CAPITAL LETTER C, CIRCLED LATIN SMALL LETTER C +test(0x24B9, 0x24D3); // CIRCLED LATIN CAPITAL LETTER D, CIRCLED LATIN SMALL LETTER D +test(0x24BA, 0x24D4); // CIRCLED LATIN CAPITAL LETTER E, CIRCLED LATIN SMALL LETTER E +test(0x24BB, 0x24D5); // CIRCLED LATIN CAPITAL LETTER F, CIRCLED LATIN SMALL LETTER F +test(0x24BC, 0x24D6); // CIRCLED LATIN CAPITAL LETTER G, CIRCLED LATIN SMALL LETTER G +test(0x24BD, 0x24D7); // CIRCLED LATIN CAPITAL LETTER H, CIRCLED LATIN SMALL LETTER H +test(0x24BE, 0x24D8); // CIRCLED LATIN CAPITAL LETTER I, CIRCLED LATIN SMALL LETTER I +test(0x24BF, 0x24D9); // CIRCLED LATIN CAPITAL LETTER J, CIRCLED LATIN SMALL LETTER J +test(0x24C0, 0x24DA); // CIRCLED LATIN CAPITAL LETTER K, CIRCLED LATIN SMALL LETTER K +test(0x24C1, 0x24DB); // CIRCLED LATIN CAPITAL LETTER L, CIRCLED LATIN SMALL LETTER L +test(0x24C2, 0x24DC); // CIRCLED LATIN CAPITAL LETTER M, CIRCLED LATIN SMALL LETTER M +test(0x24C3, 0x24DD); // CIRCLED LATIN CAPITAL LETTER N, CIRCLED LATIN SMALL LETTER N +test(0x24C4, 0x24DE); // CIRCLED LATIN CAPITAL LETTER O, CIRCLED LATIN SMALL LETTER O +test(0x24C5, 0x24DF); // CIRCLED LATIN CAPITAL LETTER P, CIRCLED LATIN SMALL LETTER P +test(0x24C6, 0x24E0); // CIRCLED LATIN CAPITAL LETTER Q, CIRCLED LATIN SMALL LETTER Q +test(0x24C7, 0x24E1); // CIRCLED LATIN CAPITAL LETTER R, CIRCLED LATIN SMALL LETTER R +test(0x24C8, 0x24E2); // CIRCLED LATIN CAPITAL LETTER S, CIRCLED LATIN SMALL LETTER S +test(0x24C9, 0x24E3); // CIRCLED LATIN CAPITAL LETTER T, CIRCLED LATIN SMALL LETTER T +test(0x24CA, 0x24E4); // CIRCLED LATIN CAPITAL LETTER U, CIRCLED LATIN SMALL LETTER U +test(0x24CB, 0x24E5); // CIRCLED LATIN CAPITAL LETTER V, CIRCLED LATIN SMALL LETTER V +test(0x24CC, 0x24E6); // CIRCLED LATIN CAPITAL LETTER W, CIRCLED LATIN SMALL LETTER W +test(0x24CD, 0x24E7); // CIRCLED LATIN CAPITAL LETTER X, CIRCLED LATIN SMALL LETTER X +test(0x24CE, 0x24E8); // CIRCLED LATIN CAPITAL LETTER Y, CIRCLED LATIN SMALL LETTER Y +test(0x24CF, 0x24E9); // CIRCLED LATIN CAPITAL LETTER Z, CIRCLED LATIN SMALL LETTER Z +test(0x24D0, 0x24B6); // CIRCLED LATIN SMALL LETTER A, CIRCLED LATIN CAPITAL LETTER A +test(0x24D1, 0x24B7); // CIRCLED LATIN SMALL LETTER B, CIRCLED LATIN CAPITAL LETTER B +test(0x24D2, 0x24B8); // CIRCLED LATIN SMALL LETTER C, CIRCLED LATIN CAPITAL LETTER C +test(0x24D3, 0x24B9); // CIRCLED LATIN SMALL LETTER D, CIRCLED LATIN CAPITAL LETTER D +test(0x24D4, 0x24BA); // CIRCLED LATIN SMALL LETTER E, CIRCLED LATIN CAPITAL LETTER E +test(0x24D5, 0x24BB); // CIRCLED LATIN SMALL LETTER F, CIRCLED LATIN CAPITAL LETTER F +test(0x24D6, 0x24BC); // CIRCLED LATIN SMALL LETTER G, CIRCLED LATIN CAPITAL LETTER G +test(0x24D7, 0x24BD); // CIRCLED LATIN SMALL LETTER H, CIRCLED LATIN CAPITAL LETTER H +test(0x24D8, 0x24BE); // CIRCLED LATIN SMALL LETTER I, CIRCLED LATIN CAPITAL LETTER I +test(0x24D9, 0x24BF); // CIRCLED LATIN SMALL LETTER J, CIRCLED LATIN CAPITAL LETTER J +test(0x24DA, 0x24C0); // CIRCLED LATIN SMALL LETTER K, CIRCLED LATIN CAPITAL LETTER K +test(0x24DB, 0x24C1); // CIRCLED LATIN SMALL LETTER L, CIRCLED LATIN CAPITAL LETTER L +test(0x24DC, 0x24C2); // CIRCLED LATIN SMALL LETTER M, CIRCLED LATIN CAPITAL LETTER M +test(0x24DD, 0x24C3); // CIRCLED LATIN SMALL LETTER N, CIRCLED LATIN CAPITAL LETTER N +test(0x24DE, 0x24C4); // CIRCLED LATIN SMALL LETTER O, CIRCLED LATIN CAPITAL LETTER O +test(0x24DF, 0x24C5); // CIRCLED LATIN SMALL LETTER P, CIRCLED LATIN CAPITAL LETTER P +test(0x24E0, 0x24C6); // CIRCLED LATIN SMALL LETTER Q, CIRCLED LATIN CAPITAL LETTER Q +test(0x24E1, 0x24C7); // CIRCLED LATIN SMALL LETTER R, CIRCLED LATIN CAPITAL LETTER R +test(0x24E2, 0x24C8); // CIRCLED LATIN SMALL LETTER S, CIRCLED LATIN CAPITAL LETTER S +test(0x24E3, 0x24C9); // CIRCLED LATIN SMALL LETTER T, CIRCLED LATIN CAPITAL LETTER T +test(0x24E4, 0x24CA); // CIRCLED LATIN SMALL LETTER U, CIRCLED LATIN CAPITAL LETTER U +test(0x24E5, 0x24CB); // CIRCLED LATIN SMALL LETTER V, CIRCLED LATIN CAPITAL LETTER V +test(0x24E6, 0x24CC); // CIRCLED LATIN SMALL LETTER W, CIRCLED LATIN CAPITAL LETTER W +test(0x24E7, 0x24CD); // CIRCLED LATIN SMALL LETTER X, CIRCLED LATIN CAPITAL LETTER X +test(0x24E8, 0x24CE); // CIRCLED LATIN SMALL LETTER Y, CIRCLED LATIN CAPITAL LETTER Y +test(0x24E9, 0x24CF); // CIRCLED LATIN SMALL LETTER Z, CIRCLED LATIN CAPITAL LETTER Z +test(0x2C00, 0x2C30); // GLAGOLITIC CAPITAL LETTER AZU, GLAGOLITIC SMALL LETTER AZU +test(0x2C01, 0x2C31); // GLAGOLITIC CAPITAL LETTER BUKY, GLAGOLITIC SMALL LETTER BUKY +test(0x2C02, 0x2C32); // GLAGOLITIC CAPITAL LETTER VEDE, GLAGOLITIC SMALL LETTER VEDE +test(0x2C03, 0x2C33); // GLAGOLITIC CAPITAL LETTER GLAGOLI, GLAGOLITIC SMALL LETTER GLAGOLI +test(0x2C04, 0x2C34); // GLAGOLITIC CAPITAL LETTER DOBRO, GLAGOLITIC SMALL LETTER DOBRO +test(0x2C05, 0x2C35); // GLAGOLITIC CAPITAL LETTER YESTU, GLAGOLITIC SMALL LETTER YESTU +test(0x2C06, 0x2C36); // GLAGOLITIC CAPITAL LETTER ZHIVETE, GLAGOLITIC SMALL LETTER ZHIVETE +test(0x2C07, 0x2C37); // GLAGOLITIC CAPITAL LETTER DZELO, GLAGOLITIC SMALL LETTER DZELO +test(0x2C08, 0x2C38); // GLAGOLITIC CAPITAL LETTER ZEMLJA, GLAGOLITIC SMALL LETTER ZEMLJA +test(0x2C09, 0x2C39); // GLAGOLITIC CAPITAL LETTER IZHE, GLAGOLITIC SMALL LETTER IZHE +test(0x2C0A, 0x2C3A); // GLAGOLITIC CAPITAL LETTER INITIAL IZHE, GLAGOLITIC SMALL LETTER INITIAL IZHE +test(0x2C0B, 0x2C3B); // GLAGOLITIC CAPITAL LETTER I, GLAGOLITIC SMALL LETTER I +test(0x2C0C, 0x2C3C); // GLAGOLITIC CAPITAL LETTER DJERVI, GLAGOLITIC SMALL LETTER DJERVI +test(0x2C0D, 0x2C3D); // GLAGOLITIC CAPITAL LETTER KAKO, GLAGOLITIC SMALL LETTER KAKO +test(0x2C0E, 0x2C3E); // GLAGOLITIC CAPITAL LETTER LJUDIJE, GLAGOLITIC SMALL LETTER LJUDIJE +test(0x2C0F, 0x2C3F); // GLAGOLITIC CAPITAL LETTER MYSLITE, GLAGOLITIC SMALL LETTER MYSLITE +test(0x2C10, 0x2C40); // GLAGOLITIC CAPITAL LETTER NASHI, GLAGOLITIC SMALL LETTER NASHI +test(0x2C11, 0x2C41); // GLAGOLITIC CAPITAL LETTER ONU, GLAGOLITIC SMALL LETTER ONU +test(0x2C12, 0x2C42); // GLAGOLITIC CAPITAL LETTER POKOJI, GLAGOLITIC SMALL LETTER POKOJI +test(0x2C13, 0x2C43); // GLAGOLITIC CAPITAL LETTER RITSI, GLAGOLITIC SMALL LETTER RITSI +test(0x2C14, 0x2C44); // GLAGOLITIC CAPITAL LETTER SLOVO, GLAGOLITIC SMALL LETTER SLOVO +test(0x2C15, 0x2C45); // GLAGOLITIC CAPITAL LETTER TVRIDO, GLAGOLITIC SMALL LETTER TVRIDO +test(0x2C16, 0x2C46); // GLAGOLITIC CAPITAL LETTER UKU, GLAGOLITIC SMALL LETTER UKU +test(0x2C17, 0x2C47); // GLAGOLITIC CAPITAL LETTER FRITU, GLAGOLITIC SMALL LETTER FRITU +test(0x2C18, 0x2C48); // GLAGOLITIC CAPITAL LETTER HERU, GLAGOLITIC SMALL LETTER HERU +test(0x2C19, 0x2C49); // GLAGOLITIC CAPITAL LETTER OTU, GLAGOLITIC SMALL LETTER OTU +test(0x2C1A, 0x2C4A); // GLAGOLITIC CAPITAL LETTER PE, GLAGOLITIC SMALL LETTER PE +test(0x2C1B, 0x2C4B); // GLAGOLITIC CAPITAL LETTER SHTA, GLAGOLITIC SMALL LETTER SHTA +test(0x2C1C, 0x2C4C); // GLAGOLITIC CAPITAL LETTER TSI, GLAGOLITIC SMALL LETTER TSI +test(0x2C1D, 0x2C4D); // GLAGOLITIC CAPITAL LETTER CHRIVI, GLAGOLITIC SMALL LETTER CHRIVI +test(0x2C1E, 0x2C4E); // GLAGOLITIC CAPITAL LETTER SHA, GLAGOLITIC SMALL LETTER SHA +test(0x2C1F, 0x2C4F); // GLAGOLITIC CAPITAL LETTER YERU, GLAGOLITIC SMALL LETTER YERU +test(0x2C20, 0x2C50); // GLAGOLITIC CAPITAL LETTER YERI, GLAGOLITIC SMALL LETTER YERI +test(0x2C21, 0x2C51); // GLAGOLITIC CAPITAL LETTER YATI, GLAGOLITIC SMALL LETTER YATI +test(0x2C22, 0x2C52); // GLAGOLITIC CAPITAL LETTER SPIDERY HA, GLAGOLITIC SMALL LETTER SPIDERY HA +test(0x2C23, 0x2C53); // GLAGOLITIC CAPITAL LETTER YU, GLAGOLITIC SMALL LETTER YU +test(0x2C24, 0x2C54); // GLAGOLITIC CAPITAL LETTER SMALL YUS, GLAGOLITIC SMALL LETTER SMALL YUS +test(0x2C25, 0x2C55); // GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL, GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL +test(0x2C26, 0x2C56); // GLAGOLITIC CAPITAL LETTER YO, GLAGOLITIC SMALL LETTER YO +test(0x2C27, 0x2C57); // GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS, GLAGOLITIC SMALL LETTER IOTATED SMALL YUS +test(0x2C28, 0x2C58); // GLAGOLITIC CAPITAL LETTER BIG YUS, GLAGOLITIC SMALL LETTER BIG YUS +test(0x2C29, 0x2C59); // GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS, GLAGOLITIC SMALL LETTER IOTATED BIG YUS +test(0x2C2A, 0x2C5A); // GLAGOLITIC CAPITAL LETTER FITA, GLAGOLITIC SMALL LETTER FITA +test(0x2C2B, 0x2C5B); // GLAGOLITIC CAPITAL LETTER IZHITSA, GLAGOLITIC SMALL LETTER IZHITSA +test(0x2C2C, 0x2C5C); // GLAGOLITIC CAPITAL LETTER SHTAPIC, GLAGOLITIC SMALL LETTER SHTAPIC +test(0x2C2D, 0x2C5D); // GLAGOLITIC CAPITAL LETTER TROKUTASTI A, GLAGOLITIC SMALL LETTER TROKUTASTI A +test(0x2C2E, 0x2C5E); // GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE, GLAGOLITIC SMALL LETTER LATINATE MYSLITE +test(0x2C2F, 0x2C5F); // GLAGOLITIC CAPITAL LETTER CAUDATE CHRIVI, GLAGOLITIC SMALL LETTER CAUDATE CHRIVI +test(0x2C30, 0x2C00); // GLAGOLITIC SMALL LETTER AZU, GLAGOLITIC CAPITAL LETTER AZU +test(0x2C31, 0x2C01); // GLAGOLITIC SMALL LETTER BUKY, GLAGOLITIC CAPITAL LETTER BUKY +test(0x2C32, 0x2C02); // GLAGOLITIC SMALL LETTER VEDE, GLAGOLITIC CAPITAL LETTER VEDE +test(0x2C33, 0x2C03); // GLAGOLITIC SMALL LETTER GLAGOLI, GLAGOLITIC CAPITAL LETTER GLAGOLI +test(0x2C34, 0x2C04); // GLAGOLITIC SMALL LETTER DOBRO, GLAGOLITIC CAPITAL LETTER DOBRO +test(0x2C35, 0x2C05); // GLAGOLITIC SMALL LETTER YESTU, GLAGOLITIC CAPITAL LETTER YESTU +test(0x2C36, 0x2C06); // GLAGOLITIC SMALL LETTER ZHIVETE, GLAGOLITIC CAPITAL LETTER ZHIVETE +test(0x2C37, 0x2C07); // GLAGOLITIC SMALL LETTER DZELO, GLAGOLITIC CAPITAL LETTER DZELO +test(0x2C38, 0x2C08); // GLAGOLITIC SMALL LETTER ZEMLJA, GLAGOLITIC CAPITAL LETTER ZEMLJA +test(0x2C39, 0x2C09); // GLAGOLITIC SMALL LETTER IZHE, GLAGOLITIC CAPITAL LETTER IZHE +test(0x2C3A, 0x2C0A); // GLAGOLITIC SMALL LETTER INITIAL IZHE, GLAGOLITIC CAPITAL LETTER INITIAL IZHE +test(0x2C3B, 0x2C0B); // GLAGOLITIC SMALL LETTER I, GLAGOLITIC CAPITAL LETTER I +test(0x2C3C, 0x2C0C); // GLAGOLITIC SMALL LETTER DJERVI, GLAGOLITIC CAPITAL LETTER DJERVI +test(0x2C3D, 0x2C0D); // GLAGOLITIC SMALL LETTER KAKO, GLAGOLITIC CAPITAL LETTER KAKO +test(0x2C3E, 0x2C0E); // GLAGOLITIC SMALL LETTER LJUDIJE, GLAGOLITIC CAPITAL LETTER LJUDIJE +test(0x2C3F, 0x2C0F); // GLAGOLITIC SMALL LETTER MYSLITE, GLAGOLITIC CAPITAL LETTER MYSLITE +test(0x2C40, 0x2C10); // GLAGOLITIC SMALL LETTER NASHI, GLAGOLITIC CAPITAL LETTER NASHI +test(0x2C41, 0x2C11); // GLAGOLITIC SMALL LETTER ONU, GLAGOLITIC CAPITAL LETTER ONU +test(0x2C42, 0x2C12); // GLAGOLITIC SMALL LETTER POKOJI, GLAGOLITIC CAPITAL LETTER POKOJI +test(0x2C43, 0x2C13); // GLAGOLITIC SMALL LETTER RITSI, GLAGOLITIC CAPITAL LETTER RITSI +test(0x2C44, 0x2C14); // GLAGOLITIC SMALL LETTER SLOVO, GLAGOLITIC CAPITAL LETTER SLOVO +test(0x2C45, 0x2C15); // GLAGOLITIC SMALL LETTER TVRIDO, GLAGOLITIC CAPITAL LETTER TVRIDO +test(0x2C46, 0x2C16); // GLAGOLITIC SMALL LETTER UKU, GLAGOLITIC CAPITAL LETTER UKU +test(0x2C47, 0x2C17); // GLAGOLITIC SMALL LETTER FRITU, GLAGOLITIC CAPITAL LETTER FRITU +test(0x2C48, 0x2C18); // GLAGOLITIC SMALL LETTER HERU, GLAGOLITIC CAPITAL LETTER HERU +test(0x2C49, 0x2C19); // GLAGOLITIC SMALL LETTER OTU, GLAGOLITIC CAPITAL LETTER OTU +test(0x2C4A, 0x2C1A); // GLAGOLITIC SMALL LETTER PE, GLAGOLITIC CAPITAL LETTER PE +test(0x2C4B, 0x2C1B); // GLAGOLITIC SMALL LETTER SHTA, GLAGOLITIC CAPITAL LETTER SHTA +test(0x2C4C, 0x2C1C); // GLAGOLITIC SMALL LETTER TSI, GLAGOLITIC CAPITAL LETTER TSI +test(0x2C4D, 0x2C1D); // GLAGOLITIC SMALL LETTER CHRIVI, GLAGOLITIC CAPITAL LETTER CHRIVI +test(0x2C4E, 0x2C1E); // GLAGOLITIC SMALL LETTER SHA, GLAGOLITIC CAPITAL LETTER SHA +test(0x2C4F, 0x2C1F); // GLAGOLITIC SMALL LETTER YERU, GLAGOLITIC CAPITAL LETTER YERU +test(0x2C50, 0x2C20); // GLAGOLITIC SMALL LETTER YERI, GLAGOLITIC CAPITAL LETTER YERI +test(0x2C51, 0x2C21); // GLAGOLITIC SMALL LETTER YATI, GLAGOLITIC CAPITAL LETTER YATI +test(0x2C52, 0x2C22); // GLAGOLITIC SMALL LETTER SPIDERY HA, GLAGOLITIC CAPITAL LETTER SPIDERY HA +test(0x2C53, 0x2C23); // GLAGOLITIC SMALL LETTER YU, GLAGOLITIC CAPITAL LETTER YU +test(0x2C54, 0x2C24); // GLAGOLITIC SMALL LETTER SMALL YUS, GLAGOLITIC CAPITAL LETTER SMALL YUS +test(0x2C55, 0x2C25); // GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL, GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL +test(0x2C56, 0x2C26); // GLAGOLITIC SMALL LETTER YO, GLAGOLITIC CAPITAL LETTER YO +test(0x2C57, 0x2C27); // GLAGOLITIC SMALL LETTER IOTATED SMALL YUS, GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS +test(0x2C58, 0x2C28); // GLAGOLITIC SMALL LETTER BIG YUS, GLAGOLITIC CAPITAL LETTER BIG YUS +test(0x2C59, 0x2C29); // GLAGOLITIC SMALL LETTER IOTATED BIG YUS, GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS +test(0x2C5A, 0x2C2A); // GLAGOLITIC SMALL LETTER FITA, GLAGOLITIC CAPITAL LETTER FITA +test(0x2C5B, 0x2C2B); // GLAGOLITIC SMALL LETTER IZHITSA, GLAGOLITIC CAPITAL LETTER IZHITSA +test(0x2C5C, 0x2C2C); // GLAGOLITIC SMALL LETTER SHTAPIC, GLAGOLITIC CAPITAL LETTER SHTAPIC +test(0x2C5D, 0x2C2D); // GLAGOLITIC SMALL LETTER TROKUTASTI A, GLAGOLITIC CAPITAL LETTER TROKUTASTI A +test(0x2C5E, 0x2C2E); // GLAGOLITIC SMALL LETTER LATINATE MYSLITE, GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE +test(0x2C5F, 0x2C2F); // GLAGOLITIC SMALL LETTER CAUDATE CHRIVI, GLAGOLITIC CAPITAL LETTER CAUDATE CHRIVI +test(0x2C60, 0x2C61); // LATIN CAPITAL LETTER L WITH DOUBLE BAR, LATIN SMALL LETTER L WITH DOUBLE BAR +test(0x2C61, 0x2C60); // LATIN SMALL LETTER L WITH DOUBLE BAR, LATIN CAPITAL LETTER L WITH DOUBLE BAR +test(0x2C62, 0x026B); // LATIN CAPITAL LETTER L WITH MIDDLE TILDE, LATIN SMALL LETTER L WITH MIDDLE TILDE +test(0x2C63, 0x1D7D); // LATIN CAPITAL LETTER P WITH STROKE, LATIN SMALL LETTER P WITH STROKE +test(0x2C64, 0x027D); // LATIN CAPITAL LETTER R WITH TAIL, LATIN SMALL LETTER R WITH TAIL (LATIN SMALL LETTER R HOOK) +test(0x2C65, 0x023A); // LATIN SMALL LETTER A WITH STROKE, LATIN CAPITAL LETTER A WITH STROKE +test(0x2C66, 0x023E); // LATIN SMALL LETTER T WITH DIAGONAL STROKE, LATIN CAPITAL LETTER T WITH DIAGONAL STROKE +test(0x2C67, 0x2C68); // LATIN CAPITAL LETTER H WITH DESCENDER, LATIN SMALL LETTER H WITH DESCENDER +test(0x2C68, 0x2C67); // LATIN SMALL LETTER H WITH DESCENDER, LATIN CAPITAL LETTER H WITH DESCENDER +test(0x2C69, 0x2C6A); // LATIN CAPITAL LETTER K WITH DESCENDER, LATIN SMALL LETTER K WITH DESCENDER +test(0x2C6A, 0x2C69); // LATIN SMALL LETTER K WITH DESCENDER, LATIN CAPITAL LETTER K WITH DESCENDER +test(0x2C6B, 0x2C6C); // LATIN CAPITAL LETTER Z WITH DESCENDER, LATIN SMALL LETTER Z WITH DESCENDER +test(0x2C6C, 0x2C6B); // LATIN SMALL LETTER Z WITH DESCENDER, LATIN CAPITAL LETTER Z WITH DESCENDER +test(0x2C6D, 0x0251); // LATIN CAPITAL LETTER ALPHA, LATIN SMALL LETTER ALPHA (LATIN SMALL LETTER SCRIPT A) +test(0x2C6E, 0x0271); // LATIN CAPITAL LETTER M WITH HOOK, LATIN SMALL LETTER M WITH HOOK (LATIN SMALL LETTER M HOOK) +test(0x2C6F, 0x0250); // LATIN CAPITAL LETTER TURNED A, LATIN SMALL LETTER TURNED A +test(0x2C70, 0x0252); // LATIN CAPITAL LETTER TURNED ALPHA, LATIN SMALL LETTER TURNED ALPHA (LATIN SMALL LETTER TURNED SCRIPT A) +test(0x2C72, 0x2C73); // LATIN CAPITAL LETTER W WITH HOOK, LATIN SMALL LETTER W WITH HOOK +test(0x2C73, 0x2C72); // LATIN SMALL LETTER W WITH HOOK, LATIN CAPITAL LETTER W WITH HOOK +test(0x2C75, 0x2C76); // LATIN CAPITAL LETTER HALF H, LATIN SMALL LETTER HALF H +test(0x2C76, 0x2C75); // LATIN SMALL LETTER HALF H, LATIN CAPITAL LETTER HALF H +test(0x2C7E, 0x023F); // LATIN CAPITAL LETTER S WITH SWASH TAIL, LATIN SMALL LETTER S WITH SWASH TAIL +test(0x2C7F, 0x0240); // LATIN CAPITAL LETTER Z WITH SWASH TAIL, LATIN SMALL LETTER Z WITH SWASH TAIL +test(0x2C80, 0x2C81); // COPTIC CAPITAL LETTER ALFA, COPTIC SMALL LETTER ALFA +test(0x2C81, 0x2C80); // COPTIC SMALL LETTER ALFA, COPTIC CAPITAL LETTER ALFA +test(0x2C82, 0x2C83); // COPTIC CAPITAL LETTER VIDA, COPTIC SMALL LETTER VIDA +test(0x2C83, 0x2C82); // COPTIC SMALL LETTER VIDA, COPTIC CAPITAL LETTER VIDA +test(0x2C84, 0x2C85); // COPTIC CAPITAL LETTER GAMMA, COPTIC SMALL LETTER GAMMA +test(0x2C85, 0x2C84); // COPTIC SMALL LETTER GAMMA, COPTIC CAPITAL LETTER GAMMA +test(0x2C86, 0x2C87); // COPTIC CAPITAL LETTER DALDA, COPTIC SMALL LETTER DALDA +test(0x2C87, 0x2C86); // COPTIC SMALL LETTER DALDA, COPTIC CAPITAL LETTER DALDA +test(0x2C88, 0x2C89); // COPTIC CAPITAL LETTER EIE, COPTIC SMALL LETTER EIE +test(0x2C89, 0x2C88); // COPTIC SMALL LETTER EIE, COPTIC CAPITAL LETTER EIE +test(0x2C8A, 0x2C8B); // COPTIC CAPITAL LETTER SOU, COPTIC SMALL LETTER SOU +test(0x2C8B, 0x2C8A); // COPTIC SMALL LETTER SOU, COPTIC CAPITAL LETTER SOU +test(0x2C8C, 0x2C8D); // COPTIC CAPITAL LETTER ZATA, COPTIC SMALL LETTER ZATA +test(0x2C8D, 0x2C8C); // COPTIC SMALL LETTER ZATA, COPTIC CAPITAL LETTER ZATA +test(0x2C8E, 0x2C8F); // COPTIC CAPITAL LETTER HATE, COPTIC SMALL LETTER HATE +test(0x2C8F, 0x2C8E); // COPTIC SMALL LETTER HATE, COPTIC CAPITAL LETTER HATE +test(0x2C90, 0x2C91); // COPTIC CAPITAL LETTER THETHE, COPTIC SMALL LETTER THETHE +test(0x2C91, 0x2C90); // COPTIC SMALL LETTER THETHE, COPTIC CAPITAL LETTER THETHE +test(0x2C92, 0x2C93); // COPTIC CAPITAL LETTER IAUDA, COPTIC SMALL LETTER IAUDA +test(0x2C93, 0x2C92); // COPTIC SMALL LETTER IAUDA, COPTIC CAPITAL LETTER IAUDA +test(0x2C94, 0x2C95); // COPTIC CAPITAL LETTER KAPA, COPTIC SMALL LETTER KAPA +test(0x2C95, 0x2C94); // COPTIC SMALL LETTER KAPA, COPTIC CAPITAL LETTER KAPA +test(0x2C96, 0x2C97); // COPTIC CAPITAL LETTER LAULA, COPTIC SMALL LETTER LAULA +test(0x2C97, 0x2C96); // COPTIC SMALL LETTER LAULA, COPTIC CAPITAL LETTER LAULA +test(0x2C98, 0x2C99); // COPTIC CAPITAL LETTER MI, COPTIC SMALL LETTER MI +test(0x2C99, 0x2C98); // COPTIC SMALL LETTER MI, COPTIC CAPITAL LETTER MI +test(0x2C9A, 0x2C9B); // COPTIC CAPITAL LETTER NI, COPTIC SMALL LETTER NI +test(0x2C9B, 0x2C9A); // COPTIC SMALL LETTER NI, COPTIC CAPITAL LETTER NI +test(0x2C9C, 0x2C9D); // COPTIC CAPITAL LETTER KSI, COPTIC SMALL LETTER KSI +test(0x2C9D, 0x2C9C); // COPTIC SMALL LETTER KSI, COPTIC CAPITAL LETTER KSI +test(0x2C9E, 0x2C9F); // COPTIC CAPITAL LETTER O, COPTIC SMALL LETTER O +test(0x2C9F, 0x2C9E); // COPTIC SMALL LETTER O, COPTIC CAPITAL LETTER O +test(0x2CA0, 0x2CA1); // COPTIC CAPITAL LETTER PI, COPTIC SMALL LETTER PI +test(0x2CA1, 0x2CA0); // COPTIC SMALL LETTER PI, COPTIC CAPITAL LETTER PI +test(0x2CA2, 0x2CA3); // COPTIC CAPITAL LETTER RO, COPTIC SMALL LETTER RO +test(0x2CA3, 0x2CA2); // COPTIC SMALL LETTER RO, COPTIC CAPITAL LETTER RO +test(0x2CA4, 0x2CA5); // COPTIC CAPITAL LETTER SIMA, COPTIC SMALL LETTER SIMA +test(0x2CA5, 0x2CA4); // COPTIC SMALL LETTER SIMA, COPTIC CAPITAL LETTER SIMA +test(0x2CA6, 0x2CA7); // COPTIC CAPITAL LETTER TAU, COPTIC SMALL LETTER TAU +test(0x2CA7, 0x2CA6); // COPTIC SMALL LETTER TAU, COPTIC CAPITAL LETTER TAU +test(0x2CA8, 0x2CA9); // COPTIC CAPITAL LETTER UA, COPTIC SMALL LETTER UA +test(0x2CA9, 0x2CA8); // COPTIC SMALL LETTER UA, COPTIC CAPITAL LETTER UA +test(0x2CAA, 0x2CAB); // COPTIC CAPITAL LETTER FI, COPTIC SMALL LETTER FI +test(0x2CAB, 0x2CAA); // COPTIC SMALL LETTER FI, COPTIC CAPITAL LETTER FI +test(0x2CAC, 0x2CAD); // COPTIC CAPITAL LETTER KHI, COPTIC SMALL LETTER KHI +test(0x2CAD, 0x2CAC); // COPTIC SMALL LETTER KHI, COPTIC CAPITAL LETTER KHI +test(0x2CAE, 0x2CAF); // COPTIC CAPITAL LETTER PSI, COPTIC SMALL LETTER PSI +test(0x2CAF, 0x2CAE); // COPTIC SMALL LETTER PSI, COPTIC CAPITAL LETTER PSI +test(0x2CB0, 0x2CB1); // COPTIC CAPITAL LETTER OOU, COPTIC SMALL LETTER OOU +test(0x2CB1, 0x2CB0); // COPTIC SMALL LETTER OOU, COPTIC CAPITAL LETTER OOU +test(0x2CB2, 0x2CB3); // COPTIC CAPITAL LETTER DIALECT-P ALEF, COPTIC SMALL LETTER DIALECT-P ALEF +test(0x2CB3, 0x2CB2); // COPTIC SMALL LETTER DIALECT-P ALEF, COPTIC CAPITAL LETTER DIALECT-P ALEF +test(0x2CB4, 0x2CB5); // COPTIC CAPITAL LETTER OLD COPTIC AIN, COPTIC SMALL LETTER OLD COPTIC AIN +test(0x2CB5, 0x2CB4); // COPTIC SMALL LETTER OLD COPTIC AIN, COPTIC CAPITAL LETTER OLD COPTIC AIN +test(0x2CB6, 0x2CB7); // COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE, COPTIC SMALL LETTER CRYPTOGRAMMIC EIE +test(0x2CB7, 0x2CB6); // COPTIC SMALL LETTER CRYPTOGRAMMIC EIE, COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE +test(0x2CB8, 0x2CB9); // COPTIC CAPITAL LETTER DIALECT-P KAPA, COPTIC SMALL LETTER DIALECT-P KAPA +test(0x2CB9, 0x2CB8); // COPTIC SMALL LETTER DIALECT-P KAPA, COPTIC CAPITAL LETTER DIALECT-P KAPA +test(0x2CBA, 0x2CBB); // COPTIC CAPITAL LETTER DIALECT-P NI, COPTIC SMALL LETTER DIALECT-P NI +test(0x2CBB, 0x2CBA); // COPTIC SMALL LETTER DIALECT-P NI, COPTIC CAPITAL LETTER DIALECT-P NI +test(0x2CBC, 0x2CBD); // COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI, COPTIC SMALL LETTER CRYPTOGRAMMIC NI +test(0x2CBD, 0x2CBC); // COPTIC SMALL LETTER CRYPTOGRAMMIC NI, COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI +test(0x2CBE, 0x2CBF); // COPTIC CAPITAL LETTER OLD COPTIC OOU, COPTIC SMALL LETTER OLD COPTIC OOU +test(0x2CBF, 0x2CBE); // COPTIC SMALL LETTER OLD COPTIC OOU, COPTIC CAPITAL LETTER OLD COPTIC OOU +test(0x2CC0, 0x2CC1); // COPTIC CAPITAL LETTER SAMPI, COPTIC SMALL LETTER SAMPI +test(0x2CC1, 0x2CC0); // COPTIC SMALL LETTER SAMPI, COPTIC CAPITAL LETTER SAMPI +test(0x2CC2, 0x2CC3); // COPTIC CAPITAL LETTER CROSSED SHEI, COPTIC SMALL LETTER CROSSED SHEI +test(0x2CC3, 0x2CC2); // COPTIC SMALL LETTER CROSSED SHEI, COPTIC CAPITAL LETTER CROSSED SHEI +test(0x2CC4, 0x2CC5); // COPTIC CAPITAL LETTER OLD COPTIC SHEI, COPTIC SMALL LETTER OLD COPTIC SHEI +test(0x2CC5, 0x2CC4); // COPTIC SMALL LETTER OLD COPTIC SHEI, COPTIC CAPITAL LETTER OLD COPTIC SHEI +test(0x2CC6, 0x2CC7); // COPTIC CAPITAL LETTER OLD COPTIC ESH, COPTIC SMALL LETTER OLD COPTIC ESH +test(0x2CC7, 0x2CC6); // COPTIC SMALL LETTER OLD COPTIC ESH, COPTIC CAPITAL LETTER OLD COPTIC ESH +test(0x2CC8, 0x2CC9); // COPTIC CAPITAL LETTER AKHMIMIC KHEI, COPTIC SMALL LETTER AKHMIMIC KHEI +test(0x2CC9, 0x2CC8); // COPTIC SMALL LETTER AKHMIMIC KHEI, COPTIC CAPITAL LETTER AKHMIMIC KHEI +test(0x2CCA, 0x2CCB); // COPTIC CAPITAL LETTER DIALECT-P HORI, COPTIC SMALL LETTER DIALECT-P HORI +test(0x2CCB, 0x2CCA); // COPTIC SMALL LETTER DIALECT-P HORI, COPTIC CAPITAL LETTER DIALECT-P HORI +test(0x2CCC, 0x2CCD); // COPTIC CAPITAL LETTER OLD COPTIC HORI, COPTIC SMALL LETTER OLD COPTIC HORI +test(0x2CCD, 0x2CCC); // COPTIC SMALL LETTER OLD COPTIC HORI, COPTIC CAPITAL LETTER OLD COPTIC HORI +test(0x2CCE, 0x2CCF); // COPTIC CAPITAL LETTER OLD COPTIC HA, COPTIC SMALL LETTER OLD COPTIC HA +test(0x2CCF, 0x2CCE); // COPTIC SMALL LETTER OLD COPTIC HA, COPTIC CAPITAL LETTER OLD COPTIC HA +test(0x2CD0, 0x2CD1); // COPTIC CAPITAL LETTER L-SHAPED HA, COPTIC SMALL LETTER L-SHAPED HA +test(0x2CD1, 0x2CD0); // COPTIC SMALL LETTER L-SHAPED HA, COPTIC CAPITAL LETTER L-SHAPED HA +test(0x2CD2, 0x2CD3); // COPTIC CAPITAL LETTER OLD COPTIC HEI, COPTIC SMALL LETTER OLD COPTIC HEI +test(0x2CD3, 0x2CD2); // COPTIC SMALL LETTER OLD COPTIC HEI, COPTIC CAPITAL LETTER OLD COPTIC HEI +test(0x2CD4, 0x2CD5); // COPTIC CAPITAL LETTER OLD COPTIC HAT, COPTIC SMALL LETTER OLD COPTIC HAT +test(0x2CD5, 0x2CD4); // COPTIC SMALL LETTER OLD COPTIC HAT, COPTIC CAPITAL LETTER OLD COPTIC HAT +test(0x2CD6, 0x2CD7); // COPTIC CAPITAL LETTER OLD COPTIC GANGIA, COPTIC SMALL LETTER OLD COPTIC GANGIA +test(0x2CD7, 0x2CD6); // COPTIC SMALL LETTER OLD COPTIC GANGIA, COPTIC CAPITAL LETTER OLD COPTIC GANGIA +test(0x2CD8, 0x2CD9); // COPTIC CAPITAL LETTER OLD COPTIC DJA, COPTIC SMALL LETTER OLD COPTIC DJA +test(0x2CD9, 0x2CD8); // COPTIC SMALL LETTER OLD COPTIC DJA, COPTIC CAPITAL LETTER OLD COPTIC DJA +test(0x2CDA, 0x2CDB); // COPTIC CAPITAL LETTER OLD COPTIC SHIMA, COPTIC SMALL LETTER OLD COPTIC SHIMA +test(0x2CDB, 0x2CDA); // COPTIC SMALL LETTER OLD COPTIC SHIMA, COPTIC CAPITAL LETTER OLD COPTIC SHIMA +test(0x2CDC, 0x2CDD); // COPTIC CAPITAL LETTER OLD NUBIAN SHIMA, COPTIC SMALL LETTER OLD NUBIAN SHIMA +test(0x2CDD, 0x2CDC); // COPTIC SMALL LETTER OLD NUBIAN SHIMA, COPTIC CAPITAL LETTER OLD NUBIAN SHIMA +test(0x2CDE, 0x2CDF); // COPTIC CAPITAL LETTER OLD NUBIAN NGI, COPTIC SMALL LETTER OLD NUBIAN NGI +test(0x2CDF, 0x2CDE); // COPTIC SMALL LETTER OLD NUBIAN NGI, COPTIC CAPITAL LETTER OLD NUBIAN NGI +test(0x2CE0, 0x2CE1); // COPTIC CAPITAL LETTER OLD NUBIAN NYI, COPTIC SMALL LETTER OLD NUBIAN NYI +test(0x2CE1, 0x2CE0); // COPTIC SMALL LETTER OLD NUBIAN NYI, COPTIC CAPITAL LETTER OLD NUBIAN NYI +test(0x2CE2, 0x2CE3); // COPTIC CAPITAL LETTER OLD NUBIAN WAU, COPTIC SMALL LETTER OLD NUBIAN WAU +test(0x2CE3, 0x2CE2); // COPTIC SMALL LETTER OLD NUBIAN WAU, COPTIC CAPITAL LETTER OLD NUBIAN WAU +test(0x2CEB, 0x2CEC); // COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI, COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI +test(0x2CEC, 0x2CEB); // COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI, COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI +test(0x2CED, 0x2CEE); // COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA, COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA +test(0x2CEE, 0x2CED); // COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA, COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA +test(0x2CF2, 0x2CF3); // COPTIC CAPITAL LETTER BOHAIRIC KHEI, COPTIC SMALL LETTER BOHAIRIC KHEI +test(0x2CF3, 0x2CF2); // COPTIC SMALL LETTER BOHAIRIC KHEI, COPTIC CAPITAL LETTER BOHAIRIC KHEI +test(0x2D00, 0x10A0); // GEORGIAN SMALL LETTER AN, GEORGIAN CAPITAL LETTER AN +test(0x2D01, 0x10A1); // GEORGIAN SMALL LETTER BAN, GEORGIAN CAPITAL LETTER BAN +test(0x2D02, 0x10A2); // GEORGIAN SMALL LETTER GAN, GEORGIAN CAPITAL LETTER GAN +test(0x2D03, 0x10A3); // GEORGIAN SMALL LETTER DON, GEORGIAN CAPITAL LETTER DON +test(0x2D04, 0x10A4); // GEORGIAN SMALL LETTER EN, GEORGIAN CAPITAL LETTER EN +test(0x2D05, 0x10A5); // GEORGIAN SMALL LETTER VIN, GEORGIAN CAPITAL LETTER VIN +test(0x2D06, 0x10A6); // GEORGIAN SMALL LETTER ZEN, GEORGIAN CAPITAL LETTER ZEN +test(0x2D07, 0x10A7); // GEORGIAN SMALL LETTER TAN, GEORGIAN CAPITAL LETTER TAN +test(0x2D08, 0x10A8); // GEORGIAN SMALL LETTER IN, GEORGIAN CAPITAL LETTER IN +test(0x2D09, 0x10A9); // GEORGIAN SMALL LETTER KAN, GEORGIAN CAPITAL LETTER KAN +test(0x2D0A, 0x10AA); // GEORGIAN SMALL LETTER LAS, GEORGIAN CAPITAL LETTER LAS +test(0x2D0B, 0x10AB); // GEORGIAN SMALL LETTER MAN, GEORGIAN CAPITAL LETTER MAN +test(0x2D0C, 0x10AC); // GEORGIAN SMALL LETTER NAR, GEORGIAN CAPITAL LETTER NAR +test(0x2D0D, 0x10AD); // GEORGIAN SMALL LETTER ON, GEORGIAN CAPITAL LETTER ON +test(0x2D0E, 0x10AE); // GEORGIAN SMALL LETTER PAR, GEORGIAN CAPITAL LETTER PAR +test(0x2D0F, 0x10AF); // GEORGIAN SMALL LETTER ZHAR, GEORGIAN CAPITAL LETTER ZHAR +test(0x2D10, 0x10B0); // GEORGIAN SMALL LETTER RAE, GEORGIAN CAPITAL LETTER RAE +test(0x2D11, 0x10B1); // GEORGIAN SMALL LETTER SAN, GEORGIAN CAPITAL LETTER SAN +test(0x2D12, 0x10B2); // GEORGIAN SMALL LETTER TAR, GEORGIAN CAPITAL LETTER TAR +test(0x2D13, 0x10B3); // GEORGIAN SMALL LETTER UN, GEORGIAN CAPITAL LETTER UN +test(0x2D14, 0x10B4); // GEORGIAN SMALL LETTER PHAR, GEORGIAN CAPITAL LETTER PHAR +test(0x2D15, 0x10B5); // GEORGIAN SMALL LETTER KHAR, GEORGIAN CAPITAL LETTER KHAR +test(0x2D16, 0x10B6); // GEORGIAN SMALL LETTER GHAN, GEORGIAN CAPITAL LETTER GHAN +test(0x2D17, 0x10B7); // GEORGIAN SMALL LETTER QAR, GEORGIAN CAPITAL LETTER QAR +test(0x2D18, 0x10B8); // GEORGIAN SMALL LETTER SHIN, GEORGIAN CAPITAL LETTER SHIN +test(0x2D19, 0x10B9); // GEORGIAN SMALL LETTER CHIN, GEORGIAN CAPITAL LETTER CHIN +test(0x2D1A, 0x10BA); // GEORGIAN SMALL LETTER CAN, GEORGIAN CAPITAL LETTER CAN +test(0x2D1B, 0x10BB); // GEORGIAN SMALL LETTER JIL, GEORGIAN CAPITAL LETTER JIL +test(0x2D1C, 0x10BC); // GEORGIAN SMALL LETTER CIL, GEORGIAN CAPITAL LETTER CIL +test(0x2D1D, 0x10BD); // GEORGIAN SMALL LETTER CHAR, GEORGIAN CAPITAL LETTER CHAR +test(0x2D1E, 0x10BE); // GEORGIAN SMALL LETTER XAN, GEORGIAN CAPITAL LETTER XAN +test(0x2D1F, 0x10BF); // GEORGIAN SMALL LETTER JHAN, GEORGIAN CAPITAL LETTER JHAN +test(0x2D20, 0x10C0); // GEORGIAN SMALL LETTER HAE, GEORGIAN CAPITAL LETTER HAE +test(0x2D21, 0x10C1); // GEORGIAN SMALL LETTER HE, GEORGIAN CAPITAL LETTER HE +test(0x2D22, 0x10C2); // GEORGIAN SMALL LETTER HIE, GEORGIAN CAPITAL LETTER HIE +test(0x2D23, 0x10C3); // GEORGIAN SMALL LETTER WE, GEORGIAN CAPITAL LETTER WE +test(0x2D24, 0x10C4); // GEORGIAN SMALL LETTER HAR, GEORGIAN CAPITAL LETTER HAR +test(0x2D25, 0x10C5); // GEORGIAN SMALL LETTER HOE, GEORGIAN CAPITAL LETTER HOE +test(0x2D27, 0x10C7); // GEORGIAN SMALL LETTER YN, GEORGIAN CAPITAL LETTER YN +test(0x2D2D, 0x10CD); // GEORGIAN SMALL LETTER AEN, GEORGIAN CAPITAL LETTER AEN +test(0xA640, 0xA641); // CYRILLIC CAPITAL LETTER ZEMLYA, CYRILLIC SMALL LETTER ZEMLYA +test(0xA641, 0xA640); // CYRILLIC SMALL LETTER ZEMLYA, CYRILLIC CAPITAL LETTER ZEMLYA +test(0xA642, 0xA643); // CYRILLIC CAPITAL LETTER DZELO, CYRILLIC SMALL LETTER DZELO +test(0xA643, 0xA642); // CYRILLIC SMALL LETTER DZELO, CYRILLIC CAPITAL LETTER DZELO +test(0xA644, 0xA645); // CYRILLIC CAPITAL LETTER REVERSED DZE, CYRILLIC SMALL LETTER REVERSED DZE +test(0xA645, 0xA644); // CYRILLIC SMALL LETTER REVERSED DZE, CYRILLIC CAPITAL LETTER REVERSED DZE +test(0xA646, 0xA647); // CYRILLIC CAPITAL LETTER IOTA, CYRILLIC SMALL LETTER IOTA +test(0xA647, 0xA646); // CYRILLIC SMALL LETTER IOTA, CYRILLIC CAPITAL LETTER IOTA +test(0xA648, 0xA649); // CYRILLIC CAPITAL LETTER DJERV, CYRILLIC SMALL LETTER DJERV +test(0xA649, 0xA648); // CYRILLIC SMALL LETTER DJERV, CYRILLIC CAPITAL LETTER DJERV +test(0xA64A, 0xA64B, 0x1C88); // CYRILLIC CAPITAL LETTER MONOGRAPH UK, CYRILLIC SMALL LETTER MONOGRAPH UK, CYRILLIC SMALL LETTER UNBLENDED UK +test(0xA64B, 0x1C88, 0xA64A); // CYRILLIC SMALL LETTER MONOGRAPH UK, CYRILLIC SMALL LETTER UNBLENDED UK, CYRILLIC CAPITAL LETTER MONOGRAPH UK +test(0xA64C, 0xA64D); // CYRILLIC CAPITAL LETTER BROAD OMEGA, CYRILLIC SMALL LETTER BROAD OMEGA +test(0xA64D, 0xA64C); // CYRILLIC SMALL LETTER BROAD OMEGA, CYRILLIC CAPITAL LETTER BROAD OMEGA +test(0xA64E, 0xA64F); // CYRILLIC CAPITAL LETTER NEUTRAL YER, CYRILLIC SMALL LETTER NEUTRAL YER +test(0xA64F, 0xA64E); // CYRILLIC SMALL LETTER NEUTRAL YER, CYRILLIC CAPITAL LETTER NEUTRAL YER +test(0xA650, 0xA651); // CYRILLIC CAPITAL LETTER YERU WITH BACK YER, CYRILLIC SMALL LETTER YERU WITH BACK YER +test(0xA651, 0xA650); // CYRILLIC SMALL LETTER YERU WITH BACK YER, CYRILLIC CAPITAL LETTER YERU WITH BACK YER +test(0xA652, 0xA653); // CYRILLIC CAPITAL LETTER IOTIFIED YAT, CYRILLIC SMALL LETTER IOTIFIED YAT +test(0xA653, 0xA652); // CYRILLIC SMALL LETTER IOTIFIED YAT, CYRILLIC CAPITAL LETTER IOTIFIED YAT +test(0xA654, 0xA655); // CYRILLIC CAPITAL LETTER REVERSED YU, CYRILLIC SMALL LETTER REVERSED YU +test(0xA655, 0xA654); // CYRILLIC SMALL LETTER REVERSED YU, CYRILLIC CAPITAL LETTER REVERSED YU +test(0xA656, 0xA657); // CYRILLIC CAPITAL LETTER IOTIFIED A, CYRILLIC SMALL LETTER IOTIFIED A +test(0xA657, 0xA656); // CYRILLIC SMALL LETTER IOTIFIED A, CYRILLIC CAPITAL LETTER IOTIFIED A +test(0xA658, 0xA659); // CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS, CYRILLIC SMALL LETTER CLOSED LITTLE YUS +test(0xA659, 0xA658); // CYRILLIC SMALL LETTER CLOSED LITTLE YUS, CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS +test(0xA65A, 0xA65B); // CYRILLIC CAPITAL LETTER BLENDED YUS, CYRILLIC SMALL LETTER BLENDED YUS +test(0xA65B, 0xA65A); // CYRILLIC SMALL LETTER BLENDED YUS, CYRILLIC CAPITAL LETTER BLENDED YUS +test(0xA65C, 0xA65D); // CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS, CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS +test(0xA65D, 0xA65C); // CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS, CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS +test(0xA65E, 0xA65F); // CYRILLIC CAPITAL LETTER YN, CYRILLIC SMALL LETTER YN +test(0xA65F, 0xA65E); // CYRILLIC SMALL LETTER YN, CYRILLIC CAPITAL LETTER YN +test(0xA660, 0xA661); // CYRILLIC CAPITAL LETTER REVERSED TSE, CYRILLIC SMALL LETTER REVERSED TSE +test(0xA661, 0xA660); // CYRILLIC SMALL LETTER REVERSED TSE, CYRILLIC CAPITAL LETTER REVERSED TSE +test(0xA662, 0xA663); // CYRILLIC CAPITAL LETTER SOFT DE, CYRILLIC SMALL LETTER SOFT DE +test(0xA663, 0xA662); // CYRILLIC SMALL LETTER SOFT DE, CYRILLIC CAPITAL LETTER SOFT DE +test(0xA664, 0xA665); // CYRILLIC CAPITAL LETTER SOFT EL, CYRILLIC SMALL LETTER SOFT EL +test(0xA665, 0xA664); // CYRILLIC SMALL LETTER SOFT EL, CYRILLIC CAPITAL LETTER SOFT EL +test(0xA666, 0xA667); // CYRILLIC CAPITAL LETTER SOFT EM, CYRILLIC SMALL LETTER SOFT EM +test(0xA667, 0xA666); // CYRILLIC SMALL LETTER SOFT EM, CYRILLIC CAPITAL LETTER SOFT EM +test(0xA668, 0xA669); // CYRILLIC CAPITAL LETTER MONOCULAR O, CYRILLIC SMALL LETTER MONOCULAR O +test(0xA669, 0xA668); // CYRILLIC SMALL LETTER MONOCULAR O, CYRILLIC CAPITAL LETTER MONOCULAR O +test(0xA66A, 0xA66B); // CYRILLIC CAPITAL LETTER BINOCULAR O, CYRILLIC SMALL LETTER BINOCULAR O +test(0xA66B, 0xA66A); // CYRILLIC SMALL LETTER BINOCULAR O, CYRILLIC CAPITAL LETTER BINOCULAR O +test(0xA66C, 0xA66D); // CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O, CYRILLIC SMALL LETTER DOUBLE MONOCULAR O +test(0xA66D, 0xA66C); // CYRILLIC SMALL LETTER DOUBLE MONOCULAR O, CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O +test(0xA680, 0xA681); // CYRILLIC CAPITAL LETTER DWE, CYRILLIC SMALL LETTER DWE +test(0xA681, 0xA680); // CYRILLIC SMALL LETTER DWE, CYRILLIC CAPITAL LETTER DWE +test(0xA682, 0xA683); // CYRILLIC CAPITAL LETTER DZWE, CYRILLIC SMALL LETTER DZWE +test(0xA683, 0xA682); // CYRILLIC SMALL LETTER DZWE, CYRILLIC CAPITAL LETTER DZWE +test(0xA684, 0xA685); // CYRILLIC CAPITAL LETTER ZHWE, CYRILLIC SMALL LETTER ZHWE +test(0xA685, 0xA684); // CYRILLIC SMALL LETTER ZHWE, CYRILLIC CAPITAL LETTER ZHWE +test(0xA686, 0xA687); // CYRILLIC CAPITAL LETTER CCHE, CYRILLIC SMALL LETTER CCHE +test(0xA687, 0xA686); // CYRILLIC SMALL LETTER CCHE, CYRILLIC CAPITAL LETTER CCHE +test(0xA688, 0xA689); // CYRILLIC CAPITAL LETTER DZZE, CYRILLIC SMALL LETTER DZZE +test(0xA689, 0xA688); // CYRILLIC SMALL LETTER DZZE, CYRILLIC CAPITAL LETTER DZZE +test(0xA68A, 0xA68B); // CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK, CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK +test(0xA68B, 0xA68A); // CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK, CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK +test(0xA68C, 0xA68D); // CYRILLIC CAPITAL LETTER TWE, CYRILLIC SMALL LETTER TWE +test(0xA68D, 0xA68C); // CYRILLIC SMALL LETTER TWE, CYRILLIC CAPITAL LETTER TWE +test(0xA68E, 0xA68F); // CYRILLIC CAPITAL LETTER TSWE, CYRILLIC SMALL LETTER TSWE +test(0xA68F, 0xA68E); // CYRILLIC SMALL LETTER TSWE, CYRILLIC CAPITAL LETTER TSWE +test(0xA690, 0xA691); // CYRILLIC CAPITAL LETTER TSSE, CYRILLIC SMALL LETTER TSSE +test(0xA691, 0xA690); // CYRILLIC SMALL LETTER TSSE, CYRILLIC CAPITAL LETTER TSSE +test(0xA692, 0xA693); // CYRILLIC CAPITAL LETTER TCHE, CYRILLIC SMALL LETTER TCHE +test(0xA693, 0xA692); // CYRILLIC SMALL LETTER TCHE, CYRILLIC CAPITAL LETTER TCHE +test(0xA694, 0xA695); // CYRILLIC CAPITAL LETTER HWE, CYRILLIC SMALL LETTER HWE +test(0xA695, 0xA694); // CYRILLIC SMALL LETTER HWE, CYRILLIC CAPITAL LETTER HWE +test(0xA696, 0xA697); // CYRILLIC CAPITAL LETTER SHWE, CYRILLIC SMALL LETTER SHWE +test(0xA697, 0xA696); // CYRILLIC SMALL LETTER SHWE, CYRILLIC CAPITAL LETTER SHWE +test(0xA698, 0xA699); // CYRILLIC CAPITAL LETTER DOUBLE O, CYRILLIC SMALL LETTER DOUBLE O +test(0xA699, 0xA698); // CYRILLIC SMALL LETTER DOUBLE O, CYRILLIC CAPITAL LETTER DOUBLE O +test(0xA69A, 0xA69B); // CYRILLIC CAPITAL LETTER CROSSED O, CYRILLIC SMALL LETTER CROSSED O +test(0xA69B, 0xA69A); // CYRILLIC SMALL LETTER CROSSED O, CYRILLIC CAPITAL LETTER CROSSED O +test(0xA722, 0xA723); // LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF, LATIN SMALL LETTER EGYPTOLOGICAL ALEF +test(0xA723, 0xA722); // LATIN SMALL LETTER EGYPTOLOGICAL ALEF, LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF +test(0xA724, 0xA725); // LATIN CAPITAL LETTER EGYPTOLOGICAL AIN, LATIN SMALL LETTER EGYPTOLOGICAL AIN +test(0xA725, 0xA724); // LATIN SMALL LETTER EGYPTOLOGICAL AIN, LATIN CAPITAL LETTER EGYPTOLOGICAL AIN +test(0xA726, 0xA727); // LATIN CAPITAL LETTER HENG, LATIN SMALL LETTER HENG +test(0xA727, 0xA726); // LATIN SMALL LETTER HENG, LATIN CAPITAL LETTER HENG +test(0xA728, 0xA729); // LATIN CAPITAL LETTER TZ, LATIN SMALL LETTER TZ +test(0xA729, 0xA728); // LATIN SMALL LETTER TZ, LATIN CAPITAL LETTER TZ +test(0xA72A, 0xA72B); // LATIN CAPITAL LETTER TRESILLO, LATIN SMALL LETTER TRESILLO +test(0xA72B, 0xA72A); // LATIN SMALL LETTER TRESILLO, LATIN CAPITAL LETTER TRESILLO +test(0xA72C, 0xA72D); // LATIN CAPITAL LETTER CUATRILLO, LATIN SMALL LETTER CUATRILLO +test(0xA72D, 0xA72C); // LATIN SMALL LETTER CUATRILLO, LATIN CAPITAL LETTER CUATRILLO +test(0xA72E, 0xA72F); // LATIN CAPITAL LETTER CUATRILLO WITH COMMA, LATIN SMALL LETTER CUATRILLO WITH COMMA +test(0xA72F, 0xA72E); // LATIN SMALL LETTER CUATRILLO WITH COMMA, LATIN CAPITAL LETTER CUATRILLO WITH COMMA +test(0xA732, 0xA733); // LATIN CAPITAL LETTER AA, LATIN SMALL LETTER AA +test(0xA733, 0xA732); // LATIN SMALL LETTER AA, LATIN CAPITAL LETTER AA +test(0xA734, 0xA735); // LATIN CAPITAL LETTER AO, LATIN SMALL LETTER AO +test(0xA735, 0xA734); // LATIN SMALL LETTER AO, LATIN CAPITAL LETTER AO +test(0xA736, 0xA737); // LATIN CAPITAL LETTER AU, LATIN SMALL LETTER AU +test(0xA737, 0xA736); // LATIN SMALL LETTER AU, LATIN CAPITAL LETTER AU +test(0xA738, 0xA739); // LATIN CAPITAL LETTER AV, LATIN SMALL LETTER AV +test(0xA739, 0xA738); // LATIN SMALL LETTER AV, LATIN CAPITAL LETTER AV +test(0xA73A, 0xA73B); // LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR, LATIN SMALL LETTER AV WITH HORIZONTAL BAR +test(0xA73B, 0xA73A); // LATIN SMALL LETTER AV WITH HORIZONTAL BAR, LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR +test(0xA73C, 0xA73D); // LATIN CAPITAL LETTER AY, LATIN SMALL LETTER AY +test(0xA73D, 0xA73C); // LATIN SMALL LETTER AY, LATIN CAPITAL LETTER AY +test(0xA73E, 0xA73F); // LATIN CAPITAL LETTER REVERSED C WITH DOT, LATIN SMALL LETTER REVERSED C WITH DOT +test(0xA73F, 0xA73E); // LATIN SMALL LETTER REVERSED C WITH DOT, LATIN CAPITAL LETTER REVERSED C WITH DOT +test(0xA740, 0xA741); // LATIN CAPITAL LETTER K WITH STROKE, LATIN SMALL LETTER K WITH STROKE +test(0xA741, 0xA740); // LATIN SMALL LETTER K WITH STROKE, LATIN CAPITAL LETTER K WITH STROKE +test(0xA742, 0xA743); // LATIN CAPITAL LETTER K WITH DIAGONAL STROKE, LATIN SMALL LETTER K WITH DIAGONAL STROKE +test(0xA743, 0xA742); // LATIN SMALL LETTER K WITH DIAGONAL STROKE, LATIN CAPITAL LETTER K WITH DIAGONAL STROKE +test(0xA744, 0xA745); // LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE, LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE +test(0xA745, 0xA744); // LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE, LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE +test(0xA746, 0xA747); // LATIN CAPITAL LETTER BROKEN L, LATIN SMALL LETTER BROKEN L +test(0xA747, 0xA746); // LATIN SMALL LETTER BROKEN L, LATIN CAPITAL LETTER BROKEN L +test(0xA748, 0xA749); // LATIN CAPITAL LETTER L WITH HIGH STROKE, LATIN SMALL LETTER L WITH HIGH STROKE +test(0xA749, 0xA748); // LATIN SMALL LETTER L WITH HIGH STROKE, LATIN CAPITAL LETTER L WITH HIGH STROKE +test(0xA74A, 0xA74B); // LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY, LATIN SMALL LETTER O WITH LONG STROKE OVERLAY +test(0xA74B, 0xA74A); // LATIN SMALL LETTER O WITH LONG STROKE OVERLAY, LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY +test(0xA74C, 0xA74D); // LATIN CAPITAL LETTER O WITH LOOP, LATIN SMALL LETTER O WITH LOOP +test(0xA74D, 0xA74C); // LATIN SMALL LETTER O WITH LOOP, LATIN CAPITAL LETTER O WITH LOOP +test(0xA74E, 0xA74F); // LATIN CAPITAL LETTER OO, LATIN SMALL LETTER OO +test(0xA74F, 0xA74E); // LATIN SMALL LETTER OO, LATIN CAPITAL LETTER OO +test(0xA750, 0xA751); // LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER, LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER +test(0xA751, 0xA750); // LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER, LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER +test(0xA752, 0xA753); // LATIN CAPITAL LETTER P WITH FLOURISH, LATIN SMALL LETTER P WITH FLOURISH +test(0xA753, 0xA752); // LATIN SMALL LETTER P WITH FLOURISH, LATIN CAPITAL LETTER P WITH FLOURISH +test(0xA754, 0xA755); // LATIN CAPITAL LETTER P WITH SQUIRREL TAIL, LATIN SMALL LETTER P WITH SQUIRREL TAIL +test(0xA755, 0xA754); // LATIN SMALL LETTER P WITH SQUIRREL TAIL, LATIN CAPITAL LETTER P WITH SQUIRREL TAIL +test(0xA756, 0xA757); // LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER, LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER +test(0xA757, 0xA756); // LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER, LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER +test(0xA758, 0xA759); // LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE, LATIN SMALL LETTER Q WITH DIAGONAL STROKE +test(0xA759, 0xA758); // LATIN SMALL LETTER Q WITH DIAGONAL STROKE, LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE +test(0xA75A, 0xA75B); // LATIN CAPITAL LETTER R ROTUNDA, LATIN SMALL LETTER R ROTUNDA +test(0xA75B, 0xA75A); // LATIN SMALL LETTER R ROTUNDA, LATIN CAPITAL LETTER R ROTUNDA +test(0xA75C, 0xA75D); // LATIN CAPITAL LETTER RUM ROTUNDA, LATIN SMALL LETTER RUM ROTUNDA +test(0xA75D, 0xA75C); // LATIN SMALL LETTER RUM ROTUNDA, LATIN CAPITAL LETTER RUM ROTUNDA +test(0xA75E, 0xA75F); // LATIN CAPITAL LETTER V WITH DIAGONAL STROKE, LATIN SMALL LETTER V WITH DIAGONAL STROKE +test(0xA75F, 0xA75E); // LATIN SMALL LETTER V WITH DIAGONAL STROKE, LATIN CAPITAL LETTER V WITH DIAGONAL STROKE +test(0xA760, 0xA761); // LATIN CAPITAL LETTER VY, LATIN SMALL LETTER VY +test(0xA761, 0xA760); // LATIN SMALL LETTER VY, LATIN CAPITAL LETTER VY +test(0xA762, 0xA763); // LATIN CAPITAL LETTER VISIGOTHIC Z, LATIN SMALL LETTER VISIGOTHIC Z +test(0xA763, 0xA762); // LATIN SMALL LETTER VISIGOTHIC Z, LATIN CAPITAL LETTER VISIGOTHIC Z +test(0xA764, 0xA765); // LATIN CAPITAL LETTER THORN WITH STROKE, LATIN SMALL LETTER THORN WITH STROKE +test(0xA765, 0xA764); // LATIN SMALL LETTER THORN WITH STROKE, LATIN CAPITAL LETTER THORN WITH STROKE +test(0xA766, 0xA767); // LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER, LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER +test(0xA767, 0xA766); // LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER, LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER +test(0xA768, 0xA769); // LATIN CAPITAL LETTER VEND, LATIN SMALL LETTER VEND +test(0xA769, 0xA768); // LATIN SMALL LETTER VEND, LATIN CAPITAL LETTER VEND +test(0xA76A, 0xA76B); // LATIN CAPITAL LETTER ET, LATIN SMALL LETTER ET +test(0xA76B, 0xA76A); // LATIN SMALL LETTER ET, LATIN CAPITAL LETTER ET +test(0xA76C, 0xA76D); // LATIN CAPITAL LETTER IS, LATIN SMALL LETTER IS +test(0xA76D, 0xA76C); // LATIN SMALL LETTER IS, LATIN CAPITAL LETTER IS +test(0xA76E, 0xA76F); // LATIN CAPITAL LETTER CON, LATIN SMALL LETTER CON +test(0xA76F, 0xA76E); // LATIN SMALL LETTER CON, LATIN CAPITAL LETTER CON +test(0xA779, 0xA77A); // LATIN CAPITAL LETTER INSULAR D, LATIN SMALL LETTER INSULAR D +test(0xA77A, 0xA779); // LATIN SMALL LETTER INSULAR D, LATIN CAPITAL LETTER INSULAR D +test(0xA77B, 0xA77C); // LATIN CAPITAL LETTER INSULAR F, LATIN SMALL LETTER INSULAR F +test(0xA77C, 0xA77B); // LATIN SMALL LETTER INSULAR F, LATIN CAPITAL LETTER INSULAR F +test(0xA77D, 0x1D79); // LATIN CAPITAL LETTER INSULAR G, LATIN SMALL LETTER INSULAR G +test(0xA77E, 0xA77F); // LATIN CAPITAL LETTER TURNED INSULAR G, LATIN SMALL LETTER TURNED INSULAR G +test(0xA77F, 0xA77E); // LATIN SMALL LETTER TURNED INSULAR G, LATIN CAPITAL LETTER TURNED INSULAR G +test(0xA780, 0xA781); // LATIN CAPITAL LETTER TURNED L, LATIN SMALL LETTER TURNED L +test(0xA781, 0xA780); // LATIN SMALL LETTER TURNED L, LATIN CAPITAL LETTER TURNED L +test(0xA782, 0xA783); // LATIN CAPITAL LETTER INSULAR R, LATIN SMALL LETTER INSULAR R +test(0xA783, 0xA782); // LATIN SMALL LETTER INSULAR R, LATIN CAPITAL LETTER INSULAR R +test(0xA784, 0xA785); // LATIN CAPITAL LETTER INSULAR S, LATIN SMALL LETTER INSULAR S +test(0xA785, 0xA784); // LATIN SMALL LETTER INSULAR S, LATIN CAPITAL LETTER INSULAR S +test(0xA786, 0xA787); // LATIN CAPITAL LETTER INSULAR T, LATIN SMALL LETTER INSULAR T +test(0xA787, 0xA786); // LATIN SMALL LETTER INSULAR T, LATIN CAPITAL LETTER INSULAR T +test(0xA78B, 0xA78C); // LATIN CAPITAL LETTER SALTILLO, LATIN SMALL LETTER SALTILLO +test(0xA78C, 0xA78B); // LATIN SMALL LETTER SALTILLO, LATIN CAPITAL LETTER SALTILLO +test(0xA78D, 0x0265); // LATIN CAPITAL LETTER TURNED H, LATIN SMALL LETTER TURNED H +test(0xA790, 0xA791); // LATIN CAPITAL LETTER N WITH DESCENDER, LATIN SMALL LETTER N WITH DESCENDER +test(0xA791, 0xA790); // LATIN SMALL LETTER N WITH DESCENDER, LATIN CAPITAL LETTER N WITH DESCENDER +test(0xA792, 0xA793); // LATIN CAPITAL LETTER C WITH BAR, LATIN SMALL LETTER C WITH BAR +test(0xA793, 0xA792); // LATIN SMALL LETTER C WITH BAR, LATIN CAPITAL LETTER C WITH BAR +test(0xA794, 0xA7C4); // LATIN SMALL LETTER C WITH PALATAL HOOK, LATIN CAPITAL LETTER C WITH PALATAL HOOK +test(0xA796, 0xA797); // LATIN CAPITAL LETTER B WITH FLOURISH, LATIN SMALL LETTER B WITH FLOURISH +test(0xA797, 0xA796); // LATIN SMALL LETTER B WITH FLOURISH, LATIN CAPITAL LETTER B WITH FLOURISH +test(0xA798, 0xA799); // LATIN CAPITAL LETTER F WITH STROKE, LATIN SMALL LETTER F WITH STROKE +test(0xA799, 0xA798); // LATIN SMALL LETTER F WITH STROKE, LATIN CAPITAL LETTER F WITH STROKE +test(0xA79A, 0xA79B); // LATIN CAPITAL LETTER VOLAPUK AE, LATIN SMALL LETTER VOLAPUK AE +test(0xA79B, 0xA79A); // LATIN SMALL LETTER VOLAPUK AE, LATIN CAPITAL LETTER VOLAPUK AE +test(0xA79C, 0xA79D); // LATIN CAPITAL LETTER VOLAPUK OE, LATIN SMALL LETTER VOLAPUK OE +test(0xA79D, 0xA79C); // LATIN SMALL LETTER VOLAPUK OE, LATIN CAPITAL LETTER VOLAPUK OE +test(0xA79E, 0xA79F); // LATIN CAPITAL LETTER VOLAPUK UE, LATIN SMALL LETTER VOLAPUK UE +test(0xA79F, 0xA79E); // LATIN SMALL LETTER VOLAPUK UE, LATIN CAPITAL LETTER VOLAPUK UE +test(0xA7A0, 0xA7A1); // LATIN CAPITAL LETTER G WITH OBLIQUE STROKE, LATIN SMALL LETTER G WITH OBLIQUE STROKE +test(0xA7A1, 0xA7A0); // LATIN SMALL LETTER G WITH OBLIQUE STROKE, LATIN CAPITAL LETTER G WITH OBLIQUE STROKE +test(0xA7A2, 0xA7A3); // LATIN CAPITAL LETTER K WITH OBLIQUE STROKE, LATIN SMALL LETTER K WITH OBLIQUE STROKE +test(0xA7A3, 0xA7A2); // LATIN SMALL LETTER K WITH OBLIQUE STROKE, LATIN CAPITAL LETTER K WITH OBLIQUE STROKE +test(0xA7A4, 0xA7A5); // LATIN CAPITAL LETTER N WITH OBLIQUE STROKE, LATIN SMALL LETTER N WITH OBLIQUE STROKE +test(0xA7A5, 0xA7A4); // LATIN SMALL LETTER N WITH OBLIQUE STROKE, LATIN CAPITAL LETTER N WITH OBLIQUE STROKE +test(0xA7A6, 0xA7A7); // LATIN CAPITAL LETTER R WITH OBLIQUE STROKE, LATIN SMALL LETTER R WITH OBLIQUE STROKE +test(0xA7A7, 0xA7A6); // LATIN SMALL LETTER R WITH OBLIQUE STROKE, LATIN CAPITAL LETTER R WITH OBLIQUE STROKE +test(0xA7A8, 0xA7A9); // LATIN CAPITAL LETTER S WITH OBLIQUE STROKE, LATIN SMALL LETTER S WITH OBLIQUE STROKE +test(0xA7A9, 0xA7A8); // LATIN SMALL LETTER S WITH OBLIQUE STROKE, LATIN CAPITAL LETTER S WITH OBLIQUE STROKE +test(0xA7AA, 0x0266); // LATIN CAPITAL LETTER H WITH HOOK, LATIN SMALL LETTER H WITH HOOK (LATIN SMALL LETTER H HOOK) +test(0xA7AB, 0x025C); // LATIN CAPITAL LETTER REVERSED OPEN E, LATIN SMALL LETTER REVERSED OPEN E (LATIN SMALL LETTER REVERSED EPSILON) +test(0xA7AC, 0x0261); // LATIN CAPITAL LETTER SCRIPT G, LATIN SMALL LETTER SCRIPT G +test(0xA7AD, 0x026C); // LATIN CAPITAL LETTER L WITH BELT, LATIN SMALL LETTER L WITH BELT (LATIN SMALL LETTER L BELT) +test(0xA7AE, 0x026A); // LATIN CAPITAL LETTER SMALL CAPITAL I, LATIN LETTER SMALL CAPITAL I +test(0xA7B0, 0x029E); // LATIN CAPITAL LETTER TURNED K, LATIN SMALL LETTER TURNED K +test(0xA7B1, 0x0287); // LATIN CAPITAL LETTER TURNED T, LATIN SMALL LETTER TURNED T +test(0xA7B2, 0x029D); // LATIN CAPITAL LETTER J WITH CROSSED-TAIL, LATIN SMALL LETTER J WITH CROSSED-TAIL (LATIN SMALL LETTER CROSSED-TAIL J) +test(0xA7B3, 0xAB53); // LATIN CAPITAL LETTER CHI, LATIN SMALL LETTER CHI +test(0xA7B4, 0xA7B5); // LATIN CAPITAL LETTER BETA, LATIN SMALL LETTER BETA +test(0xA7B5, 0xA7B4); // LATIN SMALL LETTER BETA, LATIN CAPITAL LETTER BETA +test(0xA7B6, 0xA7B7); // LATIN CAPITAL LETTER OMEGA, LATIN SMALL LETTER OMEGA +test(0xA7B7, 0xA7B6); // LATIN SMALL LETTER OMEGA, LATIN CAPITAL LETTER OMEGA +test(0xA7B8, 0xA7B9); // LATIN CAPITAL LETTER U WITH STROKE, LATIN SMALL LETTER U WITH STROKE +test(0xA7B9, 0xA7B8); // LATIN SMALL LETTER U WITH STROKE, LATIN CAPITAL LETTER U WITH STROKE +test(0xA7BA, 0xA7BB); // LATIN CAPITAL LETTER GLOTTAL A, LATIN SMALL LETTER GLOTTAL A +test(0xA7BB, 0xA7BA); // LATIN SMALL LETTER GLOTTAL A, LATIN CAPITAL LETTER GLOTTAL A +test(0xA7BC, 0xA7BD); // LATIN CAPITAL LETTER GLOTTAL I, LATIN SMALL LETTER GLOTTAL I +test(0xA7BD, 0xA7BC); // LATIN SMALL LETTER GLOTTAL I, LATIN CAPITAL LETTER GLOTTAL I +test(0xA7BE, 0xA7BF); // LATIN CAPITAL LETTER GLOTTAL U, LATIN SMALL LETTER GLOTTAL U +test(0xA7BF, 0xA7BE); // LATIN SMALL LETTER GLOTTAL U, LATIN CAPITAL LETTER GLOTTAL U +test(0xA7C0, 0xA7C1); // LATIN CAPITAL LETTER OLD POLISH O, LATIN SMALL LETTER OLD POLISH O +test(0xA7C1, 0xA7C0); // LATIN SMALL LETTER OLD POLISH O, LATIN CAPITAL LETTER OLD POLISH O +test(0xA7C2, 0xA7C3); // LATIN CAPITAL LETTER ANGLICANA W, LATIN SMALL LETTER ANGLICANA W +test(0xA7C3, 0xA7C2); // LATIN SMALL LETTER ANGLICANA W, LATIN CAPITAL LETTER ANGLICANA W +test(0xA7C4, 0xA794); // LATIN CAPITAL LETTER C WITH PALATAL HOOK, LATIN SMALL LETTER C WITH PALATAL HOOK +test(0xA7C5, 0x0282); // LATIN CAPITAL LETTER S WITH HOOK, LATIN SMALL LETTER S WITH HOOK (LATIN SMALL LETTER S HOOK) +test(0xA7C6, 0x1D8E); // LATIN CAPITAL LETTER Z WITH PALATAL HOOK, LATIN SMALL LETTER Z WITH PALATAL HOOK +test(0xA7C7, 0xA7C8); // LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY, LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY +test(0xA7C8, 0xA7C7); // LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY, LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY +test(0xA7C9, 0xA7CA); // LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY, LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +test(0xA7CA, 0xA7C9); // LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY, LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY +test(0xA7D0, 0xA7D1); // LATIN CAPITAL LETTER CLOSED INSULAR G, LATIN SMALL LETTER CLOSED INSULAR G +test(0xA7D1, 0xA7D0); // LATIN SMALL LETTER CLOSED INSULAR G, LATIN CAPITAL LETTER CLOSED INSULAR G +test(0xA7D6, 0xA7D7); // LATIN CAPITAL LETTER MIDDLE SCOTS S, LATIN SMALL LETTER MIDDLE SCOTS S +test(0xA7D7, 0xA7D6); // LATIN SMALL LETTER MIDDLE SCOTS S, LATIN CAPITAL LETTER MIDDLE SCOTS S +test(0xA7D8, 0xA7D9); // LATIN CAPITAL LETTER SIGMOID S, LATIN SMALL LETTER SIGMOID S +test(0xA7D9, 0xA7D8); // LATIN SMALL LETTER SIGMOID S, LATIN CAPITAL LETTER SIGMOID S +test(0xA7F5, 0xA7F6); // LATIN CAPITAL LETTER REVERSED HALF H, LATIN SMALL LETTER REVERSED HALF H +test(0xA7F6, 0xA7F5); // LATIN SMALL LETTER REVERSED HALF H, LATIN CAPITAL LETTER REVERSED HALF H +test(0xAB53, 0xA7B3); // LATIN SMALL LETTER CHI, LATIN CAPITAL LETTER CHI +test(0xAB70, 0x13A0); // CHEROKEE SMALL LETTER A, CHEROKEE LETTER A +test(0xAB71, 0x13A1); // CHEROKEE SMALL LETTER E, CHEROKEE LETTER E +test(0xAB72, 0x13A2); // CHEROKEE SMALL LETTER I, CHEROKEE LETTER I +test(0xAB73, 0x13A3); // CHEROKEE SMALL LETTER O, CHEROKEE LETTER O +test(0xAB74, 0x13A4); // CHEROKEE SMALL LETTER U, CHEROKEE LETTER U +test(0xAB75, 0x13A5); // CHEROKEE SMALL LETTER V, CHEROKEE LETTER V +test(0xAB76, 0x13A6); // CHEROKEE SMALL LETTER GA, CHEROKEE LETTER GA +test(0xAB77, 0x13A7); // CHEROKEE SMALL LETTER KA, CHEROKEE LETTER KA +test(0xAB78, 0x13A8); // CHEROKEE SMALL LETTER GE, CHEROKEE LETTER GE +test(0xAB79, 0x13A9); // CHEROKEE SMALL LETTER GI, CHEROKEE LETTER GI +test(0xAB7A, 0x13AA); // CHEROKEE SMALL LETTER GO, CHEROKEE LETTER GO +test(0xAB7B, 0x13AB); // CHEROKEE SMALL LETTER GU, CHEROKEE LETTER GU +test(0xAB7C, 0x13AC); // CHEROKEE SMALL LETTER GV, CHEROKEE LETTER GV +test(0xAB7D, 0x13AD); // CHEROKEE SMALL LETTER HA, CHEROKEE LETTER HA +test(0xAB7E, 0x13AE); // CHEROKEE SMALL LETTER HE, CHEROKEE LETTER HE +test(0xAB7F, 0x13AF); // CHEROKEE SMALL LETTER HI, CHEROKEE LETTER HI +test(0xAB80, 0x13B0); // CHEROKEE SMALL LETTER HO, CHEROKEE LETTER HO +test(0xAB81, 0x13B1); // CHEROKEE SMALL LETTER HU, CHEROKEE LETTER HU +test(0xAB82, 0x13B2); // CHEROKEE SMALL LETTER HV, CHEROKEE LETTER HV +test(0xAB83, 0x13B3); // CHEROKEE SMALL LETTER LA, CHEROKEE LETTER LA +test(0xAB84, 0x13B4); // CHEROKEE SMALL LETTER LE, CHEROKEE LETTER LE +test(0xAB85, 0x13B5); // CHEROKEE SMALL LETTER LI, CHEROKEE LETTER LI +test(0xAB86, 0x13B6); // CHEROKEE SMALL LETTER LO, CHEROKEE LETTER LO +test(0xAB87, 0x13B7); // CHEROKEE SMALL LETTER LU, CHEROKEE LETTER LU +test(0xAB88, 0x13B8); // CHEROKEE SMALL LETTER LV, CHEROKEE LETTER LV +test(0xAB89, 0x13B9); // CHEROKEE SMALL LETTER MA, CHEROKEE LETTER MA +test(0xAB8A, 0x13BA); // CHEROKEE SMALL LETTER ME, CHEROKEE LETTER ME +test(0xAB8B, 0x13BB); // CHEROKEE SMALL LETTER MI, CHEROKEE LETTER MI +test(0xAB8C, 0x13BC); // CHEROKEE SMALL LETTER MO, CHEROKEE LETTER MO +test(0xAB8D, 0x13BD); // CHEROKEE SMALL LETTER MU, CHEROKEE LETTER MU +test(0xAB8E, 0x13BE); // CHEROKEE SMALL LETTER NA, CHEROKEE LETTER NA +test(0xAB8F, 0x13BF); // CHEROKEE SMALL LETTER HNA, CHEROKEE LETTER HNA +test(0xAB90, 0x13C0); // CHEROKEE SMALL LETTER NAH, CHEROKEE LETTER NAH +test(0xAB91, 0x13C1); // CHEROKEE SMALL LETTER NE, CHEROKEE LETTER NE +test(0xAB92, 0x13C2); // CHEROKEE SMALL LETTER NI, CHEROKEE LETTER NI +test(0xAB93, 0x13C3); // CHEROKEE SMALL LETTER NO, CHEROKEE LETTER NO +test(0xAB94, 0x13C4); // CHEROKEE SMALL LETTER NU, CHEROKEE LETTER NU +test(0xAB95, 0x13C5); // CHEROKEE SMALL LETTER NV, CHEROKEE LETTER NV +test(0xAB96, 0x13C6); // CHEROKEE SMALL LETTER QUA, CHEROKEE LETTER QUA +test(0xAB97, 0x13C7); // CHEROKEE SMALL LETTER QUE, CHEROKEE LETTER QUE +test(0xAB98, 0x13C8); // CHEROKEE SMALL LETTER QUI, CHEROKEE LETTER QUI +test(0xAB99, 0x13C9); // CHEROKEE SMALL LETTER QUO, CHEROKEE LETTER QUO +test(0xAB9A, 0x13CA); // CHEROKEE SMALL LETTER QUU, CHEROKEE LETTER QUU +test(0xAB9B, 0x13CB); // CHEROKEE SMALL LETTER QUV, CHEROKEE LETTER QUV +test(0xAB9C, 0x13CC); // CHEROKEE SMALL LETTER SA, CHEROKEE LETTER SA +test(0xAB9D, 0x13CD); // CHEROKEE SMALL LETTER S, CHEROKEE LETTER S +test(0xAB9E, 0x13CE); // CHEROKEE SMALL LETTER SE, CHEROKEE LETTER SE +test(0xAB9F, 0x13CF); // CHEROKEE SMALL LETTER SI, CHEROKEE LETTER SI +test(0xABA0, 0x13D0); // CHEROKEE SMALL LETTER SO, CHEROKEE LETTER SO +test(0xABA1, 0x13D1); // CHEROKEE SMALL LETTER SU, CHEROKEE LETTER SU +test(0xABA2, 0x13D2); // CHEROKEE SMALL LETTER SV, CHEROKEE LETTER SV +test(0xABA3, 0x13D3); // CHEROKEE SMALL LETTER DA, CHEROKEE LETTER DA +test(0xABA4, 0x13D4); // CHEROKEE SMALL LETTER TA, CHEROKEE LETTER TA +test(0xABA5, 0x13D5); // CHEROKEE SMALL LETTER DE, CHEROKEE LETTER DE +test(0xABA6, 0x13D6); // CHEROKEE SMALL LETTER TE, CHEROKEE LETTER TE +test(0xABA7, 0x13D7); // CHEROKEE SMALL LETTER DI, CHEROKEE LETTER DI +test(0xABA8, 0x13D8); // CHEROKEE SMALL LETTER TI, CHEROKEE LETTER TI +test(0xABA9, 0x13D9); // CHEROKEE SMALL LETTER DO, CHEROKEE LETTER DO +test(0xABAA, 0x13DA); // CHEROKEE SMALL LETTER DU, CHEROKEE LETTER DU +test(0xABAB, 0x13DB); // CHEROKEE SMALL LETTER DV, CHEROKEE LETTER DV +test(0xABAC, 0x13DC); // CHEROKEE SMALL LETTER DLA, CHEROKEE LETTER DLA +test(0xABAD, 0x13DD); // CHEROKEE SMALL LETTER TLA, CHEROKEE LETTER TLA +test(0xABAE, 0x13DE); // CHEROKEE SMALL LETTER TLE, CHEROKEE LETTER TLE +test(0xABAF, 0x13DF); // CHEROKEE SMALL LETTER TLI, CHEROKEE LETTER TLI +test(0xABB0, 0x13E0); // CHEROKEE SMALL LETTER TLO, CHEROKEE LETTER TLO +test(0xABB1, 0x13E1); // CHEROKEE SMALL LETTER TLU, CHEROKEE LETTER TLU +test(0xABB2, 0x13E2); // CHEROKEE SMALL LETTER TLV, CHEROKEE LETTER TLV +test(0xABB3, 0x13E3); // CHEROKEE SMALL LETTER TSA, CHEROKEE LETTER TSA +test(0xABB4, 0x13E4); // CHEROKEE SMALL LETTER TSE, CHEROKEE LETTER TSE +test(0xABB5, 0x13E5); // CHEROKEE SMALL LETTER TSI, CHEROKEE LETTER TSI +test(0xABB6, 0x13E6); // CHEROKEE SMALL LETTER TSO, CHEROKEE LETTER TSO +test(0xABB7, 0x13E7); // CHEROKEE SMALL LETTER TSU, CHEROKEE LETTER TSU +test(0xABB8, 0x13E8); // CHEROKEE SMALL LETTER TSV, CHEROKEE LETTER TSV +test(0xABB9, 0x13E9); // CHEROKEE SMALL LETTER WA, CHEROKEE LETTER WA +test(0xABBA, 0x13EA); // CHEROKEE SMALL LETTER WE, CHEROKEE LETTER WE +test(0xABBB, 0x13EB); // CHEROKEE SMALL LETTER WI, CHEROKEE LETTER WI +test(0xABBC, 0x13EC); // CHEROKEE SMALL LETTER WO, CHEROKEE LETTER WO +test(0xABBD, 0x13ED); // CHEROKEE SMALL LETTER WU, CHEROKEE LETTER WU +test(0xABBE, 0x13EE); // CHEROKEE SMALL LETTER WV, CHEROKEE LETTER WV +test(0xABBF, 0x13EF); // CHEROKEE SMALL LETTER YA, CHEROKEE LETTER YA +test(0xFF21, 0xFF41); // FULLWIDTH LATIN CAPITAL LETTER A, FULLWIDTH LATIN SMALL LETTER A +test(0xFF22, 0xFF42); // FULLWIDTH LATIN CAPITAL LETTER B, FULLWIDTH LATIN SMALL LETTER B +test(0xFF23, 0xFF43); // FULLWIDTH LATIN CAPITAL LETTER C, FULLWIDTH LATIN SMALL LETTER C +test(0xFF24, 0xFF44); // FULLWIDTH LATIN CAPITAL LETTER D, FULLWIDTH LATIN SMALL LETTER D +test(0xFF25, 0xFF45); // FULLWIDTH LATIN CAPITAL LETTER E, FULLWIDTH LATIN SMALL LETTER E +test(0xFF26, 0xFF46); // FULLWIDTH LATIN CAPITAL LETTER F, FULLWIDTH LATIN SMALL LETTER F +test(0xFF27, 0xFF47); // FULLWIDTH LATIN CAPITAL LETTER G, FULLWIDTH LATIN SMALL LETTER G +test(0xFF28, 0xFF48); // FULLWIDTH LATIN CAPITAL LETTER H, FULLWIDTH LATIN SMALL LETTER H +test(0xFF29, 0xFF49); // FULLWIDTH LATIN CAPITAL LETTER I, FULLWIDTH LATIN SMALL LETTER I +test(0xFF2A, 0xFF4A); // FULLWIDTH LATIN CAPITAL LETTER J, FULLWIDTH LATIN SMALL LETTER J +test(0xFF2B, 0xFF4B); // FULLWIDTH LATIN CAPITAL LETTER K, FULLWIDTH LATIN SMALL LETTER K +test(0xFF2C, 0xFF4C); // FULLWIDTH LATIN CAPITAL LETTER L, FULLWIDTH LATIN SMALL LETTER L +test(0xFF2D, 0xFF4D); // FULLWIDTH LATIN CAPITAL LETTER M, FULLWIDTH LATIN SMALL LETTER M +test(0xFF2E, 0xFF4E); // FULLWIDTH LATIN CAPITAL LETTER N, FULLWIDTH LATIN SMALL LETTER N +test(0xFF2F, 0xFF4F); // FULLWIDTH LATIN CAPITAL LETTER O, FULLWIDTH LATIN SMALL LETTER O +test(0xFF30, 0xFF50); // FULLWIDTH LATIN CAPITAL LETTER P, FULLWIDTH LATIN SMALL LETTER P +test(0xFF31, 0xFF51); // FULLWIDTH LATIN CAPITAL LETTER Q, FULLWIDTH LATIN SMALL LETTER Q +test(0xFF32, 0xFF52); // FULLWIDTH LATIN CAPITAL LETTER R, FULLWIDTH LATIN SMALL LETTER R +test(0xFF33, 0xFF53); // FULLWIDTH LATIN CAPITAL LETTER S, FULLWIDTH LATIN SMALL LETTER S +test(0xFF34, 0xFF54); // FULLWIDTH LATIN CAPITAL LETTER T, FULLWIDTH LATIN SMALL LETTER T +test(0xFF35, 0xFF55); // FULLWIDTH LATIN CAPITAL LETTER U, FULLWIDTH LATIN SMALL LETTER U +test(0xFF36, 0xFF56); // FULLWIDTH LATIN CAPITAL LETTER V, FULLWIDTH LATIN SMALL LETTER V +test(0xFF37, 0xFF57); // FULLWIDTH LATIN CAPITAL LETTER W, FULLWIDTH LATIN SMALL LETTER W +test(0xFF38, 0xFF58); // FULLWIDTH LATIN CAPITAL LETTER X, FULLWIDTH LATIN SMALL LETTER X +test(0xFF39, 0xFF59); // FULLWIDTH LATIN CAPITAL LETTER Y, FULLWIDTH LATIN SMALL LETTER Y +test(0xFF3A, 0xFF5A); // FULLWIDTH LATIN CAPITAL LETTER Z, FULLWIDTH LATIN SMALL LETTER Z +test(0xFF41, 0xFF21); // FULLWIDTH LATIN SMALL LETTER A, FULLWIDTH LATIN CAPITAL LETTER A +test(0xFF42, 0xFF22); // FULLWIDTH LATIN SMALL LETTER B, FULLWIDTH LATIN CAPITAL LETTER B +test(0xFF43, 0xFF23); // FULLWIDTH LATIN SMALL LETTER C, FULLWIDTH LATIN CAPITAL LETTER C +test(0xFF44, 0xFF24); // FULLWIDTH LATIN SMALL LETTER D, FULLWIDTH LATIN CAPITAL LETTER D +test(0xFF45, 0xFF25); // FULLWIDTH LATIN SMALL LETTER E, FULLWIDTH LATIN CAPITAL LETTER E +test(0xFF46, 0xFF26); // FULLWIDTH LATIN SMALL LETTER F, FULLWIDTH LATIN CAPITAL LETTER F +test(0xFF47, 0xFF27); // FULLWIDTH LATIN SMALL LETTER G, FULLWIDTH LATIN CAPITAL LETTER G +test(0xFF48, 0xFF28); // FULLWIDTH LATIN SMALL LETTER H, FULLWIDTH LATIN CAPITAL LETTER H +test(0xFF49, 0xFF29); // FULLWIDTH LATIN SMALL LETTER I, FULLWIDTH LATIN CAPITAL LETTER I +test(0xFF4A, 0xFF2A); // FULLWIDTH LATIN SMALL LETTER J, FULLWIDTH LATIN CAPITAL LETTER J +test(0xFF4B, 0xFF2B); // FULLWIDTH LATIN SMALL LETTER K, FULLWIDTH LATIN CAPITAL LETTER K +test(0xFF4C, 0xFF2C); // FULLWIDTH LATIN SMALL LETTER L, FULLWIDTH LATIN CAPITAL LETTER L +test(0xFF4D, 0xFF2D); // FULLWIDTH LATIN SMALL LETTER M, FULLWIDTH LATIN CAPITAL LETTER M +test(0xFF4E, 0xFF2E); // FULLWIDTH LATIN SMALL LETTER N, FULLWIDTH LATIN CAPITAL LETTER N +test(0xFF4F, 0xFF2F); // FULLWIDTH LATIN SMALL LETTER O, FULLWIDTH LATIN CAPITAL LETTER O +test(0xFF50, 0xFF30); // FULLWIDTH LATIN SMALL LETTER P, FULLWIDTH LATIN CAPITAL LETTER P +test(0xFF51, 0xFF31); // FULLWIDTH LATIN SMALL LETTER Q, FULLWIDTH LATIN CAPITAL LETTER Q +test(0xFF52, 0xFF32); // FULLWIDTH LATIN SMALL LETTER R, FULLWIDTH LATIN CAPITAL LETTER R +test(0xFF53, 0xFF33); // FULLWIDTH LATIN SMALL LETTER S, FULLWIDTH LATIN CAPITAL LETTER S +test(0xFF54, 0xFF34); // FULLWIDTH LATIN SMALL LETTER T, FULLWIDTH LATIN CAPITAL LETTER T +test(0xFF55, 0xFF35); // FULLWIDTH LATIN SMALL LETTER U, FULLWIDTH LATIN CAPITAL LETTER U +test(0xFF56, 0xFF36); // FULLWIDTH LATIN SMALL LETTER V, FULLWIDTH LATIN CAPITAL LETTER V +test(0xFF57, 0xFF37); // FULLWIDTH LATIN SMALL LETTER W, FULLWIDTH LATIN CAPITAL LETTER W +test(0xFF58, 0xFF38); // FULLWIDTH LATIN SMALL LETTER X, FULLWIDTH LATIN CAPITAL LETTER X +test(0xFF59, 0xFF39); // FULLWIDTH LATIN SMALL LETTER Y, FULLWIDTH LATIN CAPITAL LETTER Y +test(0xFF5A, 0xFF3A); // FULLWIDTH LATIN SMALL LETTER Z, FULLWIDTH LATIN CAPITAL LETTER Z +test(0x10400, 0x10428); // DESERET CAPITAL LETTER LONG I, DESERET SMALL LETTER LONG I +test(0x10401, 0x10429); // DESERET CAPITAL LETTER LONG E, DESERET SMALL LETTER LONG E +test(0x10402, 0x1042A); // DESERET CAPITAL LETTER LONG A, DESERET SMALL LETTER LONG A +test(0x10403, 0x1042B); // DESERET CAPITAL LETTER LONG AH, DESERET SMALL LETTER LONG AH +test(0x10404, 0x1042C); // DESERET CAPITAL LETTER LONG O, DESERET SMALL LETTER LONG O +test(0x10405, 0x1042D); // DESERET CAPITAL LETTER LONG OO, DESERET SMALL LETTER LONG OO +test(0x10406, 0x1042E); // DESERET CAPITAL LETTER SHORT I, DESERET SMALL LETTER SHORT I +test(0x10407, 0x1042F); // DESERET CAPITAL LETTER SHORT E, DESERET SMALL LETTER SHORT E +test(0x10408, 0x10430); // DESERET CAPITAL LETTER SHORT A, DESERET SMALL LETTER SHORT A +test(0x10409, 0x10431); // DESERET CAPITAL LETTER SHORT AH, DESERET SMALL LETTER SHORT AH +test(0x1040A, 0x10432); // DESERET CAPITAL LETTER SHORT O, DESERET SMALL LETTER SHORT O +test(0x1040B, 0x10433); // DESERET CAPITAL LETTER SHORT OO, DESERET SMALL LETTER SHORT OO +test(0x1040C, 0x10434); // DESERET CAPITAL LETTER AY, DESERET SMALL LETTER AY +test(0x1040D, 0x10435); // DESERET CAPITAL LETTER OW, DESERET SMALL LETTER OW +test(0x1040E, 0x10436); // DESERET CAPITAL LETTER WU, DESERET SMALL LETTER WU +test(0x1040F, 0x10437); // DESERET CAPITAL LETTER YEE, DESERET SMALL LETTER YEE +test(0x10410, 0x10438); // DESERET CAPITAL LETTER H, DESERET SMALL LETTER H +test(0x10411, 0x10439); // DESERET CAPITAL LETTER PEE, DESERET SMALL LETTER PEE +test(0x10412, 0x1043A); // DESERET CAPITAL LETTER BEE, DESERET SMALL LETTER BEE +test(0x10413, 0x1043B); // DESERET CAPITAL LETTER TEE, DESERET SMALL LETTER TEE +test(0x10414, 0x1043C); // DESERET CAPITAL LETTER DEE, DESERET SMALL LETTER DEE +test(0x10415, 0x1043D); // DESERET CAPITAL LETTER CHEE, DESERET SMALL LETTER CHEE +test(0x10416, 0x1043E); // DESERET CAPITAL LETTER JEE, DESERET SMALL LETTER JEE +test(0x10417, 0x1043F); // DESERET CAPITAL LETTER KAY, DESERET SMALL LETTER KAY +test(0x10418, 0x10440); // DESERET CAPITAL LETTER GAY, DESERET SMALL LETTER GAY +test(0x10419, 0x10441); // DESERET CAPITAL LETTER EF, DESERET SMALL LETTER EF +test(0x1041A, 0x10442); // DESERET CAPITAL LETTER VEE, DESERET SMALL LETTER VEE +test(0x1041B, 0x10443); // DESERET CAPITAL LETTER ETH, DESERET SMALL LETTER ETH +test(0x1041C, 0x10444); // DESERET CAPITAL LETTER THEE, DESERET SMALL LETTER THEE +test(0x1041D, 0x10445); // DESERET CAPITAL LETTER ES, DESERET SMALL LETTER ES +test(0x1041E, 0x10446); // DESERET CAPITAL LETTER ZEE, DESERET SMALL LETTER ZEE +test(0x1041F, 0x10447); // DESERET CAPITAL LETTER ESH, DESERET SMALL LETTER ESH +test(0x10420, 0x10448); // DESERET CAPITAL LETTER ZHEE, DESERET SMALL LETTER ZHEE +test(0x10421, 0x10449); // DESERET CAPITAL LETTER ER, DESERET SMALL LETTER ER +test(0x10422, 0x1044A); // DESERET CAPITAL LETTER EL, DESERET SMALL LETTER EL +test(0x10423, 0x1044B); // DESERET CAPITAL LETTER EM, DESERET SMALL LETTER EM +test(0x10424, 0x1044C); // DESERET CAPITAL LETTER EN, DESERET SMALL LETTER EN +test(0x10425, 0x1044D); // DESERET CAPITAL LETTER ENG, DESERET SMALL LETTER ENG +test(0x10426, 0x1044E); // DESERET CAPITAL LETTER OI, DESERET SMALL LETTER OI +test(0x10427, 0x1044F); // DESERET CAPITAL LETTER EW, DESERET SMALL LETTER EW +test(0x10428, 0x10400); // DESERET SMALL LETTER LONG I, DESERET CAPITAL LETTER LONG I +test(0x10429, 0x10401); // DESERET SMALL LETTER LONG E, DESERET CAPITAL LETTER LONG E +test(0x1042A, 0x10402); // DESERET SMALL LETTER LONG A, DESERET CAPITAL LETTER LONG A +test(0x1042B, 0x10403); // DESERET SMALL LETTER LONG AH, DESERET CAPITAL LETTER LONG AH +test(0x1042C, 0x10404); // DESERET SMALL LETTER LONG O, DESERET CAPITAL LETTER LONG O +test(0x1042D, 0x10405); // DESERET SMALL LETTER LONG OO, DESERET CAPITAL LETTER LONG OO +test(0x1042E, 0x10406); // DESERET SMALL LETTER SHORT I, DESERET CAPITAL LETTER SHORT I +test(0x1042F, 0x10407); // DESERET SMALL LETTER SHORT E, DESERET CAPITAL LETTER SHORT E +test(0x10430, 0x10408); // DESERET SMALL LETTER SHORT A, DESERET CAPITAL LETTER SHORT A +test(0x10431, 0x10409); // DESERET SMALL LETTER SHORT AH, DESERET CAPITAL LETTER SHORT AH +test(0x10432, 0x1040A); // DESERET SMALL LETTER SHORT O, DESERET CAPITAL LETTER SHORT O +test(0x10433, 0x1040B); // DESERET SMALL LETTER SHORT OO, DESERET CAPITAL LETTER SHORT OO +test(0x10434, 0x1040C); // DESERET SMALL LETTER AY, DESERET CAPITAL LETTER AY +test(0x10435, 0x1040D); // DESERET SMALL LETTER OW, DESERET CAPITAL LETTER OW +test(0x10436, 0x1040E); // DESERET SMALL LETTER WU, DESERET CAPITAL LETTER WU +test(0x10437, 0x1040F); // DESERET SMALL LETTER YEE, DESERET CAPITAL LETTER YEE +test(0x10438, 0x10410); // DESERET SMALL LETTER H, DESERET CAPITAL LETTER H +test(0x10439, 0x10411); // DESERET SMALL LETTER PEE, DESERET CAPITAL LETTER PEE +test(0x1043A, 0x10412); // DESERET SMALL LETTER BEE, DESERET CAPITAL LETTER BEE +test(0x1043B, 0x10413); // DESERET SMALL LETTER TEE, DESERET CAPITAL LETTER TEE +test(0x1043C, 0x10414); // DESERET SMALL LETTER DEE, DESERET CAPITAL LETTER DEE +test(0x1043D, 0x10415); // DESERET SMALL LETTER CHEE, DESERET CAPITAL LETTER CHEE +test(0x1043E, 0x10416); // DESERET SMALL LETTER JEE, DESERET CAPITAL LETTER JEE +test(0x1043F, 0x10417); // DESERET SMALL LETTER KAY, DESERET CAPITAL LETTER KAY +test(0x10440, 0x10418); // DESERET SMALL LETTER GAY, DESERET CAPITAL LETTER GAY +test(0x10441, 0x10419); // DESERET SMALL LETTER EF, DESERET CAPITAL LETTER EF +test(0x10442, 0x1041A); // DESERET SMALL LETTER VEE, DESERET CAPITAL LETTER VEE +test(0x10443, 0x1041B); // DESERET SMALL LETTER ETH, DESERET CAPITAL LETTER ETH +test(0x10444, 0x1041C); // DESERET SMALL LETTER THEE, DESERET CAPITAL LETTER THEE +test(0x10445, 0x1041D); // DESERET SMALL LETTER ES, DESERET CAPITAL LETTER ES +test(0x10446, 0x1041E); // DESERET SMALL LETTER ZEE, DESERET CAPITAL LETTER ZEE +test(0x10447, 0x1041F); // DESERET SMALL LETTER ESH, DESERET CAPITAL LETTER ESH +test(0x10448, 0x10420); // DESERET SMALL LETTER ZHEE, DESERET CAPITAL LETTER ZHEE +test(0x10449, 0x10421); // DESERET SMALL LETTER ER, DESERET CAPITAL LETTER ER +test(0x1044A, 0x10422); // DESERET SMALL LETTER EL, DESERET CAPITAL LETTER EL +test(0x1044B, 0x10423); // DESERET SMALL LETTER EM, DESERET CAPITAL LETTER EM +test(0x1044C, 0x10424); // DESERET SMALL LETTER EN, DESERET CAPITAL LETTER EN +test(0x1044D, 0x10425); // DESERET SMALL LETTER ENG, DESERET CAPITAL LETTER ENG +test(0x1044E, 0x10426); // DESERET SMALL LETTER OI, DESERET CAPITAL LETTER OI +test(0x1044F, 0x10427); // DESERET SMALL LETTER EW, DESERET CAPITAL LETTER EW +test(0x104B0, 0x104D8); // OSAGE CAPITAL LETTER A, OSAGE SMALL LETTER A +test(0x104B1, 0x104D9); // OSAGE CAPITAL LETTER AI, OSAGE SMALL LETTER AI +test(0x104B2, 0x104DA); // OSAGE CAPITAL LETTER AIN, OSAGE SMALL LETTER AIN +test(0x104B3, 0x104DB); // OSAGE CAPITAL LETTER AH, OSAGE SMALL LETTER AH +test(0x104B4, 0x104DC); // OSAGE CAPITAL LETTER BRA, OSAGE SMALL LETTER BRA +test(0x104B5, 0x104DD); // OSAGE CAPITAL LETTER CHA, OSAGE SMALL LETTER CHA +test(0x104B6, 0x104DE); // OSAGE CAPITAL LETTER EHCHA, OSAGE SMALL LETTER EHCHA +test(0x104B7, 0x104DF); // OSAGE CAPITAL LETTER E, OSAGE SMALL LETTER E +test(0x104B8, 0x104E0); // OSAGE CAPITAL LETTER EIN, OSAGE SMALL LETTER EIN +test(0x104B9, 0x104E1); // OSAGE CAPITAL LETTER HA, OSAGE SMALL LETTER HA +test(0x104BA, 0x104E2); // OSAGE CAPITAL LETTER HYA, OSAGE SMALL LETTER HYA +test(0x104BB, 0x104E3); // OSAGE CAPITAL LETTER I, OSAGE SMALL LETTER I +test(0x104BC, 0x104E4); // OSAGE CAPITAL LETTER KA, OSAGE SMALL LETTER KA +test(0x104BD, 0x104E5); // OSAGE CAPITAL LETTER EHKA, OSAGE SMALL LETTER EHKA +test(0x104BE, 0x104E6); // OSAGE CAPITAL LETTER KYA, OSAGE SMALL LETTER KYA +test(0x104BF, 0x104E7); // OSAGE CAPITAL LETTER LA, OSAGE SMALL LETTER LA +test(0x104C0, 0x104E8); // OSAGE CAPITAL LETTER MA, OSAGE SMALL LETTER MA +test(0x104C1, 0x104E9); // OSAGE CAPITAL LETTER NA, OSAGE SMALL LETTER NA +test(0x104C2, 0x104EA); // OSAGE CAPITAL LETTER O, OSAGE SMALL LETTER O +test(0x104C3, 0x104EB); // OSAGE CAPITAL LETTER OIN, OSAGE SMALL LETTER OIN +test(0x104C4, 0x104EC); // OSAGE CAPITAL LETTER PA, OSAGE SMALL LETTER PA +test(0x104C5, 0x104ED); // OSAGE CAPITAL LETTER EHPA, OSAGE SMALL LETTER EHPA +test(0x104C6, 0x104EE); // OSAGE CAPITAL LETTER SA, OSAGE SMALL LETTER SA +test(0x104C7, 0x104EF); // OSAGE CAPITAL LETTER SHA, OSAGE SMALL LETTER SHA +test(0x104C8, 0x104F0); // OSAGE CAPITAL LETTER TA, OSAGE SMALL LETTER TA +test(0x104C9, 0x104F1); // OSAGE CAPITAL LETTER EHTA, OSAGE SMALL LETTER EHTA +test(0x104CA, 0x104F2); // OSAGE CAPITAL LETTER TSA, OSAGE SMALL LETTER TSA +test(0x104CB, 0x104F3); // OSAGE CAPITAL LETTER EHTSA, OSAGE SMALL LETTER EHTSA +test(0x104CC, 0x104F4); // OSAGE CAPITAL LETTER TSHA, OSAGE SMALL LETTER TSHA +test(0x104CD, 0x104F5); // OSAGE CAPITAL LETTER DHA, OSAGE SMALL LETTER DHA +test(0x104CE, 0x104F6); // OSAGE CAPITAL LETTER U, OSAGE SMALL LETTER U +test(0x104CF, 0x104F7); // OSAGE CAPITAL LETTER WA, OSAGE SMALL LETTER WA +test(0x104D0, 0x104F8); // OSAGE CAPITAL LETTER KHA, OSAGE SMALL LETTER KHA +test(0x104D1, 0x104F9); // OSAGE CAPITAL LETTER GHA, OSAGE SMALL LETTER GHA +test(0x104D2, 0x104FA); // OSAGE CAPITAL LETTER ZA, OSAGE SMALL LETTER ZA +test(0x104D3, 0x104FB); // OSAGE CAPITAL LETTER ZHA, OSAGE SMALL LETTER ZHA +test(0x104D8, 0x104B0); // OSAGE SMALL LETTER A, OSAGE CAPITAL LETTER A +test(0x104D9, 0x104B1); // OSAGE SMALL LETTER AI, OSAGE CAPITAL LETTER AI +test(0x104DA, 0x104B2); // OSAGE SMALL LETTER AIN, OSAGE CAPITAL LETTER AIN +test(0x104DB, 0x104B3); // OSAGE SMALL LETTER AH, OSAGE CAPITAL LETTER AH +test(0x104DC, 0x104B4); // OSAGE SMALL LETTER BRA, OSAGE CAPITAL LETTER BRA +test(0x104DD, 0x104B5); // OSAGE SMALL LETTER CHA, OSAGE CAPITAL LETTER CHA +test(0x104DE, 0x104B6); // OSAGE SMALL LETTER EHCHA, OSAGE CAPITAL LETTER EHCHA +test(0x104DF, 0x104B7); // OSAGE SMALL LETTER E, OSAGE CAPITAL LETTER E +test(0x104E0, 0x104B8); // OSAGE SMALL LETTER EIN, OSAGE CAPITAL LETTER EIN +test(0x104E1, 0x104B9); // OSAGE SMALL LETTER HA, OSAGE CAPITAL LETTER HA +test(0x104E2, 0x104BA); // OSAGE SMALL LETTER HYA, OSAGE CAPITAL LETTER HYA +test(0x104E3, 0x104BB); // OSAGE SMALL LETTER I, OSAGE CAPITAL LETTER I +test(0x104E4, 0x104BC); // OSAGE SMALL LETTER KA, OSAGE CAPITAL LETTER KA +test(0x104E5, 0x104BD); // OSAGE SMALL LETTER EHKA, OSAGE CAPITAL LETTER EHKA +test(0x104E6, 0x104BE); // OSAGE SMALL LETTER KYA, OSAGE CAPITAL LETTER KYA +test(0x104E7, 0x104BF); // OSAGE SMALL LETTER LA, OSAGE CAPITAL LETTER LA +test(0x104E8, 0x104C0); // OSAGE SMALL LETTER MA, OSAGE CAPITAL LETTER MA +test(0x104E9, 0x104C1); // OSAGE SMALL LETTER NA, OSAGE CAPITAL LETTER NA +test(0x104EA, 0x104C2); // OSAGE SMALL LETTER O, OSAGE CAPITAL LETTER O +test(0x104EB, 0x104C3); // OSAGE SMALL LETTER OIN, OSAGE CAPITAL LETTER OIN +test(0x104EC, 0x104C4); // OSAGE SMALL LETTER PA, OSAGE CAPITAL LETTER PA +test(0x104ED, 0x104C5); // OSAGE SMALL LETTER EHPA, OSAGE CAPITAL LETTER EHPA +test(0x104EE, 0x104C6); // OSAGE SMALL LETTER SA, OSAGE CAPITAL LETTER SA +test(0x104EF, 0x104C7); // OSAGE SMALL LETTER SHA, OSAGE CAPITAL LETTER SHA +test(0x104F0, 0x104C8); // OSAGE SMALL LETTER TA, OSAGE CAPITAL LETTER TA +test(0x104F1, 0x104C9); // OSAGE SMALL LETTER EHTA, OSAGE CAPITAL LETTER EHTA +test(0x104F2, 0x104CA); // OSAGE SMALL LETTER TSA, OSAGE CAPITAL LETTER TSA +test(0x104F3, 0x104CB); // OSAGE SMALL LETTER EHTSA, OSAGE CAPITAL LETTER EHTSA +test(0x104F4, 0x104CC); // OSAGE SMALL LETTER TSHA, OSAGE CAPITAL LETTER TSHA +test(0x104F5, 0x104CD); // OSAGE SMALL LETTER DHA, OSAGE CAPITAL LETTER DHA +test(0x104F6, 0x104CE); // OSAGE SMALL LETTER U, OSAGE CAPITAL LETTER U +test(0x104F7, 0x104CF); // OSAGE SMALL LETTER WA, OSAGE CAPITAL LETTER WA +test(0x104F8, 0x104D0); // OSAGE SMALL LETTER KHA, OSAGE CAPITAL LETTER KHA +test(0x104F9, 0x104D1); // OSAGE SMALL LETTER GHA, OSAGE CAPITAL LETTER GHA +test(0x104FA, 0x104D2); // OSAGE SMALL LETTER ZA, OSAGE CAPITAL LETTER ZA +test(0x104FB, 0x104D3); // OSAGE SMALL LETTER ZHA, OSAGE CAPITAL LETTER ZHA +test(0x10570, 0x10597); // VITHKUQI CAPITAL LETTER A, VITHKUQI SMALL LETTER A +test(0x10571, 0x10598); // VITHKUQI CAPITAL LETTER BBE, VITHKUQI SMALL LETTER BBE +test(0x10572, 0x10599); // VITHKUQI CAPITAL LETTER BE, VITHKUQI SMALL LETTER BE +test(0x10573, 0x1059A); // VITHKUQI CAPITAL LETTER CE, VITHKUQI SMALL LETTER CE +test(0x10574, 0x1059B); // VITHKUQI CAPITAL LETTER CHE, VITHKUQI SMALL LETTER CHE +test(0x10575, 0x1059C); // VITHKUQI CAPITAL LETTER DE, VITHKUQI SMALL LETTER DE +test(0x10576, 0x1059D); // VITHKUQI CAPITAL LETTER DHE, VITHKUQI SMALL LETTER DHE +test(0x10577, 0x1059E); // VITHKUQI CAPITAL LETTER EI, VITHKUQI SMALL LETTER EI +test(0x10578, 0x1059F); // VITHKUQI CAPITAL LETTER E, VITHKUQI SMALL LETTER E +test(0x10579, 0x105A0); // VITHKUQI CAPITAL LETTER FE, VITHKUQI SMALL LETTER FE +test(0x1057A, 0x105A1); // VITHKUQI CAPITAL LETTER GA, VITHKUQI SMALL LETTER GA +test(0x1057C, 0x105A3); // VITHKUQI CAPITAL LETTER HA, VITHKUQI SMALL LETTER HA +test(0x1057D, 0x105A4); // VITHKUQI CAPITAL LETTER HHA, VITHKUQI SMALL LETTER HHA +test(0x1057E, 0x105A5); // VITHKUQI CAPITAL LETTER I, VITHKUQI SMALL LETTER I +test(0x1057F, 0x105A6); // VITHKUQI CAPITAL LETTER IJE, VITHKUQI SMALL LETTER IJE +test(0x10580, 0x105A7); // VITHKUQI CAPITAL LETTER JE, VITHKUQI SMALL LETTER JE +test(0x10581, 0x105A8); // VITHKUQI CAPITAL LETTER KA, VITHKUQI SMALL LETTER KA +test(0x10582, 0x105A9); // VITHKUQI CAPITAL LETTER LA, VITHKUQI SMALL LETTER LA +test(0x10583, 0x105AA); // VITHKUQI CAPITAL LETTER LLA, VITHKUQI SMALL LETTER LLA +test(0x10584, 0x105AB); // VITHKUQI CAPITAL LETTER ME, VITHKUQI SMALL LETTER ME +test(0x10585, 0x105AC); // VITHKUQI CAPITAL LETTER NE, VITHKUQI SMALL LETTER NE +test(0x10586, 0x105AD); // VITHKUQI CAPITAL LETTER NJE, VITHKUQI SMALL LETTER NJE +test(0x10587, 0x105AE); // VITHKUQI CAPITAL LETTER O, VITHKUQI SMALL LETTER O +test(0x10588, 0x105AF); // VITHKUQI CAPITAL LETTER PE, VITHKUQI SMALL LETTER PE +test(0x10589, 0x105B0); // VITHKUQI CAPITAL LETTER QA, VITHKUQI SMALL LETTER QA +test(0x1058A, 0x105B1); // VITHKUQI CAPITAL LETTER RE, VITHKUQI SMALL LETTER RE +test(0x1058C, 0x105B3); // VITHKUQI CAPITAL LETTER SE, VITHKUQI SMALL LETTER SE +test(0x1058D, 0x105B4); // VITHKUQI CAPITAL LETTER SHE, VITHKUQI SMALL LETTER SHE +test(0x1058E, 0x105B5); // VITHKUQI CAPITAL LETTER TE, VITHKUQI SMALL LETTER TE +test(0x1058F, 0x105B6); // VITHKUQI CAPITAL LETTER THE, VITHKUQI SMALL LETTER THE +test(0x10590, 0x105B7); // VITHKUQI CAPITAL LETTER U, VITHKUQI SMALL LETTER U +test(0x10591, 0x105B8); // VITHKUQI CAPITAL LETTER VE, VITHKUQI SMALL LETTER VE +test(0x10592, 0x105B9); // VITHKUQI CAPITAL LETTER XE, VITHKUQI SMALL LETTER XE +test(0x10594, 0x105BB); // VITHKUQI CAPITAL LETTER Y, VITHKUQI SMALL LETTER Y +test(0x10595, 0x105BC); // VITHKUQI CAPITAL LETTER ZE, VITHKUQI SMALL LETTER ZE +test(0x10597, 0x10570); // VITHKUQI SMALL LETTER A, VITHKUQI CAPITAL LETTER A +test(0x10598, 0x10571); // VITHKUQI SMALL LETTER BBE, VITHKUQI CAPITAL LETTER BBE +test(0x10599, 0x10572); // VITHKUQI SMALL LETTER BE, VITHKUQI CAPITAL LETTER BE +test(0x1059A, 0x10573); // VITHKUQI SMALL LETTER CE, VITHKUQI CAPITAL LETTER CE +test(0x1059B, 0x10574); // VITHKUQI SMALL LETTER CHE, VITHKUQI CAPITAL LETTER CHE +test(0x1059C, 0x10575); // VITHKUQI SMALL LETTER DE, VITHKUQI CAPITAL LETTER DE +test(0x1059D, 0x10576); // VITHKUQI SMALL LETTER DHE, VITHKUQI CAPITAL LETTER DHE +test(0x1059E, 0x10577); // VITHKUQI SMALL LETTER EI, VITHKUQI CAPITAL LETTER EI +test(0x1059F, 0x10578); // VITHKUQI SMALL LETTER E, VITHKUQI CAPITAL LETTER E +test(0x105A0, 0x10579); // VITHKUQI SMALL LETTER FE, VITHKUQI CAPITAL LETTER FE +test(0x105A1, 0x1057A); // VITHKUQI SMALL LETTER GA, VITHKUQI CAPITAL LETTER GA +test(0x105A3, 0x1057C); // VITHKUQI SMALL LETTER HA, VITHKUQI CAPITAL LETTER HA +test(0x105A4, 0x1057D); // VITHKUQI SMALL LETTER HHA, VITHKUQI CAPITAL LETTER HHA +test(0x105A5, 0x1057E); // VITHKUQI SMALL LETTER I, VITHKUQI CAPITAL LETTER I +test(0x105A6, 0x1057F); // VITHKUQI SMALL LETTER IJE, VITHKUQI CAPITAL LETTER IJE +test(0x105A7, 0x10580); // VITHKUQI SMALL LETTER JE, VITHKUQI CAPITAL LETTER JE +test(0x105A8, 0x10581); // VITHKUQI SMALL LETTER KA, VITHKUQI CAPITAL LETTER KA +test(0x105A9, 0x10582); // VITHKUQI SMALL LETTER LA, VITHKUQI CAPITAL LETTER LA +test(0x105AA, 0x10583); // VITHKUQI SMALL LETTER LLA, VITHKUQI CAPITAL LETTER LLA +test(0x105AB, 0x10584); // VITHKUQI SMALL LETTER ME, VITHKUQI CAPITAL LETTER ME +test(0x105AC, 0x10585); // VITHKUQI SMALL LETTER NE, VITHKUQI CAPITAL LETTER NE +test(0x105AD, 0x10586); // VITHKUQI SMALL LETTER NJE, VITHKUQI CAPITAL LETTER NJE +test(0x105AE, 0x10587); // VITHKUQI SMALL LETTER O, VITHKUQI CAPITAL LETTER O +test(0x105AF, 0x10588); // VITHKUQI SMALL LETTER PE, VITHKUQI CAPITAL LETTER PE +test(0x105B0, 0x10589); // VITHKUQI SMALL LETTER QA, VITHKUQI CAPITAL LETTER QA +test(0x105B1, 0x1058A); // VITHKUQI SMALL LETTER RE, VITHKUQI CAPITAL LETTER RE +test(0x105B3, 0x1058C); // VITHKUQI SMALL LETTER SE, VITHKUQI CAPITAL LETTER SE +test(0x105B4, 0x1058D); // VITHKUQI SMALL LETTER SHE, VITHKUQI CAPITAL LETTER SHE +test(0x105B5, 0x1058E); // VITHKUQI SMALL LETTER TE, VITHKUQI CAPITAL LETTER TE +test(0x105B6, 0x1058F); // VITHKUQI SMALL LETTER THE, VITHKUQI CAPITAL LETTER THE +test(0x105B7, 0x10590); // VITHKUQI SMALL LETTER U, VITHKUQI CAPITAL LETTER U +test(0x105B8, 0x10591); // VITHKUQI SMALL LETTER VE, VITHKUQI CAPITAL LETTER VE +test(0x105B9, 0x10592); // VITHKUQI SMALL LETTER XE, VITHKUQI CAPITAL LETTER XE +test(0x105BB, 0x10594); // VITHKUQI SMALL LETTER Y, VITHKUQI CAPITAL LETTER Y +test(0x105BC, 0x10595); // VITHKUQI SMALL LETTER ZE, VITHKUQI CAPITAL LETTER ZE +test(0x10C80, 0x10CC0); // OLD HUNGARIAN CAPITAL LETTER A, OLD HUNGARIAN SMALL LETTER A +test(0x10C81, 0x10CC1); // OLD HUNGARIAN CAPITAL LETTER AA, OLD HUNGARIAN SMALL LETTER AA +test(0x10C82, 0x10CC2); // OLD HUNGARIAN CAPITAL LETTER EB, OLD HUNGARIAN SMALL LETTER EB +test(0x10C83, 0x10CC3); // OLD HUNGARIAN CAPITAL LETTER AMB, OLD HUNGARIAN SMALL LETTER AMB +test(0x10C84, 0x10CC4); // OLD HUNGARIAN CAPITAL LETTER EC, OLD HUNGARIAN SMALL LETTER EC +test(0x10C85, 0x10CC5); // OLD HUNGARIAN CAPITAL LETTER ENC, OLD HUNGARIAN SMALL LETTER ENC +test(0x10C86, 0x10CC6); // OLD HUNGARIAN CAPITAL LETTER ECS, OLD HUNGARIAN SMALL LETTER ECS +test(0x10C87, 0x10CC7); // OLD HUNGARIAN CAPITAL LETTER ED, OLD HUNGARIAN SMALL LETTER ED +test(0x10C88, 0x10CC8); // OLD HUNGARIAN CAPITAL LETTER AND, OLD HUNGARIAN SMALL LETTER AND +test(0x10C89, 0x10CC9); // OLD HUNGARIAN CAPITAL LETTER E, OLD HUNGARIAN SMALL LETTER E +test(0x10C8A, 0x10CCA); // OLD HUNGARIAN CAPITAL LETTER CLOSE E, OLD HUNGARIAN SMALL LETTER CLOSE E +test(0x10C8B, 0x10CCB); // OLD HUNGARIAN CAPITAL LETTER EE, OLD HUNGARIAN SMALL LETTER EE +test(0x10C8C, 0x10CCC); // OLD HUNGARIAN CAPITAL LETTER EF, OLD HUNGARIAN SMALL LETTER EF +test(0x10C8D, 0x10CCD); // OLD HUNGARIAN CAPITAL LETTER EG, OLD HUNGARIAN SMALL LETTER EG +test(0x10C8E, 0x10CCE); // OLD HUNGARIAN CAPITAL LETTER EGY, OLD HUNGARIAN SMALL LETTER EGY +test(0x10C8F, 0x10CCF); // OLD HUNGARIAN CAPITAL LETTER EH, OLD HUNGARIAN SMALL LETTER EH +test(0x10C90, 0x10CD0); // OLD HUNGARIAN CAPITAL LETTER I, OLD HUNGARIAN SMALL LETTER I +test(0x10C91, 0x10CD1); // OLD HUNGARIAN CAPITAL LETTER II, OLD HUNGARIAN SMALL LETTER II +test(0x10C92, 0x10CD2); // OLD HUNGARIAN CAPITAL LETTER EJ, OLD HUNGARIAN SMALL LETTER EJ +test(0x10C93, 0x10CD3); // OLD HUNGARIAN CAPITAL LETTER EK, OLD HUNGARIAN SMALL LETTER EK +test(0x10C94, 0x10CD4); // OLD HUNGARIAN CAPITAL LETTER AK, OLD HUNGARIAN SMALL LETTER AK +test(0x10C95, 0x10CD5); // OLD HUNGARIAN CAPITAL LETTER UNK, OLD HUNGARIAN SMALL LETTER UNK +test(0x10C96, 0x10CD6); // OLD HUNGARIAN CAPITAL LETTER EL, OLD HUNGARIAN SMALL LETTER EL +test(0x10C97, 0x10CD7); // OLD HUNGARIAN CAPITAL LETTER ELY, OLD HUNGARIAN SMALL LETTER ELY +test(0x10C98, 0x10CD8); // OLD HUNGARIAN CAPITAL LETTER EM, OLD HUNGARIAN SMALL LETTER EM +test(0x10C99, 0x10CD9); // OLD HUNGARIAN CAPITAL LETTER EN, OLD HUNGARIAN SMALL LETTER EN +test(0x10C9A, 0x10CDA); // OLD HUNGARIAN CAPITAL LETTER ENY, OLD HUNGARIAN SMALL LETTER ENY +test(0x10C9B, 0x10CDB); // OLD HUNGARIAN CAPITAL LETTER O, OLD HUNGARIAN SMALL LETTER O +test(0x10C9C, 0x10CDC); // OLD HUNGARIAN CAPITAL LETTER OO, OLD HUNGARIAN SMALL LETTER OO +test(0x10C9D, 0x10CDD); // OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE, OLD HUNGARIAN SMALL LETTER NIKOLSBURG OE +test(0x10C9E, 0x10CDE); // OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE, OLD HUNGARIAN SMALL LETTER RUDIMENTA OE +test(0x10C9F, 0x10CDF); // OLD HUNGARIAN CAPITAL LETTER OEE, OLD HUNGARIAN SMALL LETTER OEE +test(0x10CA0, 0x10CE0); // OLD HUNGARIAN CAPITAL LETTER EP, OLD HUNGARIAN SMALL LETTER EP +test(0x10CA1, 0x10CE1); // OLD HUNGARIAN CAPITAL LETTER EMP, OLD HUNGARIAN SMALL LETTER EMP +test(0x10CA2, 0x10CE2); // OLD HUNGARIAN CAPITAL LETTER ER, OLD HUNGARIAN SMALL LETTER ER +test(0x10CA3, 0x10CE3); // OLD HUNGARIAN CAPITAL LETTER SHORT ER, OLD HUNGARIAN SMALL LETTER SHORT ER +test(0x10CA4, 0x10CE4); // OLD HUNGARIAN CAPITAL LETTER ES, OLD HUNGARIAN SMALL LETTER ES +test(0x10CA5, 0x10CE5); // OLD HUNGARIAN CAPITAL LETTER ESZ, OLD HUNGARIAN SMALL LETTER ESZ +test(0x10CA6, 0x10CE6); // OLD HUNGARIAN CAPITAL LETTER ET, OLD HUNGARIAN SMALL LETTER ET +test(0x10CA7, 0x10CE7); // OLD HUNGARIAN CAPITAL LETTER ENT, OLD HUNGARIAN SMALL LETTER ENT +test(0x10CA8, 0x10CE8); // OLD HUNGARIAN CAPITAL LETTER ETY, OLD HUNGARIAN SMALL LETTER ETY +test(0x10CA9, 0x10CE9); // OLD HUNGARIAN CAPITAL LETTER ECH, OLD HUNGARIAN SMALL LETTER ECH +test(0x10CAA, 0x10CEA); // OLD HUNGARIAN CAPITAL LETTER U, OLD HUNGARIAN SMALL LETTER U +test(0x10CAB, 0x10CEB); // OLD HUNGARIAN CAPITAL LETTER UU, OLD HUNGARIAN SMALL LETTER UU +test(0x10CAC, 0x10CEC); // OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE, OLD HUNGARIAN SMALL LETTER NIKOLSBURG UE +test(0x10CAD, 0x10CED); // OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE, OLD HUNGARIAN SMALL LETTER RUDIMENTA UE +test(0x10CAE, 0x10CEE); // OLD HUNGARIAN CAPITAL LETTER EV, OLD HUNGARIAN SMALL LETTER EV +test(0x10CAF, 0x10CEF); // OLD HUNGARIAN CAPITAL LETTER EZ, OLD HUNGARIAN SMALL LETTER EZ +test(0x10CB0, 0x10CF0); // OLD HUNGARIAN CAPITAL LETTER EZS, OLD HUNGARIAN SMALL LETTER EZS +test(0x10CB1, 0x10CF1); // OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN, OLD HUNGARIAN SMALL LETTER ENT-SHAPED SIGN +test(0x10CB2, 0x10CF2); // OLD HUNGARIAN CAPITAL LETTER US, OLD HUNGARIAN SMALL LETTER US +test(0x10CC0, 0x10C80); // OLD HUNGARIAN SMALL LETTER A, OLD HUNGARIAN CAPITAL LETTER A +test(0x10CC1, 0x10C81); // OLD HUNGARIAN SMALL LETTER AA, OLD HUNGARIAN CAPITAL LETTER AA +test(0x10CC2, 0x10C82); // OLD HUNGARIAN SMALL LETTER EB, OLD HUNGARIAN CAPITAL LETTER EB +test(0x10CC3, 0x10C83); // OLD HUNGARIAN SMALL LETTER AMB, OLD HUNGARIAN CAPITAL LETTER AMB +test(0x10CC4, 0x10C84); // OLD HUNGARIAN SMALL LETTER EC, OLD HUNGARIAN CAPITAL LETTER EC +test(0x10CC5, 0x10C85); // OLD HUNGARIAN SMALL LETTER ENC, OLD HUNGARIAN CAPITAL LETTER ENC +test(0x10CC6, 0x10C86); // OLD HUNGARIAN SMALL LETTER ECS, OLD HUNGARIAN CAPITAL LETTER ECS +test(0x10CC7, 0x10C87); // OLD HUNGARIAN SMALL LETTER ED, OLD HUNGARIAN CAPITAL LETTER ED +test(0x10CC8, 0x10C88); // OLD HUNGARIAN SMALL LETTER AND, OLD HUNGARIAN CAPITAL LETTER AND +test(0x10CC9, 0x10C89); // OLD HUNGARIAN SMALL LETTER E, OLD HUNGARIAN CAPITAL LETTER E +test(0x10CCA, 0x10C8A); // OLD HUNGARIAN SMALL LETTER CLOSE E, OLD HUNGARIAN CAPITAL LETTER CLOSE E +test(0x10CCB, 0x10C8B); // OLD HUNGARIAN SMALL LETTER EE, OLD HUNGARIAN CAPITAL LETTER EE +test(0x10CCC, 0x10C8C); // OLD HUNGARIAN SMALL LETTER EF, OLD HUNGARIAN CAPITAL LETTER EF +test(0x10CCD, 0x10C8D); // OLD HUNGARIAN SMALL LETTER EG, OLD HUNGARIAN CAPITAL LETTER EG +test(0x10CCE, 0x10C8E); // OLD HUNGARIAN SMALL LETTER EGY, OLD HUNGARIAN CAPITAL LETTER EGY +test(0x10CCF, 0x10C8F); // OLD HUNGARIAN SMALL LETTER EH, OLD HUNGARIAN CAPITAL LETTER EH +test(0x10CD0, 0x10C90); // OLD HUNGARIAN SMALL LETTER I, OLD HUNGARIAN CAPITAL LETTER I +test(0x10CD1, 0x10C91); // OLD HUNGARIAN SMALL LETTER II, OLD HUNGARIAN CAPITAL LETTER II +test(0x10CD2, 0x10C92); // OLD HUNGARIAN SMALL LETTER EJ, OLD HUNGARIAN CAPITAL LETTER EJ +test(0x10CD3, 0x10C93); // OLD HUNGARIAN SMALL LETTER EK, OLD HUNGARIAN CAPITAL LETTER EK +test(0x10CD4, 0x10C94); // OLD HUNGARIAN SMALL LETTER AK, OLD HUNGARIAN CAPITAL LETTER AK +test(0x10CD5, 0x10C95); // OLD HUNGARIAN SMALL LETTER UNK, OLD HUNGARIAN CAPITAL LETTER UNK +test(0x10CD6, 0x10C96); // OLD HUNGARIAN SMALL LETTER EL, OLD HUNGARIAN CAPITAL LETTER EL +test(0x10CD7, 0x10C97); // OLD HUNGARIAN SMALL LETTER ELY, OLD HUNGARIAN CAPITAL LETTER ELY +test(0x10CD8, 0x10C98); // OLD HUNGARIAN SMALL LETTER EM, OLD HUNGARIAN CAPITAL LETTER EM +test(0x10CD9, 0x10C99); // OLD HUNGARIAN SMALL LETTER EN, OLD HUNGARIAN CAPITAL LETTER EN +test(0x10CDA, 0x10C9A); // OLD HUNGARIAN SMALL LETTER ENY, OLD HUNGARIAN CAPITAL LETTER ENY +test(0x10CDB, 0x10C9B); // OLD HUNGARIAN SMALL LETTER O, OLD HUNGARIAN CAPITAL LETTER O +test(0x10CDC, 0x10C9C); // OLD HUNGARIAN SMALL LETTER OO, OLD HUNGARIAN CAPITAL LETTER OO +test(0x10CDD, 0x10C9D); // OLD HUNGARIAN SMALL LETTER NIKOLSBURG OE, OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE +test(0x10CDE, 0x10C9E); // OLD HUNGARIAN SMALL LETTER RUDIMENTA OE, OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE +test(0x10CDF, 0x10C9F); // OLD HUNGARIAN SMALL LETTER OEE, OLD HUNGARIAN CAPITAL LETTER OEE +test(0x10CE0, 0x10CA0); // OLD HUNGARIAN SMALL LETTER EP, OLD HUNGARIAN CAPITAL LETTER EP +test(0x10CE1, 0x10CA1); // OLD HUNGARIAN SMALL LETTER EMP, OLD HUNGARIAN CAPITAL LETTER EMP +test(0x10CE2, 0x10CA2); // OLD HUNGARIAN SMALL LETTER ER, OLD HUNGARIAN CAPITAL LETTER ER +test(0x10CE3, 0x10CA3); // OLD HUNGARIAN SMALL LETTER SHORT ER, OLD HUNGARIAN CAPITAL LETTER SHORT ER +test(0x10CE4, 0x10CA4); // OLD HUNGARIAN SMALL LETTER ES, OLD HUNGARIAN CAPITAL LETTER ES +test(0x10CE5, 0x10CA5); // OLD HUNGARIAN SMALL LETTER ESZ, OLD HUNGARIAN CAPITAL LETTER ESZ +test(0x10CE6, 0x10CA6); // OLD HUNGARIAN SMALL LETTER ET, OLD HUNGARIAN CAPITAL LETTER ET +test(0x10CE7, 0x10CA7); // OLD HUNGARIAN SMALL LETTER ENT, OLD HUNGARIAN CAPITAL LETTER ENT +test(0x10CE8, 0x10CA8); // OLD HUNGARIAN SMALL LETTER ETY, OLD HUNGARIAN CAPITAL LETTER ETY +test(0x10CE9, 0x10CA9); // OLD HUNGARIAN SMALL LETTER ECH, OLD HUNGARIAN CAPITAL LETTER ECH +test(0x10CEA, 0x10CAA); // OLD HUNGARIAN SMALL LETTER U, OLD HUNGARIAN CAPITAL LETTER U +test(0x10CEB, 0x10CAB); // OLD HUNGARIAN SMALL LETTER UU, OLD HUNGARIAN CAPITAL LETTER UU +test(0x10CEC, 0x10CAC); // OLD HUNGARIAN SMALL LETTER NIKOLSBURG UE, OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE +test(0x10CED, 0x10CAD); // OLD HUNGARIAN SMALL LETTER RUDIMENTA UE, OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE +test(0x10CEE, 0x10CAE); // OLD HUNGARIAN SMALL LETTER EV, OLD HUNGARIAN CAPITAL LETTER EV +test(0x10CEF, 0x10CAF); // OLD HUNGARIAN SMALL LETTER EZ, OLD HUNGARIAN CAPITAL LETTER EZ +test(0x10CF0, 0x10CB0); // OLD HUNGARIAN SMALL LETTER EZS, OLD HUNGARIAN CAPITAL LETTER EZS +test(0x10CF1, 0x10CB1); // OLD HUNGARIAN SMALL LETTER ENT-SHAPED SIGN, OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN +test(0x10CF2, 0x10CB2); // OLD HUNGARIAN SMALL LETTER US, OLD HUNGARIAN CAPITAL LETTER US +test(0x118A0, 0x118C0); // WARANG CITI CAPITAL LETTER NGAA, WARANG CITI SMALL LETTER NGAA +test(0x118A1, 0x118C1); // WARANG CITI CAPITAL LETTER A, WARANG CITI SMALL LETTER A +test(0x118A2, 0x118C2); // WARANG CITI CAPITAL LETTER WI, WARANG CITI SMALL LETTER WI +test(0x118A3, 0x118C3); // WARANG CITI CAPITAL LETTER YU, WARANG CITI SMALL LETTER YU +test(0x118A4, 0x118C4); // WARANG CITI CAPITAL LETTER YA, WARANG CITI SMALL LETTER YA +test(0x118A5, 0x118C5); // WARANG CITI CAPITAL LETTER YO, WARANG CITI SMALL LETTER YO +test(0x118A6, 0x118C6); // WARANG CITI CAPITAL LETTER II, WARANG CITI SMALL LETTER II +test(0x118A7, 0x118C7); // WARANG CITI CAPITAL LETTER UU, WARANG CITI SMALL LETTER UU +test(0x118A8, 0x118C8); // WARANG CITI CAPITAL LETTER E, WARANG CITI SMALL LETTER E +test(0x118A9, 0x118C9); // WARANG CITI CAPITAL LETTER O, WARANG CITI SMALL LETTER O +test(0x118AA, 0x118CA); // WARANG CITI CAPITAL LETTER ANG, WARANG CITI SMALL LETTER ANG +test(0x118AB, 0x118CB); // WARANG CITI CAPITAL LETTER GA, WARANG CITI SMALL LETTER GA +test(0x118AC, 0x118CC); // WARANG CITI CAPITAL LETTER KO, WARANG CITI SMALL LETTER KO +test(0x118AD, 0x118CD); // WARANG CITI CAPITAL LETTER ENY, WARANG CITI SMALL LETTER ENY +test(0x118AE, 0x118CE); // WARANG CITI CAPITAL LETTER YUJ, WARANG CITI SMALL LETTER YUJ +test(0x118AF, 0x118CF); // WARANG CITI CAPITAL LETTER UC, WARANG CITI SMALL LETTER UC +test(0x118B0, 0x118D0); // WARANG CITI CAPITAL LETTER ENN, WARANG CITI SMALL LETTER ENN +test(0x118B1, 0x118D1); // WARANG CITI CAPITAL LETTER ODD, WARANG CITI SMALL LETTER ODD +test(0x118B2, 0x118D2); // WARANG CITI CAPITAL LETTER TTE, WARANG CITI SMALL LETTER TTE +test(0x118B3, 0x118D3); // WARANG CITI CAPITAL LETTER NUNG, WARANG CITI SMALL LETTER NUNG +test(0x118B4, 0x118D4); // WARANG CITI CAPITAL LETTER DA, WARANG CITI SMALL LETTER DA +test(0x118B5, 0x118D5); // WARANG CITI CAPITAL LETTER AT, WARANG CITI SMALL LETTER AT +test(0x118B6, 0x118D6); // WARANG CITI CAPITAL LETTER AM, WARANG CITI SMALL LETTER AM +test(0x118B7, 0x118D7); // WARANG CITI CAPITAL LETTER BU, WARANG CITI SMALL LETTER BU +test(0x118B8, 0x118D8); // WARANG CITI CAPITAL LETTER PU, WARANG CITI SMALL LETTER PU +test(0x118B9, 0x118D9); // WARANG CITI CAPITAL LETTER HIYO, WARANG CITI SMALL LETTER HIYO +test(0x118BA, 0x118DA); // WARANG CITI CAPITAL LETTER HOLO, WARANG CITI SMALL LETTER HOLO +test(0x118BB, 0x118DB); // WARANG CITI CAPITAL LETTER HORR, WARANG CITI SMALL LETTER HORR +test(0x118BC, 0x118DC); // WARANG CITI CAPITAL LETTER HAR, WARANG CITI SMALL LETTER HAR +test(0x118BD, 0x118DD); // WARANG CITI CAPITAL LETTER SSUU, WARANG CITI SMALL LETTER SSUU +test(0x118BE, 0x118DE); // WARANG CITI CAPITAL LETTER SII, WARANG CITI SMALL LETTER SII +test(0x118BF, 0x118DF); // WARANG CITI CAPITAL LETTER VIYO, WARANG CITI SMALL LETTER VIYO +test(0x118C0, 0x118A0); // WARANG CITI SMALL LETTER NGAA, WARANG CITI CAPITAL LETTER NGAA +test(0x118C1, 0x118A1); // WARANG CITI SMALL LETTER A, WARANG CITI CAPITAL LETTER A +test(0x118C2, 0x118A2); // WARANG CITI SMALL LETTER WI, WARANG CITI CAPITAL LETTER WI +test(0x118C3, 0x118A3); // WARANG CITI SMALL LETTER YU, WARANG CITI CAPITAL LETTER YU +test(0x118C4, 0x118A4); // WARANG CITI SMALL LETTER YA, WARANG CITI CAPITAL LETTER YA +test(0x118C5, 0x118A5); // WARANG CITI SMALL LETTER YO, WARANG CITI CAPITAL LETTER YO +test(0x118C6, 0x118A6); // WARANG CITI SMALL LETTER II, WARANG CITI CAPITAL LETTER II +test(0x118C7, 0x118A7); // WARANG CITI SMALL LETTER UU, WARANG CITI CAPITAL LETTER UU +test(0x118C8, 0x118A8); // WARANG CITI SMALL LETTER E, WARANG CITI CAPITAL LETTER E +test(0x118C9, 0x118A9); // WARANG CITI SMALL LETTER O, WARANG CITI CAPITAL LETTER O +test(0x118CA, 0x118AA); // WARANG CITI SMALL LETTER ANG, WARANG CITI CAPITAL LETTER ANG +test(0x118CB, 0x118AB); // WARANG CITI SMALL LETTER GA, WARANG CITI CAPITAL LETTER GA +test(0x118CC, 0x118AC); // WARANG CITI SMALL LETTER KO, WARANG CITI CAPITAL LETTER KO +test(0x118CD, 0x118AD); // WARANG CITI SMALL LETTER ENY, WARANG CITI CAPITAL LETTER ENY +test(0x118CE, 0x118AE); // WARANG CITI SMALL LETTER YUJ, WARANG CITI CAPITAL LETTER YUJ +test(0x118CF, 0x118AF); // WARANG CITI SMALL LETTER UC, WARANG CITI CAPITAL LETTER UC +test(0x118D0, 0x118B0); // WARANG CITI SMALL LETTER ENN, WARANG CITI CAPITAL LETTER ENN +test(0x118D1, 0x118B1); // WARANG CITI SMALL LETTER ODD, WARANG CITI CAPITAL LETTER ODD +test(0x118D2, 0x118B2); // WARANG CITI SMALL LETTER TTE, WARANG CITI CAPITAL LETTER TTE +test(0x118D3, 0x118B3); // WARANG CITI SMALL LETTER NUNG, WARANG CITI CAPITAL LETTER NUNG +test(0x118D4, 0x118B4); // WARANG CITI SMALL LETTER DA, WARANG CITI CAPITAL LETTER DA +test(0x118D5, 0x118B5); // WARANG CITI SMALL LETTER AT, WARANG CITI CAPITAL LETTER AT +test(0x118D6, 0x118B6); // WARANG CITI SMALL LETTER AM, WARANG CITI CAPITAL LETTER AM +test(0x118D7, 0x118B7); // WARANG CITI SMALL LETTER BU, WARANG CITI CAPITAL LETTER BU +test(0x118D8, 0x118B8); // WARANG CITI SMALL LETTER PU, WARANG CITI CAPITAL LETTER PU +test(0x118D9, 0x118B9); // WARANG CITI SMALL LETTER HIYO, WARANG CITI CAPITAL LETTER HIYO +test(0x118DA, 0x118BA); // WARANG CITI SMALL LETTER HOLO, WARANG CITI CAPITAL LETTER HOLO +test(0x118DB, 0x118BB); // WARANG CITI SMALL LETTER HORR, WARANG CITI CAPITAL LETTER HORR +test(0x118DC, 0x118BC); // WARANG CITI SMALL LETTER HAR, WARANG CITI CAPITAL LETTER HAR +test(0x118DD, 0x118BD); // WARANG CITI SMALL LETTER SSUU, WARANG CITI CAPITAL LETTER SSUU +test(0x118DE, 0x118BE); // WARANG CITI SMALL LETTER SII, WARANG CITI CAPITAL LETTER SII +test(0x118DF, 0x118BF); // WARANG CITI SMALL LETTER VIYO, WARANG CITI CAPITAL LETTER VIYO +test(0x16E40, 0x16E60); // MEDEFAIDRIN CAPITAL LETTER M, MEDEFAIDRIN SMALL LETTER M +test(0x16E41, 0x16E61); // MEDEFAIDRIN CAPITAL LETTER S, MEDEFAIDRIN SMALL LETTER S +test(0x16E42, 0x16E62); // MEDEFAIDRIN CAPITAL LETTER V, MEDEFAIDRIN SMALL LETTER V +test(0x16E43, 0x16E63); // MEDEFAIDRIN CAPITAL LETTER W, MEDEFAIDRIN SMALL LETTER W +test(0x16E44, 0x16E64); // MEDEFAIDRIN CAPITAL LETTER ATIU, MEDEFAIDRIN SMALL LETTER ATIU +test(0x16E45, 0x16E65); // MEDEFAIDRIN CAPITAL LETTER Z, MEDEFAIDRIN SMALL LETTER Z +test(0x16E46, 0x16E66); // MEDEFAIDRIN CAPITAL LETTER KP, MEDEFAIDRIN SMALL LETTER KP +test(0x16E47, 0x16E67); // MEDEFAIDRIN CAPITAL LETTER P, MEDEFAIDRIN SMALL LETTER P +test(0x16E48, 0x16E68); // MEDEFAIDRIN CAPITAL LETTER T, MEDEFAIDRIN SMALL LETTER T +test(0x16E49, 0x16E69); // MEDEFAIDRIN CAPITAL LETTER G, MEDEFAIDRIN SMALL LETTER G +test(0x16E4A, 0x16E6A); // MEDEFAIDRIN CAPITAL LETTER F, MEDEFAIDRIN SMALL LETTER F +test(0x16E4B, 0x16E6B); // MEDEFAIDRIN CAPITAL LETTER I, MEDEFAIDRIN SMALL LETTER I +test(0x16E4C, 0x16E6C); // MEDEFAIDRIN CAPITAL LETTER K, MEDEFAIDRIN SMALL LETTER K +test(0x16E4D, 0x16E6D); // MEDEFAIDRIN CAPITAL LETTER A, MEDEFAIDRIN SMALL LETTER A +test(0x16E4E, 0x16E6E); // MEDEFAIDRIN CAPITAL LETTER J, MEDEFAIDRIN SMALL LETTER J +test(0x16E4F, 0x16E6F); // MEDEFAIDRIN CAPITAL LETTER E, MEDEFAIDRIN SMALL LETTER E +test(0x16E50, 0x16E70); // MEDEFAIDRIN CAPITAL LETTER B, MEDEFAIDRIN SMALL LETTER B +test(0x16E51, 0x16E71); // MEDEFAIDRIN CAPITAL LETTER C, MEDEFAIDRIN SMALL LETTER C +test(0x16E52, 0x16E72); // MEDEFAIDRIN CAPITAL LETTER U, MEDEFAIDRIN SMALL LETTER U +test(0x16E53, 0x16E73); // MEDEFAIDRIN CAPITAL LETTER YU, MEDEFAIDRIN SMALL LETTER YU +test(0x16E54, 0x16E74); // MEDEFAIDRIN CAPITAL LETTER L, MEDEFAIDRIN SMALL LETTER L +test(0x16E55, 0x16E75); // MEDEFAIDRIN CAPITAL LETTER Q, MEDEFAIDRIN SMALL LETTER Q +test(0x16E56, 0x16E76); // MEDEFAIDRIN CAPITAL LETTER HP, MEDEFAIDRIN SMALL LETTER HP +test(0x16E57, 0x16E77); // MEDEFAIDRIN CAPITAL LETTER NY, MEDEFAIDRIN SMALL LETTER NY +test(0x16E58, 0x16E78); // MEDEFAIDRIN CAPITAL LETTER X, MEDEFAIDRIN SMALL LETTER X +test(0x16E59, 0x16E79); // MEDEFAIDRIN CAPITAL LETTER D, MEDEFAIDRIN SMALL LETTER D +test(0x16E5A, 0x16E7A); // MEDEFAIDRIN CAPITAL LETTER OE, MEDEFAIDRIN SMALL LETTER OE +test(0x16E5B, 0x16E7B); // MEDEFAIDRIN CAPITAL LETTER N, MEDEFAIDRIN SMALL LETTER N +test(0x16E5C, 0x16E7C); // MEDEFAIDRIN CAPITAL LETTER R, MEDEFAIDRIN SMALL LETTER R +test(0x16E5D, 0x16E7D); // MEDEFAIDRIN CAPITAL LETTER O, MEDEFAIDRIN SMALL LETTER O +test(0x16E5E, 0x16E7E); // MEDEFAIDRIN CAPITAL LETTER AI, MEDEFAIDRIN SMALL LETTER AI +test(0x16E5F, 0x16E7F); // MEDEFAIDRIN CAPITAL LETTER Y, MEDEFAIDRIN SMALL LETTER Y +test(0x16E60, 0x16E40); // MEDEFAIDRIN SMALL LETTER M, MEDEFAIDRIN CAPITAL LETTER M +test(0x16E61, 0x16E41); // MEDEFAIDRIN SMALL LETTER S, MEDEFAIDRIN CAPITAL LETTER S +test(0x16E62, 0x16E42); // MEDEFAIDRIN SMALL LETTER V, MEDEFAIDRIN CAPITAL LETTER V +test(0x16E63, 0x16E43); // MEDEFAIDRIN SMALL LETTER W, MEDEFAIDRIN CAPITAL LETTER W +test(0x16E64, 0x16E44); // MEDEFAIDRIN SMALL LETTER ATIU, MEDEFAIDRIN CAPITAL LETTER ATIU +test(0x16E65, 0x16E45); // MEDEFAIDRIN SMALL LETTER Z, MEDEFAIDRIN CAPITAL LETTER Z +test(0x16E66, 0x16E46); // MEDEFAIDRIN SMALL LETTER KP, MEDEFAIDRIN CAPITAL LETTER KP +test(0x16E67, 0x16E47); // MEDEFAIDRIN SMALL LETTER P, MEDEFAIDRIN CAPITAL LETTER P +test(0x16E68, 0x16E48); // MEDEFAIDRIN SMALL LETTER T, MEDEFAIDRIN CAPITAL LETTER T +test(0x16E69, 0x16E49); // MEDEFAIDRIN SMALL LETTER G, MEDEFAIDRIN CAPITAL LETTER G +test(0x16E6A, 0x16E4A); // MEDEFAIDRIN SMALL LETTER F, MEDEFAIDRIN CAPITAL LETTER F +test(0x16E6B, 0x16E4B); // MEDEFAIDRIN SMALL LETTER I, MEDEFAIDRIN CAPITAL LETTER I +test(0x16E6C, 0x16E4C); // MEDEFAIDRIN SMALL LETTER K, MEDEFAIDRIN CAPITAL LETTER K +test(0x16E6D, 0x16E4D); // MEDEFAIDRIN SMALL LETTER A, MEDEFAIDRIN CAPITAL LETTER A +test(0x16E6E, 0x16E4E); // MEDEFAIDRIN SMALL LETTER J, MEDEFAIDRIN CAPITAL LETTER J +test(0x16E6F, 0x16E4F); // MEDEFAIDRIN SMALL LETTER E, MEDEFAIDRIN CAPITAL LETTER E +test(0x16E70, 0x16E50); // MEDEFAIDRIN SMALL LETTER B, MEDEFAIDRIN CAPITAL LETTER B +test(0x16E71, 0x16E51); // MEDEFAIDRIN SMALL LETTER C, MEDEFAIDRIN CAPITAL LETTER C +test(0x16E72, 0x16E52); // MEDEFAIDRIN SMALL LETTER U, MEDEFAIDRIN CAPITAL LETTER U +test(0x16E73, 0x16E53); // MEDEFAIDRIN SMALL LETTER YU, MEDEFAIDRIN CAPITAL LETTER YU +test(0x16E74, 0x16E54); // MEDEFAIDRIN SMALL LETTER L, MEDEFAIDRIN CAPITAL LETTER L +test(0x16E75, 0x16E55); // MEDEFAIDRIN SMALL LETTER Q, MEDEFAIDRIN CAPITAL LETTER Q +test(0x16E76, 0x16E56); // MEDEFAIDRIN SMALL LETTER HP, MEDEFAIDRIN CAPITAL LETTER HP +test(0x16E77, 0x16E57); // MEDEFAIDRIN SMALL LETTER NY, MEDEFAIDRIN CAPITAL LETTER NY +test(0x16E78, 0x16E58); // MEDEFAIDRIN SMALL LETTER X, MEDEFAIDRIN CAPITAL LETTER X +test(0x16E79, 0x16E59); // MEDEFAIDRIN SMALL LETTER D, MEDEFAIDRIN CAPITAL LETTER D +test(0x16E7A, 0x16E5A); // MEDEFAIDRIN SMALL LETTER OE, MEDEFAIDRIN CAPITAL LETTER OE +test(0x16E7B, 0x16E5B); // MEDEFAIDRIN SMALL LETTER N, MEDEFAIDRIN CAPITAL LETTER N +test(0x16E7C, 0x16E5C); // MEDEFAIDRIN SMALL LETTER R, MEDEFAIDRIN CAPITAL LETTER R +test(0x16E7D, 0x16E5D); // MEDEFAIDRIN SMALL LETTER O, MEDEFAIDRIN CAPITAL LETTER O +test(0x16E7E, 0x16E5E); // MEDEFAIDRIN SMALL LETTER AI, MEDEFAIDRIN CAPITAL LETTER AI +test(0x16E7F, 0x16E5F); // MEDEFAIDRIN SMALL LETTER Y, MEDEFAIDRIN CAPITAL LETTER Y +test(0x1E900, 0x1E922); // ADLAM CAPITAL LETTER ALIF, ADLAM SMALL LETTER ALIF +test(0x1E901, 0x1E923); // ADLAM CAPITAL LETTER DAALI, ADLAM SMALL LETTER DAALI +test(0x1E902, 0x1E924); // ADLAM CAPITAL LETTER LAAM, ADLAM SMALL LETTER LAAM +test(0x1E903, 0x1E925); // ADLAM CAPITAL LETTER MIIM, ADLAM SMALL LETTER MIIM +test(0x1E904, 0x1E926); // ADLAM CAPITAL LETTER BA, ADLAM SMALL LETTER BA +test(0x1E905, 0x1E927); // ADLAM CAPITAL LETTER SINNYIIYHE, ADLAM SMALL LETTER SINNYIIYHE +test(0x1E906, 0x1E928); // ADLAM CAPITAL LETTER PE, ADLAM SMALL LETTER PE +test(0x1E907, 0x1E929); // ADLAM CAPITAL LETTER BHE, ADLAM SMALL LETTER BHE +test(0x1E908, 0x1E92A); // ADLAM CAPITAL LETTER RA, ADLAM SMALL LETTER RA +test(0x1E909, 0x1E92B); // ADLAM CAPITAL LETTER E, ADLAM SMALL LETTER E +test(0x1E90A, 0x1E92C); // ADLAM CAPITAL LETTER FA, ADLAM SMALL LETTER FA +test(0x1E90B, 0x1E92D); // ADLAM CAPITAL LETTER I, ADLAM SMALL LETTER I +test(0x1E90C, 0x1E92E); // ADLAM CAPITAL LETTER O, ADLAM SMALL LETTER O +test(0x1E90D, 0x1E92F); // ADLAM CAPITAL LETTER DHA, ADLAM SMALL LETTER DHA +test(0x1E90E, 0x1E930); // ADLAM CAPITAL LETTER YHE, ADLAM SMALL LETTER YHE +test(0x1E90F, 0x1E931); // ADLAM CAPITAL LETTER WAW, ADLAM SMALL LETTER WAW +test(0x1E910, 0x1E932); // ADLAM CAPITAL LETTER NUN, ADLAM SMALL LETTER NUN +test(0x1E911, 0x1E933); // ADLAM CAPITAL LETTER KAF, ADLAM SMALL LETTER KAF +test(0x1E912, 0x1E934); // ADLAM CAPITAL LETTER YA, ADLAM SMALL LETTER YA +test(0x1E913, 0x1E935); // ADLAM CAPITAL LETTER U, ADLAM SMALL LETTER U +test(0x1E914, 0x1E936); // ADLAM CAPITAL LETTER JIIM, ADLAM SMALL LETTER JIIM +test(0x1E915, 0x1E937); // ADLAM CAPITAL LETTER CHI, ADLAM SMALL LETTER CHI +test(0x1E916, 0x1E938); // ADLAM CAPITAL LETTER HA, ADLAM SMALL LETTER HA +test(0x1E917, 0x1E939); // ADLAM CAPITAL LETTER QAAF, ADLAM SMALL LETTER QAAF +test(0x1E918, 0x1E93A); // ADLAM CAPITAL LETTER GA, ADLAM SMALL LETTER GA +test(0x1E919, 0x1E93B); // ADLAM CAPITAL LETTER NYA, ADLAM SMALL LETTER NYA +test(0x1E91A, 0x1E93C); // ADLAM CAPITAL LETTER TU, ADLAM SMALL LETTER TU +test(0x1E91B, 0x1E93D); // ADLAM CAPITAL LETTER NHA, ADLAM SMALL LETTER NHA +test(0x1E91C, 0x1E93E); // ADLAM CAPITAL LETTER VA, ADLAM SMALL LETTER VA +test(0x1E91D, 0x1E93F); // ADLAM CAPITAL LETTER KHA, ADLAM SMALL LETTER KHA +test(0x1E91E, 0x1E940); // ADLAM CAPITAL LETTER GBE, ADLAM SMALL LETTER GBE +test(0x1E91F, 0x1E941); // ADLAM CAPITAL LETTER ZAL, ADLAM SMALL LETTER ZAL +test(0x1E920, 0x1E942); // ADLAM CAPITAL LETTER KPO, ADLAM SMALL LETTER KPO +test(0x1E921, 0x1E943); // ADLAM CAPITAL LETTER SHA, ADLAM SMALL LETTER SHA +test(0x1E922, 0x1E900); // ADLAM SMALL LETTER ALIF, ADLAM CAPITAL LETTER ALIF +test(0x1E923, 0x1E901); // ADLAM SMALL LETTER DAALI, ADLAM CAPITAL LETTER DAALI +test(0x1E924, 0x1E902); // ADLAM SMALL LETTER LAAM, ADLAM CAPITAL LETTER LAAM +test(0x1E925, 0x1E903); // ADLAM SMALL LETTER MIIM, ADLAM CAPITAL LETTER MIIM +test(0x1E926, 0x1E904); // ADLAM SMALL LETTER BA, ADLAM CAPITAL LETTER BA +test(0x1E927, 0x1E905); // ADLAM SMALL LETTER SINNYIIYHE, ADLAM CAPITAL LETTER SINNYIIYHE +test(0x1E928, 0x1E906); // ADLAM SMALL LETTER PE, ADLAM CAPITAL LETTER PE +test(0x1E929, 0x1E907); // ADLAM SMALL LETTER BHE, ADLAM CAPITAL LETTER BHE +test(0x1E92A, 0x1E908); // ADLAM SMALL LETTER RA, ADLAM CAPITAL LETTER RA +test(0x1E92B, 0x1E909); // ADLAM SMALL LETTER E, ADLAM CAPITAL LETTER E +test(0x1E92C, 0x1E90A); // ADLAM SMALL LETTER FA, ADLAM CAPITAL LETTER FA +test(0x1E92D, 0x1E90B); // ADLAM SMALL LETTER I, ADLAM CAPITAL LETTER I +test(0x1E92E, 0x1E90C); // ADLAM SMALL LETTER O, ADLAM CAPITAL LETTER O +test(0x1E92F, 0x1E90D); // ADLAM SMALL LETTER DHA, ADLAM CAPITAL LETTER DHA +test(0x1E930, 0x1E90E); // ADLAM SMALL LETTER YHE, ADLAM CAPITAL LETTER YHE +test(0x1E931, 0x1E90F); // ADLAM SMALL LETTER WAW, ADLAM CAPITAL LETTER WAW +test(0x1E932, 0x1E910); // ADLAM SMALL LETTER NUN, ADLAM CAPITAL LETTER NUN +test(0x1E933, 0x1E911); // ADLAM SMALL LETTER KAF, ADLAM CAPITAL LETTER KAF +test(0x1E934, 0x1E912); // ADLAM SMALL LETTER YA, ADLAM CAPITAL LETTER YA +test(0x1E935, 0x1E913); // ADLAM SMALL LETTER U, ADLAM CAPITAL LETTER U +test(0x1E936, 0x1E914); // ADLAM SMALL LETTER JIIM, ADLAM CAPITAL LETTER JIIM +test(0x1E937, 0x1E915); // ADLAM SMALL LETTER CHI, ADLAM CAPITAL LETTER CHI +test(0x1E938, 0x1E916); // ADLAM SMALL LETTER HA, ADLAM CAPITAL LETTER HA +test(0x1E939, 0x1E917); // ADLAM SMALL LETTER QAAF, ADLAM CAPITAL LETTER QAAF +test(0x1E93A, 0x1E918); // ADLAM SMALL LETTER GA, ADLAM CAPITAL LETTER GA +test(0x1E93B, 0x1E919); // ADLAM SMALL LETTER NYA, ADLAM CAPITAL LETTER NYA +test(0x1E93C, 0x1E91A); // ADLAM SMALL LETTER TU, ADLAM CAPITAL LETTER TU +test(0x1E93D, 0x1E91B); // ADLAM SMALL LETTER NHA, ADLAM CAPITAL LETTER NHA +test(0x1E93E, 0x1E91C); // ADLAM SMALL LETTER VA, ADLAM CAPITAL LETTER VA +test(0x1E93F, 0x1E91D); // ADLAM SMALL LETTER KHA, ADLAM CAPITAL LETTER KHA +test(0x1E940, 0x1E91E); // ADLAM SMALL LETTER GBE, ADLAM CAPITAL LETTER GBE +test(0x1E941, 0x1E91F); // ADLAM SMALL LETTER ZAL, ADLAM CAPITAL LETTER ZAL +test(0x1E942, 0x1E920); // ADLAM SMALL LETTER KPO, ADLAM CAPITAL LETTER KPO +test(0x1E943, 0x1E921); // ADLAM SMALL LETTER SHA, ADLAM CAPITAL LETTER SHA + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/non262/RegExp/unicode-index.js b/js/src/tests/non262/RegExp/unicode-index.js new file mode 100644 index 0000000000..a4b2eb2030 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-lead-trail.js b/js/src/tests/non262/RegExp/unicode-lead-trail.js new file mode 100644 index 0000000000..7ecdb9ace4 --- /dev/null +++ b/js/src/tests/non262/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/non262/RegExp/unicode-raw.js b/js/src/tests/non262/RegExp/unicode-raw.js new file mode 100644 index 0000000000..37b572cd82 --- /dev/null +++ b/js/src/tests/non262/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); diff --git a/js/src/tests/non262/RegExp/yflag.js b/js/src/tests/non262/RegExp/yflag.js new file mode 100644 index 0000000000..db101c0b01 --- /dev/null +++ b/js/src/tests/non262/RegExp/yflag.js @@ -0,0 +1,85 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 371932; +var summary = 'ES4 Regular Expression /y flag'; +var actual = ''; +var expect = ''; + +print('See http://developer.mozilla.org/es4/proposals/extend_regexps.html#y_flag'); + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + printBugNumber(BUGNUMBER); + printStatus (summary); + + var c; + var s = '123456'; + + print('Test global flag.'); + + var g = /(1)/g; + expect = 'captures: 1,1; RegExp.leftContext: ""; RegExp.rightContext: "234561"'; + actual = 'captures: ' + g.exec('1234561') + + '; RegExp.leftContext: "' + RegExp.leftContext + + '"; RegExp.rightContext: "' + RegExp.rightContext + '"'; + reportCompare(expect, actual, summary + ' - /(1)/g.exec("1234561") first call'); + + expect = 'captures: 1,1; RegExp.leftContext: "123456"; RegExp.rightContext: ""'; + actual = 'captures: ' + g.exec('1234561') + + '; RegExp.leftContext: "' + RegExp.leftContext + + '"; RegExp.rightContext: "' + RegExp.rightContext + '"'; + reportCompare(expect, actual, summary + ' - /(1)/g.exec("1234561") second call'); + var y = /(1)/y; + + print('Test sticky flag.'); + + /* + * calls to reportCompare invoke regular expression matches which interfere + * with the test of the sticky flag. Collect expect and actual values prior + * to calling reportCompare. Note setting y = /(1)/y resets the lastIndex etc. + */ + + var y = /(1)/y; + var expect4 = 'captures: 1,1; RegExp.leftContext: ""; RegExp.rightContext: "234561"'; + var actual4 = 'captures: ' + y.exec('1234561') + + '; RegExp.leftContext: "' + RegExp.leftContext + + '"; RegExp.rightContext: "' + RegExp.rightContext + '"'; + + var expect5 = 'captures: null; RegExp.leftContext: ""; RegExp.rightContext: "234561"'; + var actual5 = 'captures: ' + y.exec('1234561') + + '; RegExp.leftContext: "' + RegExp.leftContext + + '"; RegExp.rightContext: "' + RegExp.rightContext + '"'; + + reportCompare(expect4, actual4, summary + ' - /(1)/y.exec("1234561") first call'); + reportCompare(expect5, actual5, summary + ' - /(1)/y.exec("1234561") second call'); + + var y = /(1)/y; + + reportCompare(expect5, actual5, summary); + + y = /(1)/y; + var expect6 = 'captures: 1,1; RegExp.leftContext: ""; RegExp.rightContext: "123456"'; + var actual6 = 'captures: ' + y.exec('1123456') + + '; RegExp.leftContext: "' + RegExp.leftContext + + '"; RegExp.rightContext: "' + RegExp.rightContext + '"'; + + var expect7 = 'captures: 1,1; RegExp.leftContext: "1"; RegExp.rightContext: "23456"'; + var actual7 = 'captures: ' + y.exec('1123456') + + '; RegExp.leftContext: "' + RegExp.leftContext + + '"; RegExp.rightContext: "' + RegExp.rightContext + '"'; + + reportCompare(expect6, actual6, summary + ' - /(1)/y.exec("1123456") first call'); + reportCompare(expect7, actual7, summary + ' - /(1)/y.exec("1123456") second call'); + + var y = /(1)/y; + + reportCompare(expect, actual, summary); +} |