OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 import "package:expect/expect.dart"; | |
6 | |
7 void testEscape(str, regex) { | |
8 assertEquals("foo:bar:baz", str.split(regex).join(":")); | |
9 } | |
10 | |
11 void assertEquals(actual, expected, [message]) => Expect.equals(actual, expected , message); | |
ricow1
2014/09/05 05:47:40
long line
jgruber1
2014/09/05 06:17:26
Done.
| |
12 void assertTrue(actual, [message]) => Expect.isTrue(actual, message); | |
13 void assertFalse(actual, [message]) => Expect.isFalse(actual, message); | |
14 void assertThrows(fn) => Expect.throws(fn); | |
15 | |
16 void main() { | |
17 testEscape("foo\nbar\nbaz", new RegExp(r"\n")); | |
18 testEscape("foo bar baz", new RegExp(r"\s")); | |
19 testEscape("foo\tbar\tbaz", new RegExp(r"\s")); | |
20 testEscape("foo-bar-baz", new RegExp(r"\u002D")); | |
21 | |
22 // Test containing null char in regexp. | |
23 var s = '[' + new String.fromCharCode(0) + ']'; | |
24 var re = new RegExp(s); | |
25 assertEquals(re.allMatches(s).length, 1); | |
26 assertEquals(re.stringMatch(s), new String.fromCharCode(0)); | |
27 | |
28 // Test strings containing all line separators | |
29 s = 'aA\nbB\rcC\r\ndD\u2028eE\u2029fF'; | |
30 re = new RegExp(r"^.", multiLine: true); // any non-newline character at the b eginning of a line | |
ricow1
2014/09/05 05:47:41
long line
jgruber1
2014/09/05 06:17:26
Done.
| |
31 var result = re.allMatches(s).toList(); | |
32 assertEquals(result.length, 6); | |
33 assertEquals(result[0][0], 'a'); | |
34 assertEquals(result[1][0], 'b'); | |
35 assertEquals(result[2][0], 'c'); | |
36 assertEquals(result[3][0], 'd'); | |
37 assertEquals(result[4][0], 'e'); | |
38 assertEquals(result[5][0], 'f'); | |
39 | |
40 re = new RegExp(r".$", multiLine: true); // any non-newline character at the e nd of a line | |
ricow1
2014/09/05 05:47:41
long line
jgruber1
2014/09/05 06:17:26
Done.
| |
41 result = re.allMatches(s).toList(); | |
42 assertEquals(result.length, 6); | |
43 assertEquals(result[0][0], 'A'); | |
44 assertEquals(result[1][0], 'B'); | |
45 assertEquals(result[2][0], 'C'); | |
46 assertEquals(result[3][0], 'D'); | |
47 assertEquals(result[4][0], 'E'); | |
48 assertEquals(result[5][0], 'F'); | |
49 | |
50 re = new RegExp(r"^[^]", multiLine: true); // *any* character at the beginning of a line | |
ricow1
2014/09/05 05:47:41
long line
jgruber1
2014/09/05 06:17:26
Done.
| |
51 result = re.allMatches(s).toList(); | |
52 assertEquals(result.length, 7); | |
53 assertEquals(result[0][0], 'a'); | |
54 assertEquals(result[1][0], 'b'); | |
55 assertEquals(result[2][0], 'c'); | |
56 assertEquals(result[3][0], '\n'); | |
57 assertEquals(result[4][0], 'd'); | |
58 assertEquals(result[5][0], 'e'); | |
59 assertEquals(result[6][0], 'f'); | |
60 | |
61 re = new RegExp(r"[^]$", multiLine: true); // *any* character at the end of a line | |
ricow1
2014/09/05 05:47:41
long line
jgruber1
2014/09/05 06:17:25
Done.
| |
62 result = re.allMatches(s).toList(); | |
63 assertEquals(result.length, 7); | |
64 assertEquals(result[0][0], 'A'); | |
65 assertEquals(result[1][0], 'B'); | |
66 assertEquals(result[2][0], 'C'); | |
67 assertEquals(result[3][0], '\r'); | |
68 assertEquals(result[4][0], 'D'); | |
69 assertEquals(result[5][0], 'E'); | |
70 assertEquals(result[6][0], 'F'); | |
71 | |
72 // Some tests from the Mozilla tests, where our behavior used to differ from | |
73 // SpiderMonkey. | |
74 // From ecma_3/RegExp/regress-334158.js | |
75 assertTrue( "\x01" .contains(new RegExp(r"\ca"))); | |
76 assertFalse( "\\ca" .contains(new RegExp(r"\ca"))); | |
77 assertFalse( "ca" .contains(new RegExp(r"\ca"))); | |
78 assertTrue( "\\ca" .contains(new RegExp(r"\c[a/]"))); | |
79 assertTrue( "\\c/" .contains(new RegExp(r"\c[a/]"))); | |
80 | |
81 // Test \c in character class | |
82 re = r"^[\cM]$"; | |
83 assertTrue("\r".contains(new RegExp(re))); | |
84 assertFalse("M".contains(new RegExp(re))); | |
85 assertFalse("c".contains(new RegExp(re))); | |
86 assertFalse("\\".contains(new RegExp(re))); | |
87 assertFalse("\x03".contains(new RegExp(re))); // I.e., read as \cc | |
88 | |
89 re = r"^[\c]]$"; | |
90 assertTrue("c]".contains(new RegExp(re))); | |
91 assertTrue("\\]".contains(new RegExp(re))); | |
92 assertFalse("\x1d".contains(new RegExp(re))); // ']' & 0x1f | |
93 assertFalse("\x03]".contains(new RegExp(re))); // I.e., read as \cc | |
94 | |
95 re = r"^[\c1]$"; // Digit control characters are masked in character classes. | |
96 assertTrue("\x11".contains(new RegExp(re))); | |
97 assertFalse("\\".contains(new RegExp(re))); | |
98 assertFalse("c".contains(new RegExp(re))); | |
99 assertFalse("1".contains(new RegExp(re))); | |
100 | |
101 re = r"^[\c_]$"; // Underscore control character is masked in character class es. | |
ricow1
2014/09/05 05:47:41
long line
jgruber1
2014/09/05 06:17:26
Done.
| |
102 assertTrue("\x1f".contains(new RegExp(re))); | |
103 assertFalse("\\".contains(new RegExp(re))); | |
104 assertFalse("c".contains(new RegExp(re))); | |
105 assertFalse("_".contains(new RegExp(re))); | |
106 | |
107 re = r"^[\c$]$"; // Other characters are interpreted literally. | |
108 assertFalse("\x04".contains(new RegExp(re))); | |
109 assertTrue("\\".contains(new RegExp(re))); | |
110 assertTrue("c".contains(new RegExp(re))); | |
111 assertTrue(r"$".contains(new RegExp(re))); | |
112 | |
113 assertTrue("Z[\\cde".contains(new RegExp(r"^[Z-\c-e]*$"))); | |
114 | |
115 // Test that we handle \s and \S correctly on special Unicode characters. | |
116 re = r"\s"; | |
117 assertTrue("\u2028".contains(new RegExp(re))); | |
118 assertTrue("\u2029".contains(new RegExp(re))); | |
119 assertTrue("\uFEFF".contains(new RegExp(re))); | |
120 | |
121 re = r"\S"; | |
122 assertFalse("\u2028".contains(new RegExp(re))); | |
123 assertFalse("\u2029".contains(new RegExp(re))); | |
124 assertFalse("\uFEFF".contains(new RegExp(re))); | |
125 | |
126 // Test that we handle \s and \S correctly inside some bizarre | |
127 // character classes. | |
128 re = r"[\s-:]"; | |
129 assertTrue('-'.contains(new RegExp(re))); | |
130 assertTrue(':'.contains(new RegExp(re))); | |
131 assertTrue(' '.contains(new RegExp(re))); | |
132 assertTrue('\t'.contains(new RegExp(re))); | |
133 assertTrue('\n'.contains(new RegExp(re))); | |
134 assertFalse('a'.contains(new RegExp(re))); | |
135 assertFalse('Z'.contains(new RegExp(re))); | |
136 | |
137 re = r"[\S-:]"; | |
138 assertTrue('-'.contains(new RegExp(re))); | |
139 assertTrue(':'.contains(new RegExp(re))); | |
140 assertFalse(' '.contains(new RegExp(re))); | |
141 assertFalse('\t'.contains(new RegExp(re))); | |
142 assertFalse('\n'.contains(new RegExp(re))); | |
143 assertTrue('a'.contains(new RegExp(re))); | |
144 assertTrue('Z'.contains(new RegExp(re))); | |
145 | |
146 re = r"[^\s-:]"; | |
147 assertFalse('-'.contains(new RegExp(re))); | |
148 assertFalse(':'.contains(new RegExp(re))); | |
149 assertFalse(' '.contains(new RegExp(re))); | |
150 assertFalse('\t'.contains(new RegExp(re))); | |
151 assertFalse('\n'.contains(new RegExp(re))); | |
152 assertTrue('a'.contains(new RegExp(re))); | |
153 assertTrue('Z'.contains(new RegExp(re))); | |
154 | |
155 re = r"[^\S-:]"; | |
156 assertFalse('-'.contains(new RegExp(re))); | |
157 assertFalse(':'.contains(new RegExp(re))); | |
158 assertTrue(' '.contains(new RegExp(re))); | |
159 assertTrue('\t'.contains(new RegExp(re))); | |
160 assertTrue('\n'.contains(new RegExp(re))); | |
161 assertFalse('a'.contains(new RegExp(re))); | |
162 assertFalse('Z'.contains(new RegExp(re))); | |
163 | |
164 re = r"[\s]"; | |
165 assertFalse('-'.contains(new RegExp(re))); | |
166 assertFalse(':'.contains(new RegExp(re))); | |
167 assertTrue(' '.contains(new RegExp(re))); | |
168 assertTrue('\t'.contains(new RegExp(re))); | |
169 assertTrue('\n'.contains(new RegExp(re))); | |
170 assertFalse('a'.contains(new RegExp(re))); | |
171 assertFalse('Z'.contains(new RegExp(re))); | |
172 | |
173 re = r"[^\s]"; | |
174 assertTrue('-'.contains(new RegExp(re))); | |
175 assertTrue(':'.contains(new RegExp(re))); | |
176 assertFalse(' '.contains(new RegExp(re))); | |
177 assertFalse('\t'.contains(new RegExp(re))); | |
178 assertFalse('\n'.contains(new RegExp(re))); | |
179 assertTrue('a'.contains(new RegExp(re))); | |
180 assertTrue('Z'.contains(new RegExp(re))); | |
181 | |
182 re = r"[\S]"; | |
183 assertTrue('-'.contains(new RegExp(re))); | |
184 assertTrue(':'.contains(new RegExp(re))); | |
185 assertFalse(' '.contains(new RegExp(re))); | |
186 assertFalse('\t'.contains(new RegExp(re))); | |
187 assertFalse('\n'.contains(new RegExp(re))); | |
188 assertTrue('a'.contains(new RegExp(re))); | |
189 assertTrue('Z'.contains(new RegExp(re))); | |
190 | |
191 re = r"[^\S]"; | |
192 assertFalse('-'.contains(new RegExp(re))); | |
193 assertFalse(':'.contains(new RegExp(re))); | |
194 assertTrue(' '.contains(new RegExp(re))); | |
195 assertTrue('\t'.contains(new RegExp(re))); | |
196 assertTrue('\n'.contains(new RegExp(re))); | |
197 assertFalse('a'.contains(new RegExp(re))); | |
198 assertFalse('Z'.contains(new RegExp(re))); | |
199 | |
200 re = r"[\s\S]"; | |
201 assertTrue('-'.contains(new RegExp(re))); | |
202 assertTrue(':'.contains(new RegExp(re))); | |
203 assertTrue(' '.contains(new RegExp(re))); | |
204 assertTrue('\t'.contains(new RegExp(re))); | |
205 assertTrue('\n'.contains(new RegExp(re))); | |
206 assertTrue('a'.contains(new RegExp(re))); | |
207 assertTrue('Z'.contains(new RegExp(re))); | |
208 | |
209 re = r"[^\s\S]"; | |
210 assertFalse('-'.contains(new RegExp(re))); | |
211 assertFalse(':'.contains(new RegExp(re))); | |
212 assertFalse(' '.contains(new RegExp(re))); | |
213 assertFalse('\t'.contains(new RegExp(re))); | |
214 assertFalse('\n'.contains(new RegExp(re))); | |
215 assertFalse('a'.contains(new RegExp(re))); | |
216 assertFalse('Z'.contains(new RegExp(re))); | |
217 | |
218 // First - is treated as range operator, second as literal minus. | |
219 // This follows the specification in parsing, but doesn't throw on | |
220 // the \s at the beginning of the range. | |
221 re = r"[\s-0-9]"; | |
222 assertTrue(' '.contains(new RegExp(re))); | |
223 assertTrue('\xA0'.contains(new RegExp(re))); | |
224 assertTrue('-'.contains(new RegExp(re))); | |
225 assertTrue('0'.contains(new RegExp(re))); | |
226 assertTrue('9'.contains(new RegExp(re))); | |
227 assertFalse('1'.contains(new RegExp(re))); | |
228 | |
229 // Test beginning and end of line assertions with or without the | |
230 // multiline flag. | |
231 re = r"^\d+"; | |
232 assertFalse("asdf\n123".contains(new RegExp(re))); | |
233 re = new RegExp(r"^\d+", multiLine: true); | |
234 assertTrue("asdf\n123".contains(re)); | |
235 | |
236 re = r"\d+$"; | |
237 assertFalse("123\nasdf".contains(new RegExp(re))); | |
238 re = new RegExp(r"\d+$", multiLine: true); | |
239 assertTrue("123\nasdf".contains(re)); | |
240 | |
241 // Test that empty matches are handled correctly for multiline global | |
242 // regexps. | |
243 re = new RegExp(r"^(.*)", multiLine: true); | |
244 assertEquals(3, re.allMatches("a\n\rb").length); | |
245 assertEquals("*a\n*b\r*c\n*\r*d\r*\n*e", | |
246 "a\nb\rc\n\rd\r\ne".replaceAllMapped(re, (Match m) => "*${m.group(1)}")); | |
247 | |
248 // Test that empty matches advance one character | |
249 re = new RegExp(""); | |
250 assertEquals("xAx", "A".replaceAll(re, "x")); | |
251 assertEquals(3, new String.fromCharCode(161).replaceAll(re, "x").length); | |
252 | |
253 // Check for lazy RegExp literal creation | |
254 void lazyLiteral(doit) { | |
255 if (doit) return "".replaceAll(new RegExp(r"foo(", caseSensitive: false), "" ); | |
ricow1
2014/09/05 05:47:41
long line
jgruber1
2014/09/05 06:17:26
Done.
| |
256 return true; | |
257 } | |
258 | |
259 assertTrue(lazyLiteral(false)); | |
260 assertThrows(() => lazyLiteral(true)); | |
261 | |
262 // Check $01 and $10 | |
263 re = new RegExp("(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)"); | |
264 assertEquals("t", "123456789t".replaceAllMapped(re, (Match m) => m.group(10))) ; | |
ricow1
2014/09/05 05:47:41
long line
ricow1
2014/09/05 05:47:41
long line
jgruber1
2014/09/05 06:17:26
Done.
jgruber1
2014/09/05 06:17:26
Done.
| |
265 assertEquals("15", "123456789t".replaceAllMapped(re, (Match m) => "${m.group(1 )}5")); | |
ricow1
2014/09/05 05:47:40
long line
jgruber1
2014/09/05 06:17:26
Done.
| |
266 assertEquals("1", "123456789t".replaceAllMapped(re, (Match m) => m.group(1))); | |
267 | |
268 assertFalse("football".contains(new RegExp(r"()foo$\1")), "football1"); | |
269 assertFalse("football".contains(new RegExp(r"foo$(?=ball)")), "football2"); | |
270 assertFalse("football".contains(new RegExp(r"foo$(?!bar)")), "football3"); | |
271 assertTrue("foo".contains(new RegExp(r"()foo$\1")), "football4"); | |
272 assertTrue("foo".contains(new RegExp(r"foo$(?=(ball)?)")), "football5"); | |
273 assertTrue("foo".contains(new RegExp(r"()foo$(?!bar)")), "football6"); | |
274 assertFalse("football".contains(new RegExp(r"(x?)foo$\1")), "football7"); | |
275 assertFalse("football".contains(new RegExp(r"foo$(?=ball)")), "football8"); | |
276 assertFalse("football".contains(new RegExp(r"foo$(?!bar)")), "football9"); | |
277 assertTrue("foo".contains(new RegExp(r"(x?)foo$\1")), "football10"); | |
278 assertTrue("foo".contains(new RegExp(r"foo$(?=(ball)?)")), "football11"); | |
279 assertTrue("foo".contains(new RegExp(r"foo$(?!bar)")), "football12"); | |
280 | |
281 // Check that the back reference has two successors. See | |
282 // BackReferenceNode::PropagateForward. | |
283 assertFalse('foo'.contains(new RegExp(r"f(o)\b\1"))); | |
284 assertTrue('foo'.contains(new RegExp(r"f(o)\B\1"))); | |
285 | |
286 // Back-reference, ignore case: | |
287 // ASCII | |
288 assertEquals("a", new RegExp(r"x(a)\1x", caseSensitive: false).firstMatch("xaA x").group(1), "backref-ASCII"); | |
ricow1
2014/09/05 05:47:41
long line + a lot below
jgruber1
2014/09/05 06:17:25
Done.
| |
289 assertFalse("xaaaaa".contains(new RegExp(r"x(...)\1", caseSensitive: false)), "backref-ASCII-short"); | |
290 assertTrue("xx".contains(new RegExp(r"x((?:))\1\1x", caseSensitive: false)), " backref-ASCII-empty"); | |
291 assertTrue("xabcx".contains(new RegExp(r"x(?:...|(...))\1x", caseSensitive: fa lse)), "backref-ASCII-uncaptured"); | |
292 assertTrue("xabcABCx".contains(new RegExp(r"x(?:...|(...))\1x", caseSensitive: false)), "backref-ASCII-backtrack"); | |
293 assertEquals("aBc", | |
294 new RegExp(r"x(...)\1\1x", caseSensitive: false).firstMatch("xaBc AbCABCx").group(1), | |
295 "backref-ASCII-twice"); | |
296 | |
297 for (var i = 0; i < 128; i++) { | |
298 var testName = "backref-ASCII-char-$i,,${i^0x20}"; | |
299 var test = new String.fromCharCodes([i, i ^ 0x20]).contains(new RegExp(r"^(. )\1$", caseSensitive: false)); | |
300 if (('A'.codeUnitAt(0) <= i && i <= 'Z'.codeUnitAt(0)) || | |
301 ('a'.codeUnitAt(0) <= i && i <= 'z'.codeUnitAt(0))) { | |
302 assertTrue(test, testName); | |
303 } else { | |
304 assertFalse(test, testName); | |
305 } | |
306 } | |
307 | |
308 assertFalse('foo'.contains(new RegExp(r"f(o)$\1")), "backref detects at_end"); | |
309 | |
310 // Check decimal escapes doesn't overflow. | |
311 // (Note: \214 is interpreted as octal). | |
312 assertEquals("\x8c7483648", | |
313 new RegExp(r"\2147483648").firstMatch("\x8c7483648").group(0 ), | |
314 "Overflow decimal escape"); | |
315 | |
316 // Check numbers in quantifiers doesn't overflow and doesn't throw on | |
317 // too large numbers. | |
318 assertFalse('b'.contains(new RegExp(r"a{11111111111111111111111111111111111111 1111111}")), | |
319 "overlarge1"); | |
320 assertFalse('b'.contains(new RegExp(r"a{99999999999999999999999999999999999999 9999999}")), | |
321 "overlarge2"); | |
322 assertFalse('b'.contains(new RegExp(r"a{1,111111111111111111111111111111111111 111111111}")), | |
323 "overlarge3"); | |
324 assertFalse('b'.contains(new RegExp(r"a{1,999999999999999999999999999999999999 999999999}")), | |
325 "overlarge4"); | |
326 assertFalse('b'.contains(new RegExp(r"a{2147483648}")), | |
327 "overlarge5"); | |
328 assertFalse('b'.contains(new RegExp(r"a{21474836471}")), | |
329 "overlarge6"); | |
330 assertFalse('b'.contains(new RegExp(r"a{1,2147483648}")), | |
331 "overlarge7"); | |
332 assertFalse('b'.contains(new RegExp(r"a{1,21474836471}")), | |
333 "overlarge8"); | |
334 assertFalse('b'.contains(new RegExp(r"a{2147483648,2147483648}")), | |
335 "overlarge9"); | |
336 assertFalse('b'.contains(new RegExp(r"a{21474836471,21474836471}")), | |
337 "overlarge10"); | |
338 assertFalse('b'.contains(new RegExp(r"a{2147483647}")), | |
339 "overlarge11"); | |
340 assertFalse('b'.contains(new RegExp(r"a{1,2147483647}")), | |
341 "overlarge12"); | |
342 assertTrue('a'.contains(new RegExp(r"a{1,2147483647}")), | |
343 "overlarge13"); | |
344 assertFalse('a'.contains(new RegExp(r"a{2147483647,2147483647}")), | |
345 "overlarge14"); | |
346 | |
347 // Check that we don't read past the end of the string. | |
348 assertFalse('b'.contains(new RegExp(r"f"))); | |
349 assertFalse('x'.contains(new RegExp(r"[abc]f"))); | |
350 assertFalse('xa'.contains(new RegExp(r"[abc]f"))); | |
351 assertFalse('x'.contains(new RegExp(r"[abc]<"))); | |
352 assertFalse('xa'.contains(new RegExp(r"[abc]<"))); | |
353 assertFalse('b'.contains(new RegExp(r"f", caseSensitive: false))); | |
354 assertFalse('x'.contains(new RegExp(r"[abc]f", caseSensitive: false))); | |
355 assertFalse('xa'.contains(new RegExp(r"[abc]f", caseSensitive: false))); | |
356 assertFalse('x'.contains(new RegExp(r"[abc]<", caseSensitive: false))); | |
357 assertFalse('xa'.contains(new RegExp(r"[abc]<", caseSensitive: false))); | |
358 assertFalse('x'.contains(new RegExp(r"f[abc]"))); | |
359 assertFalse('xa'.contains(new RegExp(r"f[abc]"))); | |
360 assertFalse('x'.contains(new RegExp(r"<[abc]"))); | |
361 assertFalse('xa'.contains(new RegExp(r"<[abc]"))); | |
362 assertFalse('x'.contains(new RegExp(r"f[abc]", caseSensitive: false))); | |
363 assertFalse('xa'.contains(new RegExp(r"f[abc]", caseSensitive: false))); | |
364 assertFalse('x'.contains(new RegExp(r"<[abc]", caseSensitive: false))); | |
365 assertFalse('xa'.contains(new RegExp(r"<[abc]", caseSensitive: false))); | |
366 | |
367 // Test that merging of quick test masks gets it right. | |
368 assertFalse('x7%%y'.contains(new RegExp(r"x([0-7]%%x|[0-6]%%y)")), 'qt'); | |
369 assertFalse('xy7%%%y'.contains(new RegExp(r"()x\1(y([0-7]%%%x|[0-6]%%%y)|dkjas ldkas)")), 'qt2'); | |
370 assertFalse('xy%%%y'.contains(new RegExp(r"()x\1(y([0-7]%%%x|[0-6]%%%y)|dkjasl dkas)")), 'qt3'); | |
371 assertFalse('xy7%%%y'.contains(new RegExp(r"()x\1y([0-7]%%%x|[0-6]%%%y)")), 'q t4'); | |
372 assertFalse('xy%%%y'.contains(new RegExp(r"()x\1(y([0-7]%%%x|[0-6]%%%y)|dkjasl dkas)")), 'qt5'); | |
373 assertFalse('xy7%%%y'.contains(new RegExp(r"()x\1y([0-7]%%%x|[0-6]%%%y)")), 'q t6'); | |
374 assertFalse('xy7%%%y'.contains(new RegExp(r"xy([0-7]%%%x|[0-6]%%%y)")), 'qt7') ; | |
375 assertFalse('x7%%%y'.contains(new RegExp(r"x([0-7]%%%x|[0-6]%%%y)")), 'qt8'); | |
376 | |
377 | |
378 // Don't hang on this one. | |
379 "".contains(new RegExp(r"[^\xfe-\xff]*")); | |
380 | |
381 var longbuffer = new StringBuffer("a"); | |
382 for (var i = 0; i < 100000; i++) { | |
383 longbuffer.write("a?"); | |
384 } | |
385 var long = longbuffer.toString(); | |
386 | |
387 // Don't crash on this one, but maybe throw an exception. | |
388 try { | |
389 new RegExp(long).allMatches("a"); | |
390 } catch (e) { | |
391 assertTrue(String(e).indexOf("Stack overflow") >= 0, "overflow"); | |
392 } | |
393 | |
394 | |
395 // Test boundary-checks. | |
396 void assertRegExpTest(re, input, test) { | |
397 assertEquals(test, input.contains(new RegExp(re)), "test:" + re + ":" + inpu t); | |
398 } | |
399 | |
400 assertRegExpTest(r"b\b", "b", true); | |
401 assertRegExpTest(r"b\b$", "b", true); | |
402 assertRegExpTest(r"\bb", "b", true); | |
403 assertRegExpTest(r"^\bb", "b", true); | |
404 assertRegExpTest(r",\b", ",", false); | |
405 assertRegExpTest(r",\b$", ",", false); | |
406 assertRegExpTest(r"\b,", ",", false); | |
407 assertRegExpTest(r"^\b,", ",", false); | |
408 | |
409 assertRegExpTest(r"b\B", "b", false); | |
410 assertRegExpTest(r"b\B$", "b", false); | |
411 assertRegExpTest(r"\Bb", "b", false); | |
412 assertRegExpTest(r"^\Bb", "b", false); | |
413 assertRegExpTest(r",\B", ",", true); | |
414 assertRegExpTest(r",\B$", ",", true); | |
415 assertRegExpTest(r"\B,", ",", true); | |
416 assertRegExpTest(r"^\B,", ",", true); | |
417 | |
418 assertRegExpTest(r"b\b", "b,", true); | |
419 assertRegExpTest(r"b\b", "ba", false); | |
420 assertRegExpTest(r"b\B", "b,", false); | |
421 assertRegExpTest(r"b\B", "ba", true); | |
422 | |
423 assertRegExpTest(r"b\Bb", "bb", true); | |
424 assertRegExpTest(r"b\bb", "bb", false); | |
425 | |
426 assertRegExpTest(r"b\b[,b]", "bb", false); | |
427 assertRegExpTest(r"b\B[,b]", "bb", true); | |
428 assertRegExpTest(r"b\b[,b]", "b,", true); | |
429 assertRegExpTest(r"b\B[,b]", "b,", false); | |
430 | |
431 assertRegExpTest(r"[,b]\bb", "bb", false); | |
432 assertRegExpTest(r"[,b]\Bb", "bb", true); | |
433 assertRegExpTest(r"[,b]\bb", ",b", true); | |
434 assertRegExpTest(r"[,b]\Bb", ",b", false); | |
435 | |
436 assertRegExpTest(r"[,b]\b[,b]", "bb", false); | |
437 assertRegExpTest(r"[,b]\B[,b]", "bb", true); | |
438 assertRegExpTest(r"[,b]\b[,b]", ",b", true); | |
439 assertRegExpTest(r"[,b]\B[,b]", ",b", false); | |
440 assertRegExpTest(r"[,b]\b[,b]", "b,", true); | |
441 assertRegExpTest(r"[,b]\B[,b]", "b,", false); | |
442 | |
443 // Skipped tests from V8: | |
444 | |
445 // Test that caching of result doesn't share result objects. | |
446 // More iterations increases the chance of hitting a GC. | |
447 | |
448 // Test that we perform the spec required conversions in the correct order. | |
449 | |
450 // Check that properties of RegExp have the correct permissions. | |
451 | |
452 // Check that end-anchored regexps are optimized correctly. | |
453 re = r"(?:a|bc)g$"; | |
454 assertTrue("ag".contains(new RegExp(re))); | |
455 assertTrue("bcg".contains(new RegExp(re))); | |
456 assertTrue("abcg".contains(new RegExp(re))); | |
457 assertTrue("zimbag".contains(new RegExp(re))); | |
458 assertTrue("zimbcg".contains(new RegExp(re))); | |
459 | |
460 assertFalse("g".contains(new RegExp(re))); | |
461 assertFalse("".contains(new RegExp(re))); | |
462 | |
463 // Global regexp (non-zero start). | |
464 re = r"(?:a|bc)g$"; | |
465 assertTrue("ag".contains(new RegExp(re))); | |
466 // Near start of string. | |
467 assertTrue(new RegExp(re).allMatches("zimbag", 1).isNotEmpty); | |
468 // At end of string. | |
469 assertTrue(new RegExp(re).allMatches("zimbag", 6).isEmpty); | |
470 5; // Near end of string. | |
471 assertTrue(new RegExp(re).allMatches("zimbag", 5).isEmpty); | |
472 assertTrue(new RegExp(re).allMatches("zimbag", 4).isNotEmpty); | |
473 | |
474 // Anchored at both ends. | |
475 re = r"^(?:a|bc)g$"; | |
476 assertTrue("ag".contains(new RegExp(re))); | |
477 assertTrue(new RegExp(re).allMatches("ag", 1).isEmpty); | |
478 assertTrue(new RegExp(re).allMatches("zag", 1).isEmpty); | |
479 | |
480 // Long max_length of RegExp. | |
481 re = r"VeryLongRegExp!{1,1000}$"; | |
482 assertTrue("BahoolaVeryLongRegExp!!!!!!".contains(new RegExp(re))); | |
483 assertFalse("VeryLongRegExp".contains(new RegExp(re))); | |
484 assertFalse("!".contains(new RegExp(re))); | |
485 | |
486 // End anchor inside disjunction. | |
487 re = r"(?:a$|bc$)"; | |
488 assertTrue("a".contains(new RegExp(re))); | |
489 assertTrue("bc".contains(new RegExp(re))); | |
490 assertTrue("abc".contains(new RegExp(re))); | |
491 assertTrue("zimzamzumba".contains(new RegExp(re))); | |
492 assertTrue("zimzamzumbc".contains(new RegExp(re))); | |
493 assertFalse("c".contains(new RegExp(re))); | |
494 assertFalse("".contains(new RegExp(re))); | |
495 | |
496 // Only partially anchored. | |
497 re = r"(?:a|bc$)"; | |
498 assertTrue("a".contains(new RegExp(re))); | |
499 assertTrue("bc".contains(new RegExp(re))); | |
500 assertEquals("a", new RegExp(re).firstMatch("abc").group(0)); | |
501 assertEquals(4, new RegExp(re).firstMatch("zimzamzumba").start); | |
502 assertEquals("bc", new RegExp(re).firstMatch("zimzomzumbc").group(0)); | |
503 assertFalse("c".contains(new RegExp(re))); | |
504 assertFalse("".contains(new RegExp(re))); | |
505 | |
506 // Valid syntax in ES5. | |
507 re = new RegExp("(?:x)*"); | |
508 re = new RegExp("(x)*"); | |
509 | |
510 // Syntax extension relative to ES5, for matching JSC (and ES3). | |
511 // Shouldn't throw. | |
512 re = new RegExp("(?=x)*"); | |
513 re = new RegExp("(?!x)*"); | |
514 | |
515 // Should throw. Shouldn't hit asserts in debug mode. | |
516 assertThrows(() => new RegExp('(*)')); | |
517 assertThrows(() => new RegExp('(?:*)')); | |
518 assertThrows(() => new RegExp('(?=*)')); | |
519 assertThrows(() => new RegExp('(?!*)')); | |
520 | |
521 // Test trimmed regular expression for RegExp.test(). | |
522 assertTrue("abc".contains(new RegExp(r".*abc"))); | |
523 assertFalse("q".contains(new RegExp(r".*\d+"))); | |
524 | |
525 // Tests skipped from V8: | |
526 // Test that RegExp.prototype.toString() throws TypeError for | |
527 // incompatible receivers (ES5 section 15.10.6 and 15.10.6.4). | |
528 } | |
OLD | NEW |