msaboff@apple.com | 5e9b065 | 2016-03-02 00:39:01 +0000 | [diff] [blame] | 1 | description( |
| 2 | 'Test for unicode regular expression processing' |
| 3 | ); |
| 4 | |
| 5 | // Test \u{} escapes in a regular expression |
msaboff@apple.com | 5bc3906 | 2016-03-04 01:24:28 +0000 | [diff] [blame] | 6 | shouldBe('"a".match(/\u{61}/u)[0].length', '1'); |
| 7 | shouldBe('"a".match(/\u{41}/ui)[0].length', '1'); |
msaboff@apple.com | 5e9b065 | 2016-03-02 00:39:01 +0000 | [diff] [blame] | 8 | shouldBe('"a".match(/\u{061}/u)[0].length', '1'); |
| 9 | shouldBe('"a".match(/\u{041}/iu)[0].length', '1'); |
msaboff@apple.com | 5bc3906 | 2016-03-04 01:24:28 +0000 | [diff] [blame] | 10 | shouldBe('"\u{212}".match(/\u{212}/u)[0].length', '1'); |
msaboff@apple.com | 5e9b065 | 2016-03-02 00:39:01 +0000 | [diff] [blame] | 11 | shouldBe('"\u{212}".match(/\u{0212}/u)[0].length', '1'); |
msaboff@apple.com | 5bc3906 | 2016-03-04 01:24:28 +0000 | [diff] [blame] | 12 | shouldBe('"\u{1234}".match(/\u{1234}/u)[0].length', '1'); |
msaboff@apple.com | 5e9b065 | 2016-03-02 00:39:01 +0000 | [diff] [blame] | 13 | shouldBe('"\u{1234}".match(/\u{01234}/u)[0].length', '1'); |
msaboff@apple.com | 5bc3906 | 2016-03-04 01:24:28 +0000 | [diff] [blame] | 14 | shouldBe('"\u{2abc}".match(/\u{2abc}/u)[0].length', '1'); |
msaboff@apple.com | 5e9b065 | 2016-03-02 00:39:01 +0000 | [diff] [blame] | 15 | shouldBe('"\u{03fed}".match(/\u{03fed}/u)[0].length', '1'); |
| 16 | shouldBe('"\u{12345}".match(/\u{12345}/u)[0].length', '2'); |
| 17 | shouldBe('"\u{12345}".match(/\u{012345}/u)[0].length', '2'); |
msaboff@apple.com | 5bc3906 | 2016-03-04 01:24:28 +0000 | [diff] [blame] | 18 | shouldBe('"\u{1d306}".match(/\u{1d306}/u)[0].length', '2'); |
msaboff@apple.com | 5e9b065 | 2016-03-02 00:39:01 +0000 | [diff] [blame] | 19 | shouldBeTrue('/\u{1044f}/u.test("\ud801\udc4f")'); |
| 20 | shouldBeTrue('/\ud801\udc4f/u.test("\u{1044f}")'); |
| 21 | |
| 22 | // Test basic unicode flag processing |
| 23 | shouldBe('"\u{1d306}".match(/\u{1d306}/u)[0].length', '2'); |
| 24 | shouldBeTrue('/(\u{10000}|\u{10400}|\u{10429})/u.test("\u{10400}")'); |
| 25 | shouldBe('"\u{10123}".match(/a|\u{10123}|b/u)[0].length', '2'); |
| 26 | shouldBe('"b".match(/a|\u{10123}|b/u)[0].length', '1'); |
| 27 | shouldBeFalse('/(?:a|\u{10123}|b)x/u.test("\u{10123}")'); |
| 28 | shouldBeTrue('/(?:a|\u{10123}|b)x/u.test("\u{10123}x")'); |
| 29 | shouldBeFalse('/(?:a|\u{10123}|b)x/u.test("b")'); |
| 30 | shouldBeTrue('/(?:a|\u{10123}|b)x/u.test("bx")'); |
| 31 | shouldBe('"a\u{10123}x".match(/a\u{10123}b|a\u{10123}x/u)[0].length', '4'); |
| 32 | |
| 33 | // Test unicode flag with ignore case |
| 34 | shouldBeTrue('/(\u{10000}|\u{10400}|\u{10429})x/ui.test("\u{10400}x")'); |
| 35 | shouldBeTrue('/(\u{10000}|\u{10400}|\u{10429})x/ui.test("\u{10429}x")'); |
| 36 | shouldBeTrue('/(\u{10000}|\u{10400}|\u{10429})x/ui.test("\u{10401}x")'); |
| 37 | shouldBeTrue('/(\u{10000}|\u{10400}|\u{10429})x/ui.test("\u{10428}x")'); |
| 38 | shouldBe('"\u{10429}".match(/a|\u{10401}|b/iu)[0].length', '2'); |
| 39 | shouldBe('"B".match(/a|\u{10123}|b/iu)[0].length', '1'); |
| 40 | shouldBeFalse('/(?:A|\u{10123}|b)x/iu.test("\u{10123}")'); |
| 41 | shouldBeTrue('/(?:A|\u{10123}|b)x/iu.test("\u{10123}x")'); |
| 42 | shouldBeFalse('/(?:A|\u{10123}|b)x/iu.test("b")'); |
| 43 | shouldBeTrue('/(?:A|\u{10123}|b)x/iu.test("bx")'); |
| 44 | shouldBe('"a\u{10123}X".match(/a\u{10123}b|a\u{10123}x/iu)[0].length', '4'); |
| 45 | shouldBe('"\u0164x".match(/\u0165x/iu)[0].length', '2'); |
msaboff@apple.com | 330ae11 | 2016-04-14 00:47:40 +0000 | [diff] [blame] | 46 | shouldBeTrue('/\\w/iu.test("\u017f")'); |
| 47 | shouldBeTrue('/\\w/iu.test("\u212a")'); |
msaboff@apple.com | 080c609 | 2016-06-27 17:38:55 +0000 | [diff] [blame] | 48 | shouldBeFalse('/\\W/iu.test("\u017f")'); |
| 49 | shouldBeFalse('/\\W/iu.test("\u212a")'); |
msaboff@apple.com | 330ae11 | 2016-04-14 00:47:40 +0000 | [diff] [blame] | 50 | shouldBeTrue('/[\\w\\d]/iu.test("\u017f")'); |
| 51 | shouldBeTrue('/[\\w\\d]/iu.test("\u212a")'); |
| 52 | shouldBeFalse('/[^\\w\\d]/iu.test("\u017f")'); |
| 53 | shouldBeFalse('/[^\\w\\d]/iu.test("\u212a")'); |
msaboff@apple.com | 080c609 | 2016-06-27 17:38:55 +0000 | [diff] [blame] | 54 | shouldBeFalse('/[\\W\\d]/iu.test("\u017f")'); |
| 55 | shouldBeFalse('/[\\W\\d]/iu.test("\u212a")'); |
| 56 | shouldBeTrue('/[^\\W\\d]/iu.test("\u017f")'); |
| 57 | shouldBeTrue('/[^\\W\\d]/iu.test("\u212a")'); |
msaboff@apple.com | 330ae11 | 2016-04-14 00:47:40 +0000 | [diff] [blame] | 58 | shouldBeTrue('/\\w/iu.test("S")'); |
| 59 | shouldBeTrue('/\\w/iu.test("K")'); |
msaboff@apple.com | 080c609 | 2016-06-27 17:38:55 +0000 | [diff] [blame] | 60 | shouldBeFalse('/\\W/iu.test("S")'); |
| 61 | shouldBeFalse('/\\W/iu.test("K")'); |
msaboff@apple.com | 330ae11 | 2016-04-14 00:47:40 +0000 | [diff] [blame] | 62 | shouldBeTrue('/[\\w\\d]/iu.test("S")'); |
| 63 | shouldBeTrue('/[\\w\\d]/iu.test("K")'); |
| 64 | shouldBeFalse('/[^\\w\\d]/iu.test("S")'); |
| 65 | shouldBeFalse('/[^\\w\\d]/iu.test("K")'); |
msaboff@apple.com | 080c609 | 2016-06-27 17:38:55 +0000 | [diff] [blame] | 66 | shouldBeFalse('/[\\W\\d]/iu.test("S")'); |
| 67 | shouldBeFalse('/[\\W\\d]/iu.test("K")'); |
| 68 | shouldBeTrue('/[^\\W\\d]/iu.test("S")'); |
| 69 | shouldBeTrue('/[^\\W\\d]/iu.test("K")'); |
| 70 | shouldBe('"Gras\u017foden is old German for grass".match(/.*?\\Bs\\u017foden/iu)[0]', '"Gras\u017foden"'); |
| 71 | shouldBe('"Gras\u017foden is old German for grass".match(/.*?\\B\\u017foden/iu)[0]', '"Gras\u017foden"'); |
| 72 | shouldBe('"Gras\u017foden is old German for grass".match(/.*?\\Boden/iu)[0]', '"Gras\u017foden"'); |
| 73 | shouldBe('"Gras\u017foden is old German for grass".match(/.*?\\Bden/iu)[0]', '"Gras\u017foden"'); |
| 74 | shouldBe('"Water freezes at 273\u212a which is 0C.".split(/\\b\\s/iu)', '["Water","freezes","at","273\u212a","which","is","0C."]'); |
msaboff@apple.com | 5e9b065 | 2016-03-02 00:39:01 +0000 | [diff] [blame] | 75 | |
| 76 | // Test . matches with Unicode flag |
| 77 | shouldBe('"\u{1D306}".match(/^.$/u)[0].length', '2'); |
| 78 | shouldBe('"It is 78\u00B0".match(/.*/u)[0].length', '9'); |
msaboff@apple.com | 5bc3906 | 2016-03-04 01:24:28 +0000 | [diff] [blame] | 79 | var stringWithDanglingFirstSurrogate = "X\uD801X"; |
| 80 | shouldBe('stringWithDanglingFirstSurrogate.match(/.*/u)[0].length', '3'); // We should match a dangling first surrogate as 1 character |
| 81 | var stringWithDanglingSecondSurrogate = "X\uDF01X"; |
| 82 | shouldBe('stringWithDanglingSecondSurrogate.match(/.*/u)[0].length', '3'); // We should match a dangling second surrogate as 1 character |
msaboff@apple.com | 5e9b065 | 2016-03-02 00:39:01 +0000 | [diff] [blame] | 83 | |
| 84 | // Test character classes with unicode characters with and without unicode flag |
msaboff@apple.com | 5bc3906 | 2016-03-04 01:24:28 +0000 | [diff] [blame] | 85 | shouldBe('"\u{1d306}".match(/[\uD834\uDF06a]/)[0].length', '1'); |
msaboff@apple.com | 5e9b065 | 2016-03-02 00:39:01 +0000 | [diff] [blame] | 86 | shouldBe('"\u{1d306}".match(/[a\u{1d306}]/u)[0].length', '2'); |
| 87 | shouldBe('"\u{1d306}".match(/[\u{1d306}a]/u)[0].length', '2'); |
msaboff@apple.com | 5bc3906 | 2016-03-04 01:24:28 +0000 | [diff] [blame] | 88 | shouldBe('"\u{1d306}".match(/[a-\uD834\uDF06]/)[0].length', '1'); |
msaboff@apple.com | 5e9b065 | 2016-03-02 00:39:01 +0000 | [diff] [blame] | 89 | shouldBe('"\u{1d306}".match(/[a-\u{1d306}]/u)[0].length', '2'); |
| 90 | |
| 91 | // Test a character class that is a range from one UTF16 to a Unicode character |
| 92 | shouldBe('"X".match(/[\u0020-\ud801\udc4f]/u)[0].length', '1'); |
| 93 | shouldBe('"\u1000".match(/[\u0020-\ud801\udc4f]/u)[0].length', '1'); |
| 94 | shouldBe('"\ud801\udc27".match(/[\u0020-\ud801\udc4f]/u)[0].length', '2'); |
| 95 | |
msaboff@apple.com | 5bc3906 | 2016-03-04 01:24:28 +0000 | [diff] [blame] | 96 | var re1 = new RegExp("[^\u0020-\uD801\uDC4F]", "u"); |
msaboff@apple.com | 5e9b065 | 2016-03-02 00:39:01 +0000 | [diff] [blame] | 97 | shouldBeFalse('re1.test("Z")'); |
| 98 | shouldBeFalse('re1.test("\u{1000}")'); |
| 99 | shouldBeFalse('re1.test("\u{10400}")'); |
| 100 | |
| 101 | var re2 = new RegExp("[a-z\u{10000}-\u{15000}]", "iu"); |
| 102 | shouldBeTrue('re2.test("A")'); |
| 103 | shouldBeFalse('re2.test("\uffff")'); |
| 104 | shouldBeTrue('re2.test("\u{12345}")'); |
| 105 | |
| 106 | // Make sure we properly handle dangling surrogates and combined surrogates |
| 107 | // FIXME: These tests are disabled until https://bugs.webkit.org/show_bug.cgi?id=154863 is fixed |
| 108 | // shouldBe('/[\u{10c01}\uD803#\uDC01]/u.exec("\u{10c01}").toString()', '"\u{10c01}"'); |
| 109 | // shouldBe('/[\uD803\u{10c01}\uDC01]/u.exec("\u{10c01}").toString()', '"\u{10c01}"'); |
| 110 | // shouldBe('/[\uD803#\uDC01\u{10c01}]/u.exec("\u{10c01}").toString()', '"\u{10c01}"'); |
| 111 | // shouldBe('/[\uD803\uD803\uDC01\uDC01]/u.exec("\u{10c01}").toString()', '"\u{10c01}"'); |
| 112 | // shouldBeNull('/[\u{10c01}\uD803#\uDC01]{2}/u.exec("\u{10c01}")'); |
| 113 | // shouldBeNull('/[\uD803\u{10c01}\uDC01]{2}/u.exec("\u{10c01}")'); |
| 114 | // shouldBeNull('/[\uD803#\uDC01\u{10c01}]{2}/u.exec("\u{10c01}")'); |
| 115 | // shouldBeNull('/[\uD803\uD803\uDC01\uDC01]{2}/u.exec("\u{10c01}")'); |
| 116 | // shouldBe('/\uD803|\uDC01|\u{10c01}/u.exec("\u{10c01}").toString()', '"\u{10c01}"'); |
| 117 | // shouldBe('/\uD803|\uD803\uDC01|\uDC01/u.exec("\u{10c01}").toString()', '"\u{10c01}"'); |
| 118 | // shouldBe('/\uD803|\uDC01|\u{10c01}/u.exec("\u{D803}").toString()', '"\u{D803}"'); |
| 119 | // shouldBe('/\uD803|\uD803\uDC01|\uDC01/u.exec("\u{DC01}").toString()', '"\u{DC01}"'); |
| 120 | // shouldBeNull('/\uD803\u{10c01}/u.exec("\u{10c01}")'); |
| 121 | // shouldBeNull('/\uD803\u{10c01}/u.exec("\uD803")'); |
| 122 | // shouldBe('"\uD803\u{10c01}".match(/\uD803\u{10c01}/u)[0].length', '3'); |
| 123 | |
msaboff@apple.com | f3669c7 | 2016-03-31 00:38:20 +0000 | [diff] [blame] | 124 | // Check quantified matches |
| 125 | shouldBeTrue('/\u{1d306}{2}/u.test("\u{1d306}\u{1d306}")'); |
| 126 | shouldBeTrue('/\uD834\uDF06{2}/u.test("\uD834\uDF06\uD834\uDF06")'); |
msaboff@apple.com | 6e73b41 | 2017-08-22 22:43:08 +0000 | [diff] [blame] | 127 | shouldBe('"\u{10405}\u{10405}\u{10405}\u{10405}".match(/\u{10405}{3}/u)[0]', '"\u{10405}\u{10405}\u{10405}"'); |
| 128 | shouldBe('"\u{10402}\u{10405}\u{10405}\u{10405}".match(/\u{10405}{3}/u)[0]', '"\u{10405}\u{10405}\u{10405}"'); |
msaboff@apple.com | f3669c7 | 2016-03-31 00:38:20 +0000 | [diff] [blame] | 129 | shouldBe('"\u{10401}\u{10401}\u{10400}".match(/\u{10401}{1,3}/u)[0]', '"\u{10401}\u{10401}"'); |
| 130 | shouldBe('"\u{10401}\u{10429}".match(/\u{10401}{1,3}/iu)[0]', '"\u{10401}\u{10429}"'); |
| 131 | shouldBe('"\u{10401}\u{10429}\u{1042a}\u{10429}".match(/\u{10401}{1,}/iu)[0]', '"\u{10401}\u{10429}"'); |
| 132 | |
msaboff@apple.com | 5e9b065 | 2016-03-02 00:39:01 +0000 | [diff] [blame] | 133 | // Check back tracking on partial matches |
| 134 | shouldBe('"\u{10311}\u{10311}\u{10311}".match(/\u{10311}*a|\u{10311}*./u)[0]', '"\u{10311}\u{10311}\u{10311}"'); |
| 135 | shouldBe('"a\u{10311}\u{10311}".match(/a\u{10311}*?$/u)[0]', '"a\u{10311}\u{10311}"'); |
| 136 | shouldBe('"a\u{10311}\u{10311}\u{10311}c".match(/a\u{10311}*cd|a\u{10311}*c/u)[0]', '"a\u{10311}\u{10311}\u{10311}c"'); |
| 137 | shouldBe('"a\u{10311}\u{10311}\u{10311}c".match(/a\u{10311}+cd|a\u{10311}+c/u)[0]', '"a\u{10311}\u{10311}\u{10311}c"'); |
| 138 | shouldBe('"\u{10311}\u{10311}\u{10311}".match(/\u{10311}+?a|\u{10311}+?./u)[0]', '"\u{10311}\u{10311}"'); |
| 139 | shouldBe('"\u{10311}\u{10311}\u{10311}".match(/\u{10311}+?a|\u{10311}+?$/u)[0]', '"\u{10311}\u{10311}\u{10311}"'); |
| 140 | shouldBe('"a\u{10311}\u{10311}\u{10311}c".match(/a\u{10311}*?cd|a\u{10311}*?c/u)[0]', '"a\u{10311}\u{10311}\u{10311}c"'); |
| 141 | shouldBe('"a\u{10311}\u{10311}\u{10311}c".match(/a\u{10311}+?cd|a\u{10311}+?c/u)[0]', '"a\u{10311}\u{10311}\u{10311}c"'); |
| 142 | shouldBe('"\u{10311}\u{10311}\u{10311}".match(/\u{10311}+?a|\u{10311}+?./iu)[0]', '"\u{10311}\u{10311}"'); |
| 143 | shouldBe('"\u{1042a}\u{1042a}\u{10311}".match(/\u{10402}*\u{10200}|\u{10402}*\u{10311}/iu)[0]', '"\u{1042a}\u{1042a}\u{10311}"'); |
| 144 | shouldBe('"\u{1042a}\u{1042a}\u{10311}".match(/\u{10402}+\u{10200}|\u{10402}+\u{10311}/iu)[0]', '"\u{1042a}\u{1042a}\u{10311}"'); |
| 145 | shouldBe('"\u{1042a}\u{1042a}\u{10311}".match(/\u{10402}*?\u{10200}|\u{10402}*?\u{10311}/iu)[0]', '"\u{1042a}\u{1042a}\u{10311}"'); |
| 146 | shouldBe('"\u{1042a}\u{1042a}\u{10311}".match(/\u{10402}+?\u{10200}|\u{10402}+?\u{10311}/iu)[0]', '"\u{1042a}\u{1042a}\u{10311}"'); |
| 147 | shouldBe('"ab\u{10311}c\u{10a01}".match(/abc|ab\u{10311}cd|ab\u{10311}c\u{10a01}d|ab\u{10311}c\u{10a01}/u)[0]', '"ab\u{10311}c\u{10a01}"'); |
| 148 | shouldBe('"ab\u{10428}c\u{10a01}".match(/abc|ab\u{10400}cd|ab\u{10400}c\u{10a01}d|ab\u{10400}c\u{10a01}/iu)[0]', '"ab\u{10428}c\u{10a01}"'); |
| 149 | shouldBeFalse('/abc|ab\u{10400}cd|ab\u{10400}c\u{10a01}d|ab\u{10400}c\u{10a01}/iu.test("qwerty123")'); |
| 150 | shouldBe('"a\u{10428}\u{10428}\u{10428}c".match(/ac|a\u{10400}*cd|a\u{10400}+cd|a\u{10400}+c/iu)[0]', '"a\u{10428}\u{10428}\u{10428}c"'); |
| 151 | shouldBe('"ab\u{10428}\u{10428}\u{10428}c\u{10a01}".match(/abc|ab\u{10400}*cd|ab\u{10400}+c\u{10a01}d|ab\u{10400}+c\u{10a01}/iu)[0]', '"ab\u{10428}\u{10428}\u{10428}c\u{10a01}"'); |
| 152 | shouldBe('"ab\u{10428}\u{10428}\u{10428}".match(/abc|ab\u{10428}*./u)[0]', '"ab\u{10428}\u{10428}\u{10428}"'); |
| 153 | shouldBe('"ab\u{10428}\u{10428}\u{10428}".match(/abc|ab\u{10400}*./iu)[0]', '"ab\u{10428}\u{10428}\u{10428}"'); |
msaboff@apple.com | 6094e9a | 2016-03-24 14:19:37 +0000 | [diff] [blame] | 154 | shouldBe('"\u{10400}".match(/a*/u)[0].length', '0'); |
| 155 | shouldBe('"\u{10400}".match(/a*/ui)[0].length', '0'); |
| 156 | shouldBe('"\u{10400}".match(/\\d*/u)[0].length', '0'); |
| 157 | shouldBe('"123\u{10400}".match(/\\d*/u)[0]', '"123"'); |
| 158 | shouldBe('"12X3\u{10400}4".match(/\\d{0,1}/ug)', '["1", "2", "", "3", "", "4", ""]'); |
msaboff@apple.com | 6e73b41 | 2017-08-22 22:43:08 +0000 | [diff] [blame] | 159 | shouldBe('"\u{10402}\u{10405}\u{10405}\u{10402}\u{10405}\u{10405}\u{10405}".match(/\u{10405}{3}/u)[0]', '"\u{10405}\u{10405}\u{10405}"'); |
msaboff@apple.com | e020e96 | 2017-08-23 22:24:30 +0000 | [diff] [blame] | 160 | shouldBe('"a\u{10410}\u{10410}b".match(/a(\u{10410}*?)bc|a(\u{10410}*?)b/ui)[0]', '"a\u{10410}\u{10410}b"'); |
msaboff@apple.com | 5e9b065 | 2016-03-02 00:39:01 +0000 | [diff] [blame] | 161 | |
| 162 | var re3 = new RegExp("(a\u{10410}*bc)|(a\u{10410}*b)", "u"); |
| 163 | var match3 = "a\u{10410}\u{10410}b".match(re3); |
| 164 | shouldBe('match3[0]', '"a\u{10410}\u{10410}b"'); |
| 165 | shouldBeUndefined('match3[1]'); |
| 166 | shouldBe('match3[2]', '"a\u{10410}\u{10410}b"'); |
| 167 | |
| 168 | var re4 = new RegExp("a(\u{10410}*)bc|a(\u{10410}*)b", "ui"); |
| 169 | var match4 = "a\u{10438}\u{10438}b".match(re4); |
| 170 | shouldBe('match4[0]', '"a\u{10438}\u{10438}b"'); |
| 171 | shouldBeUndefined('match4[1]'); |
| 172 | shouldBe('match4[2]', '"\u{10438}\u{10438}"'); |
| 173 | |
| 174 | var match5 = "a\u{10412}\u{10412}b\u{10412}\u{10412}".match(/a(\u{10412}*)bc\1|a(\u{10412}*)b\2/u); |
| 175 | shouldBe('match5[0]', '"a\u{10412}\u{10412}b\u{10412}\u{10412}"'); |
| 176 | shouldBeUndefined('match5[1]'); |
| 177 | shouldBe('match5[2]', '"\u{10412}\u{10412}"'); |
| 178 | |
| 179 | var match6 = "a\u{10412}\u{10412}b\u{1043a}\u{10412}\u{1043a}".match(/a(\u{1043a}*)bc\1|a(\u{1043a}*)b\2/iu); |
| 180 | shouldBe('match6[0]', '"a\u{10412}\u{10412}b\u{1043a}\u{10412}"'); |
| 181 | shouldBeUndefined('match6[1]'); |
| 182 | shouldBe('match6[2]', '"\u{10412}\u{10412}"'); |
| 183 | |
msaboff@apple.com | 5bc3906 | 2016-03-04 01:24:28 +0000 | [diff] [blame] | 184 | // Check unicode case insensitive matches |
msaboff@apple.com | 94db89d | 2016-03-08 18:35:58 +0000 | [diff] [blame] | 185 | shouldBeTrue('/\u017ftop/ui.test("stop")'); |
| 186 | shouldBeTrue('/stop/ui.test("\u017ftop")'); |
| 187 | shouldBeTrue('/\u212aelvin/ui.test("kelvin")'); |
| 188 | shouldBeTrue('/KELVIN/ui.test("\u212aelvin")'); |
msaboff@apple.com | 5bc3906 | 2016-03-04 01:24:28 +0000 | [diff] [blame] | 189 | |
| 190 | // Verify that without the unicode flag, \u{} doesn't parse to a unicode escapes, but to a counted match of the character 'u'. |
| 191 | shouldBeTrue('/\\u{1}/.test("u")'); |
| 192 | shouldBeFalse('/\\u{4}/.test("u")'); |
| 193 | shouldBeTrue('/\\u{4}/.test("uuuu")'); |
| 194 | |
| 195 | // Check that \- escape works in a character class for a unicode pattern |
| 196 | shouldBe('"800-555-1212".match(/[0-9\\-]*/u)[0].length', '12'); |
| 197 | |
msaboff@apple.com | 6e73b41 | 2017-08-22 22:43:08 +0000 | [diff] [blame] | 198 | // Check that counted Unicode character classes work. |
| 199 | var re7 = new RegExp("(?:[\u{1f0a1}\u{1f0b1}\u{1f0d1}\u{1f0c1}]{2,4})", "u"); |
| 200 | shouldBe('"\u{1f0a1}\u{1f0d1}\u{1f0b8}\u{1f0c9}\u{1f0da}".match(re7)[0]', '"\u{1f0a1}\u{1f0d1}"'); |
| 201 | shouldBe('"\u{1f0a1}\u{1f0d1}\u{1f0b1}\u{1f0c9}\u{1f0da}".match(re7)[0]', '"\u{1f0a1}\u{1f0d1}\u{1f0b1}"'); |
| 202 | shouldBe('"\u{1f0a1}\u{1f0d1}\u{1f0b1}\u{1f0c1}\u{1f0da}".match(re7)[0]', '"\u{1f0a1}\u{1f0d1}\u{1f0b1}\u{1f0c1}"'); |
| 203 | shouldBe('"\u{1f0a3}\u{1f0d1}\u{1f0b1}\u{1f0c1}\u{1f0da}".match(re7)[0]', '"\u{1f0d1}\u{1f0b1}\u{1f0c1}"'); |
| 204 | shouldBe('"\u{10311}\u{10310}\u{10311}".match(/[\u{10301}\u{10311}]*a|[\u{10310}\u{10311}]*./iu)[0]', '"\u{10311}\u{10310}\u{10311}"'); |
| 205 | shouldBe('"\u{10311}\u{10310}\u{10311}".match(/[\u{10301}\u{10311}]*?a|[\u{10310}\u{10311}]*?./iu)[0]', '"\u{10311}"'); |
| 206 | shouldBe('"\u{10311}\u{10310}\u{10311}".match(/[\u{10301}\u{10311}]+a|[\u{10310}\u{10311}]+./iu)[0]', '"\u{10311}\u{10310}\u{10311}"'); |
| 207 | shouldBe('"\u{10311}\u{10310}\u{10311}".match(/[\u{10301}\u{10311}]+?a|[\u{10310}\u{10311}]+?./iu)[0]', '"\u{10311}\u{10310}"'); |
| 208 | |
| 209 | var re8 = new RegExp("^([0-9a-z\.]{3,16})\\|\u{041d}\u{0410}\u{0427}\u{0410}\u{0422}\u{042c}", "ui"); |
| 210 | shouldBe('"C83|\u{041d}\u{0410}\u{0427}\u{0410}\u{0422}\u{042c}".match(re8)[0]', '"C83|\u{041d}\u{0410}\u{0427}\u{0410}\u{0422}\u{042c}"'); |
| 211 | shouldBe('"This.Is.16.Chars|\u{041d}\u{0410}\u{0427}\u{0410}\u{0422}\u{042c}".match(re8)[0]', '"This.Is.16.Chars|\u{041d}\u{0410}\u{0427}\u{0410}\u{0422}\u{042c}"'); |
| 212 | |
| 213 | // Check that unicode characters work with ^ and $ for multiline patterns |
| 214 | shouldBe('"Testing\\n\u{1234} 1 2 3".match(/^[\u{1000}-\u{100ff}] 1 2 3/um)[0]', '"\u{1234} 1 2 3"'); |
| 215 | shouldBe('"Testing\\n\u{100f0} 1 2 3".match(/^[\u{1000}-\u{100ff}] 1 2 3/um)[0]', '"\u{100f0} 1 2 3"'); |
| 216 | shouldBe('"g\\n\u{1234} 1 2 3".match(/g\\n^[\u{1000}-\u{100ff}] 1 2 3/um)[0]', '"g\\n\u{1234} 1 2 3"'); |
| 217 | shouldBe('"g\\n\u{100f0} 1 2 3".match(/g\\n^[\u{1000}-\u{100ff}] 1 2 3/um)[0]', '"g\\n\u{100f0} 1 2 3"'); |
| 218 | shouldBe('"Testing \u{1234}\\n1 2 3".match(/Testing [\u{1000}-\u{100ff}]$/um)[0]', '"Testing \u{1234}"'); |
| 219 | shouldBe('"Testing \u{100f0}\\n1 2 3".match(/Testing [\u{1000}-\u{100ff}]$/um)[0]', '"Testing \u{100f0}"'); |
| 220 | shouldBe('"Testing \u{1234}\\n1 2 3".match(/g [\u{1000}-\u{100ff}]$\\n1/um)[0]', '"g \u{1234}\\n1"'); |
| 221 | shouldBe('"Testing \u{100f0}\\n1 2 3".match(/g [\u{1000}-\u{100ff}]$\\n1/um)[0]', '"g \u{100f0}\\n1"'); |
| 222 | |
msaboff@apple.com | 5bc3906 | 2016-03-04 01:24:28 +0000 | [diff] [blame] | 223 | // Check that control letter escapes work with unicode flag |
| 224 | shouldBe('"this is b\ba test".match(/is b\\cha test/u)[0].length', '11'); |
| 225 | |
| 226 | // Check that invalid unicode patterns throw exceptions |
| 227 | shouldBe('new RegExp("\\\\/", "u").source', '"\\\\/"'); |
| 228 | shouldThrow('r = new RegExp("\\\\u{110000}", "u")', '"SyntaxError: Invalid regular expression: invalid unicode {} escape"'); |
msaboff@apple.com | 6e73b41 | 2017-08-22 22:43:08 +0000 | [diff] [blame] | 229 | shouldThrow('r = new RegExp("\u{10405}{2147483648}", "u")', '"SyntaxError: Invalid regular expression: pattern exceeds string length limits"'); |
msaboff@apple.com | 5bc3906 | 2016-03-04 01:24:28 +0000 | [diff] [blame] | 230 | |
| 231 | var invalidEscapeException = "SyntaxError: Invalid regular expression: invalid escaped character for unicode pattern"; |
| 232 | var newRegExp; |
| 233 | |
oliver@apple.com | 3909b16 | 2016-06-06 17:31:28 +0000 | [diff] [blame] | 234 | function shouldThrowInvalidEscape(pattern, error='invalidEscapeException') |
msaboff@apple.com | 5bc3906 | 2016-03-04 01:24:28 +0000 | [diff] [blame] | 235 | { |
| 236 | newRegExp = 'r = new RegExp("' + pattern + '", "u")'; |
| 237 | |
oliver@apple.com | 3909b16 | 2016-06-06 17:31:28 +0000 | [diff] [blame] | 238 | shouldThrow(newRegExp, error); |
msaboff@apple.com | 5bc3906 | 2016-03-04 01:24:28 +0000 | [diff] [blame] | 239 | } |
| 240 | |
| 241 | shouldThrowInvalidEscape("\\\\-"); |
| 242 | shouldThrowInvalidEscape("\\\\a"); |
| 243 | shouldThrowInvalidEscape("[\\\\a]"); |
| 244 | shouldThrowInvalidEscape("[\\\\b]"); |
| 245 | shouldThrowInvalidEscape("[\\\\B]"); |
| 246 | shouldThrowInvalidEscape("\\\\x"); |
| 247 | shouldThrowInvalidEscape("[\\\\x]"); |
| 248 | shouldThrowInvalidEscape("\\\\u"); |
| 249 | shouldThrowInvalidEscape("[\\\\u]"); |
| 250 | |
oliver@apple.com | 3909b16 | 2016-06-06 17:31:28 +0000 | [diff] [blame] | 251 | shouldThrowInvalidEscape("\\\\u{", '"SyntaxError: Invalid regular expression: invalid unicode {} escape"'); |
| 252 | shouldThrowInvalidEscape("\\\\u{\\udead", '"SyntaxError: Invalid regular expression: invalid unicode {} escape"'); |
commit-queue@webkit.org | c9a6fe8 | 2017-04-13 02:51:18 +0000 | [diff] [blame] | 253 | |
| 254 | // Check that invalid backreferences in unicode patterns throw exceptions. |
| 255 | shouldThrow(`/\\1/u`); |
| 256 | shouldThrow(`/\\2/u`); |
| 257 | shouldThrow(`/\\3/u`); |
| 258 | shouldThrow(`/\\4/u`); |
| 259 | shouldThrow(`/\\5/u`); |
| 260 | shouldThrow(`/\\6/u`); |
| 261 | shouldThrow(`/\\7/u`); |
| 262 | shouldThrow(`/\\8/u`); |
| 263 | shouldThrow(`/\\9/u`); |
| 264 | shouldNotThrow(`/(.)\\1/u`); |
| 265 | shouldNotThrow(`/(.)(.)\\2/u`); |
| 266 | shouldThrow(`/(.)(.)\\3/u`); |
| 267 | |
| 268 | // Invalid backreferences are okay in non-unicode patterns. |
| 269 | shouldNotThrow(`/\\1/`); |
| 270 | shouldNotThrow(`/\\2/`); |
| 271 | shouldNotThrow(`/\\3/`); |
| 272 | shouldNotThrow(`/\\4/`); |
| 273 | shouldNotThrow(`/\\5/`); |
| 274 | shouldNotThrow(`/\\6/`); |
| 275 | shouldNotThrow(`/\\7/`); |
| 276 | shouldNotThrow(`/\\8/`); |
| 277 | shouldNotThrow(`/\\9/`); |