summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/RegExp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/src/tests/non262/RegExp/15.10.5-01.js21
-rw-r--r--js/src/tests/non262/RegExp/15.10.6.2-2.js292
-rw-r--r--js/src/tests/non262/RegExp/15.10.7.5-01.js71
-rw-r--r--js/src/tests/non262/RegExp/15.5.4.11.js498
-rw-r--r--js/src/tests/non262/RegExp/7.8.5-01.js35
-rw-r--r--js/src/tests/non262/RegExp/RegExpExec-exec-type-check.js12
-rw-r--r--js/src/tests/non262/RegExp/RegExpExec-exec.js18
-rw-r--r--js/src/tests/non262/RegExp/RegExpExec-return.js31
-rw-r--r--js/src/tests/non262/RegExp/RegExp_dollar_number.js76
-rw-r--r--js/src/tests/non262/RegExp/RegExp_lastMatch.js52
-rw-r--r--js/src/tests/non262/RegExp/RegExp_lastMatch_as_array.js52
-rw-r--r--js/src/tests/non262/RegExp/RegExp_lastParen.js66
-rw-r--r--js/src/tests/non262/RegExp/RegExp_lastParen_as_array.js66
-rw-r--r--js/src/tests/non262/RegExp/RegExp_leftContext.js56
-rw-r--r--js/src/tests/non262/RegExp/RegExp_leftContext_as_array.js56
-rw-r--r--js/src/tests/non262/RegExp/RegExp_object.js54
-rw-r--r--js/src/tests/non262/RegExp/RegExp_rightContext.js56
-rw-r--r--js/src/tests/non262/RegExp/RegExp_rightContext_as_array.js56
-rw-r--r--js/src/tests/non262/RegExp/browser.js0
-rw-r--r--js/src/tests/non262/RegExp/character-class-escape-s.js54
-rw-r--r--js/src/tests/non262/RegExp/character-escape-class-s-mongolian-vowel-separator.js25
-rw-r--r--js/src/tests/non262/RegExp/class-null.js15
-rw-r--r--js/src/tests/non262/RegExp/compile-lastIndex.js82
-rw-r--r--js/src/tests/non262/RegExp/compile-symbol.js14
-rw-r--r--js/src/tests/non262/RegExp/constructor-IsRegExp.js86
-rw-r--r--js/src/tests/non262/RegExp/constructor-constructor.js78
-rw-r--r--js/src/tests/non262/RegExp/constructor-ordering-2.js21
-rw-r--r--js/src/tests/non262/RegExp/constructor-ordering.js16
-rw-r--r--js/src/tests/non262/RegExp/constructor-regexp-unicode.js9
-rw-r--r--js/src/tests/non262/RegExp/constructor-regexp.js61
-rw-r--r--js/src/tests/non262/RegExp/constructor-symbol.js14
-rw-r--r--js/src/tests/non262/RegExp/control_characters.js39
-rw-r--r--js/src/tests/non262/RegExp/cross-compartment-getter.js43
-rw-r--r--js/src/tests/non262/RegExp/descriptor.js25
-rw-r--r--js/src/tests/non262/RegExp/empty-lookahead.js8
-rw-r--r--js/src/tests/non262/RegExp/escape.js70
-rw-r--r--js/src/tests/non262/RegExp/everything.js47
-rw-r--r--js/src/tests/non262/RegExp/exec-002.js186
-rw-r--r--js/src/tests/non262/RegExp/exec-lastIndex-ToInteger.js36
-rw-r--r--js/src/tests/non262/RegExp/exec-lastIndex-negative.js27
-rw-r--r--js/src/tests/non262/RegExp/exec.js240
-rw-r--r--js/src/tests/non262/RegExp/flag-accessors.js49
-rw-r--r--js/src/tests/non262/RegExp/flags-param-handling.js18
-rw-r--r--js/src/tests/non262/RegExp/flags.js26
-rw-r--r--js/src/tests/non262/RegExp/getter-name.js16
-rw-r--r--js/src/tests/non262/RegExp/ignoreCase-multiple.js71
-rw-r--r--js/src/tests/non262/RegExp/ignoreCase-non-latin1-to-latin1.js118
-rw-r--r--js/src/tests/non262/RegExp/instance-property-storage-introspection.js128
-rw-r--r--js/src/tests/non262/RegExp/lastIndex-exec.js80
-rw-r--r--js/src/tests/non262/RegExp/lastIndex-match-or-replace.js123
-rw-r--r--js/src/tests/non262/RegExp/lastIndex-nonwritable.js27
-rw-r--r--js/src/tests/non262/RegExp/lastIndex-search.js118
-rw-r--r--js/src/tests/non262/RegExp/match-local-tolength-recompilation.js75
-rw-r--r--js/src/tests/non262/RegExp/match-this.js12
-rw-r--r--js/src/tests/non262/RegExp/match-trace.js142
-rw-r--r--js/src/tests/non262/RegExp/match.js36
-rw-r--r--js/src/tests/non262/RegExp/multiline-001.js67
-rw-r--r--js/src/tests/non262/RegExp/octal-001.js77
-rw-r--r--js/src/tests/non262/RegExp/octal-002.js92
-rw-r--r--js/src/tests/non262/RegExp/octal-003.js86
-rw-r--r--js/src/tests/non262/RegExp/oom-in-construction.js17
-rw-r--r--js/src/tests/non262/RegExp/perlstress-001.js3194
-rw-r--r--js/src/tests/non262/RegExp/perlstress-002.js1806
-rw-r--r--js/src/tests/non262/RegExp/properties-001.js87
-rw-r--r--js/src/tests/non262/RegExp/properties-002.js128
-rw-r--r--js/src/tests/non262/RegExp/prototype-different-global.js28
-rw-r--r--js/src/tests/non262/RegExp/prototype.js37
-rw-r--r--js/src/tests/non262/RegExp/regexp-enumerate-001.js79
-rw-r--r--js/src/tests/non262/RegExp/regexp-space-character-class.js27
-rw-r--r--js/src/tests/non262/RegExp/regress-001.js44
-rw-r--r--js/src/tests/non262/RegExp/regress-100199.js271
-rw-r--r--js/src/tests/non262/RegExp/regress-105972.js121
-rw-r--r--js/src/tests/non262/RegExp/regress-119909.js55
-rw-r--r--js/src/tests/non262/RegExp/regress-122076.js76
-rw-r--r--js/src/tests/non262/RegExp/regress-123437.js76
-rw-r--r--js/src/tests/non262/RegExp/regress-165353.js86
-rw-r--r--js/src/tests/non262/RegExp/regress-169497.js69
-rw-r--r--js/src/tests/non262/RegExp/regress-169534.js58
-rw-r--r--js/src/tests/non262/RegExp/regress-187133.js106
-rw-r--r--js/src/tests/non262/RegExp/regress-188206.js182
-rw-r--r--js/src/tests/non262/RegExp/regress-191479.js162
-rw-r--r--js/src/tests/non262/RegExp/regress-202564.js65
-rw-r--r--js/src/tests/non262/RegExp/regress-209919.js138
-rw-r--r--js/src/tests/non262/RegExp/regress-216591.js81
-rw-r--r--js/src/tests/non262/RegExp/regress-220367-001.js68
-rw-r--r--js/src/tests/non262/RegExp/regress-223273.js242
-rw-r--r--js/src/tests/non262/RegExp/regress-223535.js97
-rw-r--r--js/src/tests/non262/RegExp/regress-224676.js190
-rw-r--r--js/src/tests/non262/RegExp/regress-225289.js140
-rw-r--r--js/src/tests/non262/RegExp/regress-225343.js89
-rw-r--r--js/src/tests/non262/RegExp/regress-24712.js19
-rw-r--r--js/src/tests/non262/RegExp/regress-285219.js18
-rw-r--r--js/src/tests/non262/RegExp/regress-28686.js17
-rw-r--r--js/src/tests/non262/RegExp/regress-305064.js54
-rw-r--r--js/src/tests/non262/RegExp/regress-309840.js24
-rw-r--r--js/src/tests/non262/RegExp/regress-312351.js17
-rw-r--r--js/src/tests/non262/RegExp/regress-31316.js60
-rw-r--r--js/src/tests/non262/RegExp/regress-330684.js21
-rw-r--r--js/src/tests/non262/RegExp/regress-334158.js25
-rw-r--r--js/src/tests/non262/RegExp/regress-346090.js26
-rw-r--r--js/src/tests/non262/RegExp/regress-367888.js26
-rw-r--r--js/src/tests/non262/RegExp/regress-375642.js25
-rw-r--r--js/src/tests/non262/RegExp/regress-375651.js26
-rw-r--r--js/src/tests/non262/RegExp/regress-375711.js82
-rw-r--r--js/src/tests/non262/RegExp/regress-375715-01-n.js27
-rw-r--r--js/src/tests/non262/RegExp/regress-375715-02.js24
-rw-r--r--js/src/tests/non262/RegExp/regress-375715-03.js24
-rw-r--r--js/src/tests/non262/RegExp/regress-375715-04.js32
-rw-r--r--js/src/tests/non262/RegExp/regress-429241.js200
-rw-r--r--js/src/tests/non262/RegExp/regress-436700.js31
-rw-r--r--js/src/tests/non262/RegExp/regress-465862.js80
-rw-r--r--js/src/tests/non262/RegExp/regress-57572.js114
-rw-r--r--js/src/tests/non262/RegExp/regress-57631.js115
-rw-r--r--js/src/tests/non262/RegExp/regress-576828.js8
-rw-r--r--js/src/tests/non262/RegExp/regress-613820-1.js9
-rw-r--r--js/src/tests/non262/RegExp/regress-613820-2.js9
-rw-r--r--js/src/tests/non262/RegExp/regress-613820-3.js9
-rw-r--r--js/src/tests/non262/RegExp/regress-617935.js42
-rw-r--r--js/src/tests/non262/RegExp/regress-6359.js52
-rw-r--r--js/src/tests/non262/RegExp/regress-67773.js175
-rw-r--r--js/src/tests/non262/RegExp/regress-72964.js85
-rw-r--r--js/src/tests/non262/RegExp/regress-76683.js78
-rw-r--r--js/src/tests/non262/RegExp/regress-78156.js87
-rw-r--r--js/src/tests/non262/RegExp/regress-85721.js243
-rw-r--r--js/src/tests/non262/RegExp/regress-87231.js109
-rw-r--r--js/src/tests/non262/RegExp/regress-9141.js71
-rw-r--r--js/src/tests/non262/RegExp/regress-98306.js63
-rw-r--r--js/src/tests/non262/RegExp/regress-yarr-regexp.js18
-rw-r--r--js/src/tests/non262/RegExp/replace-compile-elembase.js22
-rw-r--r--js/src/tests/non262/RegExp/replace-compile.js21
-rw-r--r--js/src/tests/non262/RegExp/replace-global-unicode.js18
-rw-r--r--js/src/tests/non262/RegExp/replace-local-tolength-lastindex.js22
-rw-r--r--js/src/tests/non262/RegExp/replace-local-tolength-recompilation.js75
-rw-r--r--js/src/tests/non262/RegExp/replace-sticky-lastIndex.js23
-rw-r--r--js/src/tests/non262/RegExp/replace-sticky.js21
-rw-r--r--js/src/tests/non262/RegExp/replace-this.js12
-rw-r--r--js/src/tests/non262/RegExp/replace-trace.js299
-rw-r--r--js/src/tests/non262/RegExp/replace-twoBytes.js44
-rw-r--r--js/src/tests/non262/RegExp/replace.js34
-rw-r--r--js/src/tests/non262/RegExp/search-this.js12
-rw-r--r--js/src/tests/non262/RegExp/search-trace.js78
-rw-r--r--js/src/tests/non262/RegExp/search.js26
-rw-r--r--js/src/tests/non262/RegExp/shell.js256
-rw-r--r--js/src/tests/non262/RegExp/source.js29
-rw-r--r--js/src/tests/non262/RegExp/split-deleted-flags.js11
-rw-r--r--js/src/tests/non262/RegExp/split-flags-on-obj.js21
-rw-r--r--js/src/tests/non262/RegExp/split-invalid-lastIndex.js31
-rw-r--r--js/src/tests/non262/RegExp/split-limit.js14
-rw-r--r--js/src/tests/non262/RegExp/split-obj.js12
-rw-r--r--js/src/tests/non262/RegExp/split-prop-access.js19
-rw-r--r--js/src/tests/non262/RegExp/split-this.js12
-rw-r--r--js/src/tests/non262/RegExp/split-trace.js229
-rw-r--r--js/src/tests/non262/RegExp/split.js30
-rw-r--r--js/src/tests/non262/RegExp/sticky.js126
-rw-r--r--js/src/tests/non262/RegExp/test-emptyMatch.js23
-rw-r--r--js/src/tests/non262/RegExp/test-trailing.js31
-rw-r--r--js/src/tests/non262/RegExp/toString.js42
-rw-r--r--js/src/tests/non262/RegExp/unicode-back-reference.js39
-rw-r--r--js/src/tests/non262/RegExp/unicode-braced.js166
-rw-r--r--js/src/tests/non262/RegExp/unicode-character-class-escape.js75
-rw-r--r--js/src/tests/non262/RegExp/unicode-class-braced.js236
-rw-r--r--js/src/tests/non262/RegExp/unicode-class-empty.js25
-rw-r--r--js/src/tests/non262/RegExp/unicode-class-ignoreCase.js28
-rw-r--r--js/src/tests/non262/RegExp/unicode-class-lead-trail.js142
-rw-r--r--js/src/tests/non262/RegExp/unicode-class-negated.js64
-rw-r--r--js/src/tests/non262/RegExp/unicode-class-range.js28
-rw-r--r--js/src/tests/non262/RegExp/unicode-class-raw.js65
-rw-r--r--js/src/tests/non262/RegExp/unicode-disallow-extended.js139
-rw-r--r--js/src/tests/non262/RegExp/unicode-everything.js59
-rw-r--r--js/src/tests/non262/RegExp/unicode-ignoreCase-ascii.js45
-rw-r--r--js/src/tests/non262/RegExp/unicode-ignoreCase-escape.js71
-rw-r--r--js/src/tests/non262/RegExp/unicode-ignoreCase-negated.js19
-rw-r--r--js/src/tests/non262/RegExp/unicode-ignoreCase-word-boundary.js46
-rw-r--r--js/src/tests/non262/RegExp/unicode-ignoreCase.js2901
-rw-r--r--js/src/tests/non262/RegExp/unicode-index.js17
-rw-r--r--js/src/tests/non262/RegExp/unicode-lead-trail.js218
-rw-r--r--js/src/tests/non262/RegExp/unicode-raw.js139
-rw-r--r--js/src/tests/non262/RegExp/yflag.js85
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);
+}