1// Copyright 2012 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28// Summary of the spec: lastIndex is reset to 0 if
29// - a regexp fails to match, regardless of global or non-global.
30// - a global regexp is used in a function that returns multiple results,
31//   such as String.prototype.replace or String.prototype.match, since it
32//   repeats the regexp until it fails to match.
33// Otherwise lastIndex is only set when a global regexp matches, to the index
34// after the match.
35
36// Test Regexp.prototype.exec
37r = /a/;
38r.lastIndex = 1;
39r.exec("zzzz");
40assertEquals(0, r.lastIndex);
41
42// Test Regexp.prototype.test
43r = /a/;
44r.lastIndex = 1;
45r.test("zzzz");
46assertEquals(0, r.lastIndex);
47
48// Test String.prototype.match
49r = /a/;
50r.lastIndex = 1;
51"zzzz".match(r);
52assertEquals(0, r.lastIndex);
53
54// Test String.prototype.replace with atomic regexp and empty string.
55r = /a/;
56r.lastIndex = 1;
57"zzzz".replace(r, "");
58assertEquals(0, r.lastIndex);
59
60// Test String.prototype.replace with non-atomic regexp and empty string.
61r = /\d/;
62r.lastIndex = 1;
63"zzzz".replace(r, "");
64assertEquals(0, r.lastIndex);
65
66// Test String.prototype.replace with atomic regexp and non-empty string.
67r = /a/;
68r.lastIndex = 1;
69"zzzz".replace(r, "a");
70assertEquals(0, r.lastIndex);
71
72// Test String.prototype.replace with non-atomic regexp and non-empty string.
73r = /\d/;
74r.lastIndex = 1;
75"zzzz".replace(r, "a");
76assertEquals(0, r.lastIndex);
77
78// Test String.prototype.replace with replacement function
79r = /a/;
80r.lastIndex = 1;
81"zzzz".replace(r, function() { return ""; });
82assertEquals(0, r.lastIndex);
83
84// Regexp functions that returns multiple results:
85// A global regexp always resets lastIndex regardless of whether it matches.
86r = /a/g;
87r.lastIndex = -1;
88"0123abcd".replace(r, "x");
89assertEquals(0, r.lastIndex);
90
91r.lastIndex = -1;
92"01234567".replace(r, "x");
93assertEquals(0, r.lastIndex);
94
95r.lastIndex = -1;
96"0123abcd".match(r);
97assertEquals(0, r.lastIndex);
98
99r.lastIndex = -1;
100"01234567".match(r);
101assertEquals(0, r.lastIndex);
102
103// A non-global regexp resets lastIndex iff it does not match.
104r = /a/;
105r.lastIndex = -1;
106"0123abcd".replace(r, "x");
107assertEquals(-1, r.lastIndex);
108
109r.lastIndex = -1;
110"01234567".replace(r, "x");
111assertEquals(0, r.lastIndex);
112
113r.lastIndex = -1;
114"0123abcd".match(r);
115assertEquals(-1, r.lastIndex);
116
117r.lastIndex = -1;
118"01234567".match(r);
119assertEquals(0, r.lastIndex);
120
121// Also test RegExp.prototype.exec and RegExp.prototype.test
122r = /a/g;
123r.lastIndex = 1;
124r.exec("01234567");
125assertEquals(0, r.lastIndex);
126
127r.lastIndex = 1;
128r.exec("0123abcd");
129assertEquals(5, r.lastIndex);
130
131r = /a/;
132r.lastIndex = 1;
133r.exec("01234567");
134assertEquals(0, r.lastIndex);
135
136r.lastIndex = 1;
137r.exec("0123abcd");
138assertEquals(1, r.lastIndex);
139
140r = /a/g;
141r.lastIndex = 1;
142r.test("01234567");
143assertEquals(0, r.lastIndex);
144
145r.lastIndex = 1;
146r.test("0123abcd");
147assertEquals(5, r.lastIndex);
148
149r = /a/;
150r.lastIndex = 1;
151r.test("01234567");
152assertEquals(0, r.lastIndex);
153
154r.lastIndex = 1;
155r.test("0123abcd");
156assertEquals(1, r.lastIndex);
157