1/*
2 * Copyright 2008 Jacek Caban for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19
20var m, re, b, i, obj;
21
22ok(RegExp.leftContext === "", "RegExp.leftContext = " + RegExp.leftContext);
23RegExp.leftContext = "abc";
24ok(RegExp.leftContext === "", "RegExp.leftContext = " + RegExp.leftContext);
25
26re = /a+/;
27ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
28
29m = re.exec(" aabaaa");
30ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
31ok(m.index === 1, "m.index = " + m.index);
32ok(m.input === " aabaaa", "m.input = " + m.input);
33ok(m.length === 1, "m.length = " + m.length);
34ok(m[0] === "aa", "m[0] = " + m[0]);
35ok(RegExp.leftContext === " ", "RegExp.leftContext = " + RegExp.leftContext);
36ok(RegExp.rightContext === "baaa", "RegExp.rightContext = " + RegExp.rightContext);
37
38m = re.exec(" aabaaa");
39ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
40ok(m.index === 1, "m.index = " + m.index);
41ok(m.input === " aabaaa", "m.input = " + m.input);
42ok(m.length === 1, "m.length = " + m.length);
43ok(m[0] === "aa", "m[0] = " + m[0]);
44ok(m.propertyIsEnumerable("0"), "m.0 is not enumerable");
45ok(m.propertyIsEnumerable("input"), "m.input is not enumerable");
46ok(m.propertyIsEnumerable("index"), "m.index is not enumerable");
47ok(m.propertyIsEnumerable("lastIndex"), "m.lastIndex is not enumerable");
48ok(m.propertyIsEnumerable("length") === false, "m.length is not enumerable");
49ok(RegExp.leftContext === " ", "RegExp.leftContext = " + RegExp.leftContext);
50ok(RegExp.rightContext === "baaa", "RegExp.rightContext = " + RegExp.rightContext);
51
52m = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/.exec(
53    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
54ok(m === null, "m is not null");
55
56re = /a+/g;
57ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
58
59m = re.exec(" aabaaa");
60ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
61ok(m.index === 1, "m.index = " + m.index);
62ok(m.lastIndex == 3, "m.lastIndex = " + m.lastIndex);
63ok(m.input === " aabaaa", "m.input = " + m.input);
64ok(m.length === 1, "m.length = " + m.length);
65ok(m[0] === "aa", "m[0] = " + m[0]);
66
67m = re.exec(" aabaaa");
68ok(re.lastIndex === 7, "re.lastIndex = " + re.lastIndex);
69ok(m.index === 4, "m.index = " + m.index);
70ok(m.input === " aabaaa", "m.input = " + m.input);
71ok(m.length === 1, "m.length = " + m.length);
72ok(m[0] === "aaa", "m[0] = " + m[0]);
73
74m = re.exec(" aabaaa");
75ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
76ok(m === null, "m is not null");
77
78re.exec("               a");
79ok(re.lastIndex === 16, "re.lastIndex = " + re.lastIndex);
80ok(RegExp.leftContext === "               ",
81   "RegExp.leftContext = " + RegExp.leftContext);
82ok(RegExp.rightContext === "", "RegExp.rightContext = " + RegExp.rightContext);
83
84m = re.exec(" a");
85ok(m === null, "m is not null");
86ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
87
88m = re.exec(" a");
89ok(re.lastIndex === 2, "re.lastIndex = " + re.lastIndex);
90
91m = re.exec();
92ok(m === null, "m is not null");
93ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
94
95m = /(a|b)+|(c)/.exec("aa");
96ok(m[0] === "aa", "m[0] = " + m[0]);
97ok(m[1] === "a", "m[1] = " + m[1]);
98ok(m[2] === "", "m[2] = " + m[2]);
99
100b = re.test("  a ");
101ok(b === true, "re.test('  a ') returned " + b);
102ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
103ok(RegExp.leftContext === "  ", "RegExp.leftContext = " + RegExp.leftContext);
104ok(RegExp.rightContext === " ", "RegExp.rightContext = " + RegExp.rightContext);
105
106b = re.test(" a ");
107ok(b === false, "re.test(' a ') returned " + b);
108ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
109ok(RegExp.leftContext === "  ", "RegExp.leftContext = " + RegExp.leftContext);
110ok(RegExp.rightContext === " ", "RegExp.rightContext = " + RegExp.rightContext);
111
112re = /\[([^\[]+)\]/g;
113m = re.exec(" [test]  ");
114ok(re.lastIndex === 7, "re.lastIndex = " + re.lastIndex);
115ok(m.index === 1, "m.index = " + m.index);
116ok(m.input === " [test]  ", "m.input = " + m.input);
117ok(m.length === 2, "m.length = " + m.length);
118ok(m[0] === "[test]", "m[0] = " + m[0]);
119ok(m[1] === "test", "m[1] = " + m[1]);
120
121b = /a*/.test();
122ok(b === true, "/a*/.test() returned " + b);
123ok(RegExp.leftContext === "", "RegExp.leftContext = " + RegExp.leftContext);
124ok(RegExp.rightContext === "undefined", "RegExp.rightContext = " + RegExp.rightContext);
125
126b = /f/.test();
127ok(b === true, "/f/.test() returned " + b);
128ok(RegExp.leftContext === "unde", "RegExp.leftContext = " + RegExp.leftContext);
129ok(RegExp.rightContext === "ined", "RegExp.rightContext = " + RegExp.rightContext);
130
131b = /abc/.test();
132ok(b === false, "/abc/.test() returned " + b);
133ok(RegExp.leftContext === "unde", "RegExp.leftContext = " + RegExp.leftContext);
134ok(RegExp.rightContext === "ined", "RegExp.rightContext = " + RegExp.rightContext);
135
136m = "abcabc".match(re = /ca/);
137ok(typeof(m) === "object", "typeof m is not object");
138ok(m.length === 1, "m.length is not 1");
139ok(m["0"] === "ca", "m[0] is not \"ca\"");
140ok(m.constructor === Array, "unexpected m.constructor");
141ok(re.lastIndex === 4, "re.lastIndex = " + re.lastIndex);
142ok(RegExp.leftContext === "ab", "RegExp.leftContext = " + RegExp.leftContext);
143ok(RegExp.rightContext === "bc", "RegExp.rightContext = " + RegExp.rightContext);
144
145m = "abcabc".match(/ab/);
146ok(typeof(m) === "object", "typeof m is not object");
147ok(m.length === 1, "m.length is not 1");
148ok(m["0"] === "ab", "m[0] is not \"ab\"");
149ok(RegExp.leftContext === "", "RegExp.leftContext = " + RegExp.leftContext);
150ok(RegExp.rightContext === "cabc", "RegExp.rightContext = " + RegExp.rightContext);
151
152m = "abcabc".match(/ab/g);
153ok(typeof(m) === "object", "typeof m is not object");
154ok(m.length === 2, "m.length is not 2");
155ok(m["0"] === "ab", "m[0] is not \"ab\"");
156ok(m["1"] === "ab", "m[1] is not \"ab\"");
157/* ok(m.input === "abcabc", "m.input = " + m.input); */
158
159m = "abcabc".match(/Ab/g);
160ok(typeof(m) === "object", "typeof m is not object");
161ok(m === null, "m is not null");
162
163m = "abcabc".match(/Ab/gi);
164ok(typeof(m) === "object", "typeof m is not object");
165ok(m.length === 2, "m.length is not 2");
166ok(m["0"] === "ab", "m[0] is not \"ab\"");
167ok(m["1"] === "ab", "m[1] is not \"ab\"");
168ok(RegExp.leftContext === "abc", "RegExp.leftContext = " + RegExp.leftContext);
169ok(RegExp.rightContext === "c", "RegExp.rightContext = " + RegExp.rightContext);
170
171m = "aaabcabc".match(/a+b/g);
172ok(typeof(m) === "object", "typeof m is not object");
173ok(m.length === 2, "m.length is not 2");
174ok(m["0"] === "aaab", "m[0] is not \"ab\"");
175ok(m["1"] === "ab", "m[1] is not \"ab\"");
176
177m = "aaa\\\\cabc".match(/\\/g);
178ok(typeof(m) === "object", "typeof m is not object");
179ok(m.length === 2, "m.length is not 2");
180ok(m["0"] === "\\", "m[0] is not \"\\\"");
181ok(m["1"] === "\\", "m[1] is not \"\\\"");
182
183m = "abcabc".match(new RegExp("ab"));
184ok(typeof(m) === "object", "typeof m is not object");
185ok(m.length === 1, "m.length is not 1");
186ok(m["0"] === "ab", "m[0] is not \"ab\"");
187
188m = "abcabc".match(new RegExp("ab","g"));
189ok(typeof(m) === "object", "typeof m is not object");
190ok(m.length === 2, "m.length is not 2");
191ok(m["0"] === "ab", "m[0] is not \"ab\"");
192ok(m["1"] === "ab", "m[1] is not \"ab\"");
193ok(RegExp.leftContext === "abc", "RegExp.leftContext = " + RegExp.leftContext);
194ok(RegExp.rightContext === "c", "RegExp.rightContext = " + RegExp.rightContext);
195
196m = "abcabc".match(new RegExp(/ab/g));
197ok(typeof(m) === "object", "typeof m is not object");
198ok(m.length === 2, "m.length is not 2");
199ok(m["0"] === "ab", "m[0] is not \"ab\"");
200ok(m["1"] === "ab", "m[1] is not \"ab\"");
201
202m = "abcabc".match(new RegExp("ab","g", "test"));
203ok(typeof(m) === "object", "typeof m is not object");
204ok(m.length === 2, "m.length is not 2");
205ok(m["0"] === "ab", "m[0] is not \"ab\"");
206ok(m["1"] === "ab", "m[1] is not \"ab\"");
207ok(m.index === 3, "m.index = " + m.index);
208ok(m.input === "abcabc", "m.input = " + m.input);
209ok(m.lastIndex === 5, "m.lastIndex = " + m.lastIndex);
210
211m = "abcabcg".match("ab", "g");
212ok(typeof(m) === "object", "typeof m is not object");
213ok(m.length === 1, "m.length is not 1");
214ok(m["0"] === "ab", "m[0] is not \"ab\"");
215ok(RegExp.leftContext === "", "RegExp.leftContext = " + RegExp.leftContext);
216ok(RegExp.rightContext === "cabcg", "RegExp.rightContext = " + RegExp.rightContext);
217
218m = "abcabc".match();
219ok(m === null, "m is not null");
220ok(RegExp.leftContext === "", "RegExp.leftContext = " + RegExp.leftContext);
221ok(RegExp.rightContext === "cabcg", "RegExp.rightContext = " + RegExp.rightContext);
222
223m = "abcabc".match(/(a)(b)cabc/);
224ok(typeof(m) === "object", "typeof m is not object");
225ok(m.length === 3, "m.length is not 3");
226ok(m[0] === "abcabc", "m[0] is not \"abc\"");
227ok(m[1] === "a", "m[1] is not \"a\"");
228ok(m[2] === "b", "m[2] is not \"b\"");
229
230re = /(a)bcabc/;
231re.lastIndex = -3;
232m = "abcabc".match(re);
233ok(typeof(m) === "object", "typeof m is not object");
234ok(m.length === 2, "m.length = " + m.length + "expected 3");
235ok(m[0] === "abcabc", "m[0] is not \"abc\"");
236ok(m[1] === "a", "m[1] is not \"a\"");
237ok(re.lastIndex === 6, "re.lastIndex = " + re.lastIndex);
238
239re = /(a)bcabc/;
240re.lastIndex = 2;
241m = "abcabcxxx".match(re);
242ok(typeof(m) === "object", "typeof m is not object");
243ok(m.length === 2, "m.length = " + m.length + "expected 3");
244ok(m[0] === "abcabc", "m[0] is not \"abc\"");
245ok(m[1] === "a", "m[1] is not \"a\"");
246ok(m.input === "abcabcxxx", "m.input = " + m.input);
247ok(re.lastIndex === 6, "re.lastIndex = " + re.lastIndex);
248
249r = "- [test] -".replace(re = /\[([^\[]+)\]/g, "success");
250ok(r === "- success -", "r = " + r + " expected '- success -'");
251ok(re.lastIndex === 8, "re.lastIndex = " + re.lastIndex);
252ok(RegExp.leftContext === "- ", "RegExp.leftContext = " + RegExp.leftContext);
253ok(RegExp.rightContext === " -", "RegExp.rightContext = " + RegExp.rightContext);
254
255r = "[test] [test]".replace(/\[([^\[]+)\]/g, "aa");
256ok(r === "aa aa", "r = " + r + "aa aa");
257ok(RegExp.leftContext === "[test] ",
258   "RegExp.leftContext = " + RegExp.leftContext);
259ok(RegExp.rightContext === "",
260   "RegExp.rightContext = " + RegExp.rightContext);
261
262r = "[test] [test]".replace(/\[([^\[]+)\]/, "aa");
263ok(r === "aa [test]", "r = " + r + " expected 'aa [test]'");
264
265r = "- [test] -".replace(/\[([^\[]+)\]/g);
266ok(r === "- undefined -", "r = " + r + " expected '- undefined -'");
267
268r = "- [test] -".replace(/\[([^\[]+)\]/g, true);
269ok(r === "- true -", "r = " + r + " expected '- true -'");
270
271r = "- [test] -".replace(/\[([^\[]+)\]/g, true, "test");
272ok(r === "- true -", "r = " + r + " expected '- true -'");
273ok(RegExp.leftContext === "- ", "RegExp.leftContext = " + RegExp.leftContext);
274ok(RegExp.rightContext === " -", "RegExp.rightContext = " + RegExp.rightContext);
275
276var tmp = 0;
277
278function replaceFunc1(m, off, str) {
279    ok(arguments.length === 3, "arguments.length = " + arguments.length);
280
281    switch(tmp) {
282    case 0:
283        ok(m === "[test1]", "m = " + m + " expected [test1]");
284        ok(off === 0, "off = " + off + " expected 0");
285        ok(RegExp.leftContext === "- ",
286           "RegExp.leftContext = " + RegExp.leftContext);
287        ok(RegExp.rightContext === " -",
288           "RegExp.rightContext = " + RegExp.rightContext);
289        break;
290    case 1:
291        ok(m === "[test2]", "m = " + m + " expected [test2]");
292        ok(off === 8, "off = " + off + " expected 8");
293        ok(RegExp.leftContext === "- ",
294           "RegExp.leftContext = " + RegExp.leftContext);
295        ok(RegExp.rightContext === " -",
296           "RegExp.rightContext = " + RegExp.rightContext);
297        break;
298    default:
299        ok(false, "unexpected call");
300    }
301
302    ok(str === "[test1] [test2]", "str = " + arguments[3]);
303    return "r" + tmp++;
304}
305
306r = "[test1] [test2]".replace(/\[[^\[]+\]/g, replaceFunc1);
307ok(r === "r0 r1", "r = " + r + " expected 'r0 r1'");
308ok(RegExp.leftContext === "[test1] ", "RegExp.leftContext = " + RegExp.leftContext);
309ok(RegExp.rightContext === "", "RegExp.rightContext = " + RegExp.rightContext);
310
311tmp = 0;
312
313function replaceFunc2(m, subm, off, str) {
314    ok(arguments.length === 4, "arguments.length = " + arguments.length);
315
316    switch(tmp) {
317    case 0:
318        ok(subm === "test1", "subm = " + subm);
319        ok(m === "[test1]", "m = " + m + " expected [test1]");
320        ok(off === 0, "off = " + off + " expected 0");
321        break;
322    case 1:
323        ok(subm === "test2", "subm = " + subm);
324        ok(m === "[test2]", "m = " + m + " expected [test2]");
325        ok(off === 8, "off = " + off + " expected 8");
326        break;
327    default:
328        ok(false, "unexpected call");
329    }
330
331    ok(str === "[test1] [test2]", "str = " + arguments[3]);
332    return "r" + tmp++;
333}
334
335r = "[test1] [test2]".replace(/\[([^\[]+)\]/g, replaceFunc2);
336ok(r === "r0 r1", "r = '" + r + "' expected 'r0 r1'");
337
338r = "$1,$2".replace(/(\$(\d))/g, "$$1-$1$2");
339ok(r === "$1-$11,$1-$22", "r = '" + r + "' expected '$1-$11,$1-$22'");
340ok(RegExp.leftContext === "$1,", "RegExp.leftContext = " + RegExp.leftContext);
341ok(RegExp.rightContext === "", "RegExp.rightContext = " + RegExp.rightContext);
342
343r = "abc &1 123".replace(/(\&(\d))/g, "$&");
344ok(r === "abc &1 123", "r = '" + r + "' expected 'abc &1 123'");
345ok(RegExp.leftContext === "abc ", "RegExp.leftContext = " + RegExp.leftContext);
346ok(RegExp.rightContext === " 123", "RegExp.rightContext = " + RegExp.rightContext);
347
348r = "abc &1 123".replace(/(\&(\d))/g, "$'");
349ok(r === "abc  123 123", "r = '" + r + "' expected 'abc  123 123'");
350
351r = "abc &1 123".replace(/(\&(\d))/g, "$`");
352ok(r === "abc abc  123", "r = '" + r + "' expected 'abc abc  123'");
353
354r = "abc &1 123".replace(/(\&(\d))/g, "$3");
355ok(r === "abc $3 123", "r = '" + r + "' expected 'abc $3 123'");
356
357r = "abc &1 123".replace(/(\&(\d))/g, "$");
358ok(r === "abc $ 123", "r = '" + r + "' expected 'abc $ 123'");
359
360r = "abc &1 123".replace(/(\&(\d))/g, "$a");
361ok(r === "abc $a 123", "r = '" + r + "' expected 'abc $a 123'");
362
363r = "abc &1 123".replace(/(\&(\d))/g, "$11");
364ok(r === "abc &11 123", "r = '" + r + "' expected 'abc &11 123'");
365
366r = "abc &1 123".replace(/(\&(\d))/g, "$0");
367ok(r === "abc $0 123", "r = '" + r + "' expected 'abc $0 123'");
368
369/a/.test("a");
370r = "1 2 3".replace("2", "$&");
371ok(r === "1 $& 3", "r = '" + r + "' expected '1 $& 3'");
372ok(RegExp.leftContext === "", "RegExp.leftContext = " + RegExp.leftContext);
373ok(RegExp.rightContext === "", "RegExp.rightContext = " + RegExp.rightContext);
374
375r = "1 2 3".replace("2", "$'");
376ok(r === "1 $' 3", "r = '" + r + "' expected '1 $' 3'");
377
378r = "1,,2,3".split(/,+/g);
379ok(r.length === 3, "r.length = " + r.length);
380ok(r[0] === "1", "r[0] = " + r[0]);
381ok(r[1] === "2", "r[1] = " + r[1]);
382ok(r[2] === "3", "r[2] = " + r[2]);
383ok(RegExp.leftContext === "1,,2", "RegExp.leftContext = " + RegExp.leftContext);
384ok(RegExp.rightContext === "3", "RegExp.rightContext = " + RegExp.rightContext);
385
386r = "1,,2,3".split(/,+/g, 2);
387ok(r.length === 2, "r.length = " + r.length);
388ok(r[0] === "1", "r[0] = " + r[0]);
389ok(r[1] === "2", "r[1] = " + r[1]);
390ok(RegExp.leftContext === "1,,2", "RegExp.leftContext = " + RegExp.leftContext);
391ok(RegExp.rightContext === "3", "RegExp.rightContext = " + RegExp.rightContext);
392
393r = "1,,2,3".split(/,+/g, 1);
394ok(r.length === 1, "r.length = " + r.length);
395ok(r[0] === "1", "r[0] = " + r[0]);
396ok(RegExp.leftContext === "1", "RegExp.leftContext = " + RegExp.leftContext);
397ok(RegExp.rightContext === "2,3", "RegExp.rightContext = " + RegExp.rightContext);
398
399r = "1,,2,3".split(/,+/);
400ok(r.length === 3, "r.length = " + r.length);
401ok(r[0] === "1", "r[0] = " + r[0]);
402ok(r[1] === "2", "r[1] = " + r[1]);
403ok(r[2] === "3", "r[2] = " + r[2]);
404
405r = "1,,2,".split(/,+/);
406ok(r.length === 2, "r.length = " + r.length);
407ok(r[0] === "1", "r[0] = " + r[0]);
408ok(r[1] === "2", "r[1] = " + r[1]);
409
410re = /,+/;
411r = "1,,2,".split(re);
412ok(r.length === 2, "r.length = " + r.length);
413ok(r[0] === "1", "r[0] = " + r[0]);
414ok(r[1] === "2", "r[1] = " + r[1]);
415ok(re.lastIndex === 5, "re.lastIndex = " + re.lastIndex);
416
417re = /,+/g;
418r = "1,,2,".split(re);
419ok(r.length === 2, "r.length = " + r.length);
420ok(r[0] === "1", "r[0] = " + r[0]);
421ok(r[1] === "2", "r[1] = " + r[1]);
422ok(re.lastIndex === 5, "re.lastIndex = " + re.lastIndex);
423
424r = "1 12 \t3".split(re = /\s+/).join(";");
425ok(r === "1;12;3", "r = " + r);
426ok(re.lastIndex === 6, "re.lastIndex = " + re.lastIndex);
427
428r = "123".split(re = /\s+/).join(";");
429ok(r === "123", "r = " + r);
430ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
431
432r = "1ab2aab3".split(/(a+)b/);
433ok(r.length === 3, "r.length = " + r.length);
434ok(r[0] === "1", "r[0] = " + r[0]);
435ok(r[1] === "2", "r[1] = " + r[1]);
436ok(r[2] === "3", "r[2] = " + r[2]);
437
438r = "A<B>bold</B>and<CODE>coded</CODE>".split(/<(\/)?([^<>]+)>/) ;
439ok(r.length === 4, "r.length = " + r.length);
440
441/* another standard violation */
442r = "1 12 \t3".split(re = /(\s)+/g).join(";");
443ok(r === "1;12;3", "r = " + r);
444ok(re.lastIndex === 6, "re.lastIndex = " + re.lastIndex);
445ok(RegExp.leftContext === "1 12", "RegExp.leftContext = " + RegExp.leftContext);
446ok(RegExp.rightContext === "3", "RegExp.rightContext = " + RegExp.rightContext);
447
448re = /,+/;
449re.lastIndex = 4;
450r = "1,,2,".split(re);
451ok(r.length === 2, "r.length = " + r.length);
452ok(r[0] === "1", "r[0] = " + r[0]);
453ok(r[1] === "2", "r[1] = " + r[1]);
454ok(re.lastIndex === 5, "re.lastIndex = " + re.lastIndex);
455
456re = /abc[^d]/g;
457ok(re.source === "abc[^d]", "re.source = '" + re.source + "', expected 'abc[^d]'");
458
459re = /a\bc[^d]/g;
460ok(re.source === "a\\bc[^d]", "re.source = '" + re.source + "', expected 'a\\bc[^d]'");
461
462re = /abc/;
463ok(re === RegExp(re), "re !== RegExp(re)");
464
465re = RegExp("abc[^d]", "g");
466ok(re.source === "abc[^d]", "re.source = '" + re.source + "', expected 'abc[^d]'");
467
468re = /abc/;
469ok(re === RegExp(re, undefined), "re !== RegExp(re, undefined)");
470
471re = /abc/;
472ok(re === RegExp(re, undefined, 1), "re !== RegExp(re, undefined, 1)");
473
474re = /a/g;
475ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex + " expected 0");
476
477m = re.exec(" a   ");
478ok(re.lastIndex === 2, "re.lastIndex = " + re.lastIndex + " expected 2");
479ok(m.index === 1, "m.index = " + m.index + " expected 1");
480ok(RegExp.leftContext === " ", "RegExp.leftContext = " + RegExp.leftContext);
481ok(RegExp.rightContext === "   ", "RegExp.rightContext = " + RegExp.rightContext);
482
483m = re.exec(" a   ");
484ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex + " expected 0");
485ok(m === null, "m = " + m + " expected null");
486
487re.lastIndex = 2;
488m = re.exec(" a a ");
489ok(re.lastIndex === 4, "re.lastIndex = " + re.lastIndex + " expected 4");
490ok(m.index === 3, "m.index = " + m.index + " expected 3");
491
492re.lastIndex = "2";
493ok(re.lastIndex === "2", "re.lastIndex = " + re.lastIndex + " expected '2'");
494m = re.exec(" a a ");
495ok(re.lastIndex === 4, "re.lastIndex = " + re.lastIndex + " expected 4");
496ok(m.index === 3, "m.index = " + m.index + " expected 3");
497
498var li = 0;
499var obj = new Object();
500obj.valueOf = function() { return li; };
501
502re.lastIndex = obj;
503ok(re.lastIndex === obj, "re.lastIndex = " + re.lastIndex + " expected obj");
504li = 2;
505m = re.exec(" a a ");
506ok(re.lastIndex === 2, "re.lastIndex = " + re.lastIndex + " expected 2");
507ok(m.index === 1, "m.index = " + m.index + " expected 1");
508
509re.lastIndex = 3;
510re.lastIndex = "test";
511ok(re.lastIndex === "test", "re.lastIndex = " + re.lastIndex + " expected 'test'");
512m = re.exec(" a a ");
513ok(re.lastIndex === 2 || re.lastIndex === 0, "re.lastIndex = " + re.lastIndex + " expected 2 or 0");
514if(re.lastIndex != 0)
515    ok(m.index === 1, "m.index = " + m.index + " expected 1");
516else
517    ok(m === null, "m = " + m + " expected null");
518
519re.lastIndex = 0;
520re.lastIndex = 3.9;
521ok(re.lastIndex === 3.9, "re.lastIndex = " + re.lastIndex + " expected 3.9");
522m = re.exec(" a a ");
523ok(re.lastIndex === 4, "re.lastIndex = " + re.lastIndex + " expected 4");
524ok(m.index === 3, "m.index = " + m.index + " expected 3");
525
526obj.valueOf = function() { throw 0; }
527re.lastIndex = obj;
528ok(re.lastIndex === obj, "unexpected re.lastIndex");
529m = re.exec(" a a ");
530ok(re.lastIndex === 2, "re.lastIndex = " + re.lastIndex + " expected 2");
531ok(m.index === 1, "m.index = " + m.index + " expected 1");
532
533re.lastIndex = -3;
534ok(re.lastIndex === -3, "re.lastIndex = " + re.lastIndex + " expected -3");
535m = re.exec(" a a ");
536ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex + " expected 0");
537ok(m === null, "m = " + m + " expected null");
538
539re.lastIndex = -1;
540ok(re.lastIndex === -1, "re.lastIndex = " + re.lastIndex + " expected -1");
541m = re.exec("  ");
542ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex + " expected 0");
543ok(m === null, "m = " + m + " expected null");
544
545re = /a/;
546re.lastIndex = -3;
547ok(re.lastIndex === -3, "re.lastIndex = " + re.lastIndex + " expected -3");
548m = re.exec(" a a ");
549ok(re.lastIndex === 2, "re.lastIndex = " + re.lastIndex + " expected 0");
550ok(m.index === 1, "m = " + m + " expected 1");
551ok(RegExp.leftContext === " ", "RegExp.leftContext = " + RegExp.leftContext);
552ok(RegExp.rightContext === " a ", "RegExp.rightContext = " + RegExp.rightContext);
553
554re.lastIndex = -1;
555ok(re.lastIndex === -1, "re.lastIndex = " + re.lastIndex + " expected -1");
556m = re.exec("  ");
557ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex + " expected 0");
558ok(m === null, "m = " + m + " expected null");
559
560re = /aa/g;
561i = 'baacd'.search(re);
562ok(i === 1, "'baacd'.search(re) = " + i);
563ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
564ok(RegExp.leftContext === "b", "RegExp.leftContext = " + RegExp.leftContext);
565ok(RegExp.rightContext === "cd", "RegExp.rightContext = " + RegExp.rightContext);
566
567re.lastIndex = 2;
568i = 'baacdaa'.search(re);
569ok(i === 1, "'baacd'.search(re) = " + i);
570ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
571
572re = /aa/;
573i = 'baacd'.search(re);
574ok(i === 1, "'baacd'.search(re) = " + i);
575ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
576
577re.lastIndex = 2;
578i = 'baacdaa'.search(re);
579ok(i === 1, "'baacd'.search(re) = " + i);
580ok(re.lastIndex === 3, "re.lastIndex = " + re.lastIndex);
581ok(RegExp.leftContext === "b", "RegExp.leftContext = " + RegExp.leftContext);
582ok(RegExp.rightContext === "cdaa", "RegExp.rightContext = " + RegExp.rightContext);
583
584re = /d/g;
585re.lastIndex = 1;
586i = 'abc'.search(re);
587ok(i === -1, "'abc'.search(/d/g) = " + i);
588ok(re.lastIndex === 0, "re.lastIndex = " + re.lastIndex);
589ok(RegExp.leftContext === "b", "RegExp.leftContext = " + RegExp.leftContext);
590ok(RegExp.rightContext === "cdaa", "RegExp.rightContext = " + RegExp.rightContext);
591
592i = 'abcdde'.search(/[df]/);
593ok(i === 3, "'abc'.search(/[df]/) = " + i);
594
595i = 'abcdde'.search(/[df]/, "a");
596ok(i === 3, "'abc'.search(/[df]/) = " + i);
597
598i = 'abcdde'.search("[df]");
599ok(i === 3, "'abc'.search(/d*/) = " + i);
600
601obj = {
602    toString: function() { return "abc"; }
603};
604i = String.prototype.search.call(obj, "b");
605ok(i === 1, "String.prototype.seatch.apply(obj, 'b') = " + i);
606
607i = " undefined ".search();
608ok(i === null, "' undefined '.search() = " + i);
609
610tmp = "=)".replace(/=/, "?");
611ok(tmp === "?)", "'=)'.replace(/=/, '?') = " + tmp);
612
613tmp = "   ".replace(/^\s*|\s*$/g, "y");
614ok(tmp === "yy", '"   ".replace(/^\s*|\s*$/g, "y") = ' + tmp);
615
616tmp = "xxx".replace(/^\s*|\s*$/g, "");
617ok(tmp === "xxx", '"xxx".replace(/^\s*|\s*$/g, "y") = ' + tmp);
618
619tmp = "xxx".replace(/^\s*|\s*$/g, "y");
620ok(tmp === "yxxxy", '"xxx".replace(/^\s*|\s*$/g, "y") = ' + tmp);
621
622tmp = "x/y".replace(/[/]/, "*");
623ok(tmp === "x*y", '"x/y".replace(/[/]/, "*") = ' + tmp);
624
625tmp = "x/y".replace(/[xy/]/g, "*");
626ok(tmp === "***", '"x/y".replace(/[xy/]/, "*") = ' + tmp);
627
628/(b)/.exec("abc");
629ok(RegExp.$1 === "b", "RegExp.$1 = " + RegExp.$1);
630ok("$2" in RegExp, "RegExp.$2 doesn't exist");
631ok(RegExp.$2 === "", "RegExp.$2 = " + RegExp.$2);
632ok(RegExp.$9 === "", "RegExp.$9 = " + RegExp.$9);
633ok(!("$10" in RegExp), "RegExp.$10 exists");
634
635/(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)/.exec("abbbbbbbbbbbc");
636ok(RegExp.$1 === "b", "RegExp.$1 = " + RegExp.$1);
637ok(RegExp.$2 === "b", "[2] RegExp.$2 = " + RegExp.$2);
638ok(RegExp.$9 === "b", "RegExp.$9 = " + RegExp.$9);
639ok(!("$10" in RegExp), "RegExp.$10 exists");
640
641/(b)/.exec("abc");
642ok(RegExp.$1 === "b", "RegExp.$1 = " + RegExp.$1);
643ok("$2" in RegExp, "RegExp.$2 doesn't exist");
644ok(RegExp.$2 === "", "RegExp.$2 = " + RegExp.$2);
645ok(RegExp.$9 === "", "RegExp.$9 = " + RegExp.$9);
646ok(!("$10" in RegExp), "RegExp.$10 exists");
647
648RegExp.$1 = "a";
649ok(RegExp.$1 === "b", "RegExp.$1 = " + RegExp.$1);
650
651ok(/abc/.toString() === "/abc/", "/abc/.toString() = " + /abc/.toString());
652ok(/\//.toString() === "/\\//", "/\//.toString() = " + /\//.toString());
653tmp = new RegExp("abc/");
654ok(tmp.toString() === "/abc//", "(new RegExp(\"abc/\")).toString() = " + tmp.toString());
655ok(/abc/g.toString() === "/abc/g", "/abc/g.toString() = " + /abc/g.toString());
656ok(/abc/i.toString() === "/abc/i", "/abc/i.toString() = " + /abc/i.toString());
657ok(/abc/ig.toString() === "/abc/ig", "/abc/ig.toString() = " + /abc/ig.toString());
658ok(/abc/mgi.toString() === "/abc/igm", "/abc/mgi.toString() = " + /abc/mgi.toString());
659tmp = new RegExp("abc/", "mgi");
660ok(tmp.toString() === "/abc//igm", "(new RegExp(\"abc/\")).toString() = " + tmp.toString());
661ok(/abc/.toString(1, false, "3") === "/abc/", "/abc/.toString(1, false, \"3\") = " + /abc/.toString());
662
663re = /x/;
664ok(re.ignoreCase === false, "re.ignoreCase = " + re.ignoreCase);
665ok(re.multiline === false, "re.multiline = " + re.multiline);
666ok(re.global === false, "re.global = " + re.global);
667re = /x/i;
668ok(re.ignoreCase === true, "re.ignoreCase = " + re.ignoreCase);
669ok(re.multiline === false, "re.multiline = " + re.multiline);
670ok(re.global === false, "re.global = " + re.global);
671re = new RegExp("xxx", "gi");
672ok(re.ignoreCase === true, "re.ignoreCase = " + re.ignoreCase);
673ok(re.multiline === false, "re.multiline = " + re.multiline);
674ok(re.global === true, "re.global = " + re.global);
675re = /x/mg;
676ok(re.ignoreCase === false, "re.ignoreCase = " + re.ignoreCase);
677ok(re.multiline === true, "re.multiline = " + re.multiline);
678ok(re.global === true, "re.global = " + re.global);
679
680reportSuccess();
681