1// Copyright 2008 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// Test the (deprecated as of JS 1.5) properties of the RegExp function.
29var re = /((\d+)\.(\d+))/;
30var s = 'abc123.456def';
31
32re.exec(s);
33
34assertEquals(s, RegExp.input);
35assertEquals('123.456', RegExp.lastMatch);
36assertEquals('456', RegExp.lastParen);
37assertEquals('abc', RegExp.leftContext);
38assertEquals('def', RegExp.rightContext);
39
40assertEquals(s, RegExp['$_']);
41assertEquals('123.456', RegExp['$&']);
42assertEquals('456', RegExp['$+']);
43assertEquals('abc', RegExp['$`']);
44assertEquals('def', RegExp["$'"]);
45
46assertEquals('123.456', RegExp['$1']);
47assertEquals('123', RegExp['$2']);
48assertEquals('456', RegExp['$3']);
49for (var i = 4; i < 10; ++i) {
50  assertEquals('', RegExp['$' + i]);
51}
52
53// They should be read only.
54RegExp['$1'] = 'fisk';
55assertEquals('123.456', RegExp['$1']);
56
57// String.prototype.match and String.prototype.replace (when given a
58// regexp) and also RegExp.prototype.test should all behave as if
59// RegExp.prototype.exec were called.
60s = 'ghi789.012jkl';
61s.match(re);
62assertEquals(s, RegExp.input);
63assertEquals('789.012', RegExp.lastMatch);
64assertEquals('012', RegExp.lastParen);
65assertEquals('ghi', RegExp.leftContext);
66assertEquals('jkl', RegExp.rightContext);
67assertEquals(s, RegExp['$_']);
68assertEquals('789.012', RegExp['$&']);
69assertEquals('012', RegExp['$+']);
70assertEquals('ghi', RegExp['$`']);
71assertEquals('jkl', RegExp["$'"]);
72assertEquals('789.012', RegExp['$1']);
73assertEquals('789', RegExp['$2']);
74assertEquals('012', RegExp['$3']);
75for (var i = 4; i < 10; ++i) {
76  assertEquals('', RegExp['$' + i]);
77}
78
79s = 'abc123.456def';
80s.replace(re, 'whocares');
81assertEquals(s, RegExp.input);
82assertEquals('123.456', RegExp.lastMatch);
83assertEquals('456', RegExp.lastParen);
84assertEquals('abc', RegExp.leftContext);
85assertEquals('def', RegExp.rightContext);
86assertEquals(s, RegExp['$_']);
87assertEquals('123.456', RegExp['$&']);
88assertEquals('456', RegExp['$+']);
89assertEquals('abc', RegExp['$`']);
90assertEquals('def', RegExp["$'"]);
91assertEquals('123.456', RegExp['$1']);
92assertEquals('123', RegExp['$2']);
93assertEquals('456', RegExp['$3']);
94for (var i = 4; i < 10; ++i) {
95  assertEquals('', RegExp['$' + i]);
96}
97
98s = 'ghi789.012jkl';
99re.test(s);
100assertEquals(s, RegExp.input);
101assertEquals('789.012', RegExp.lastMatch);
102assertEquals('012', RegExp.lastParen);
103assertEquals('ghi', RegExp.leftContext);
104assertEquals('jkl', RegExp.rightContext);
105assertEquals(s, RegExp['$_']);
106assertEquals('789.012', RegExp['$&']);
107assertEquals('012', RegExp['$+']);
108assertEquals('ghi', RegExp['$`']);
109assertEquals('jkl', RegExp["$'"]);
110assertEquals('789.012', RegExp['$1']);
111assertEquals('789', RegExp['$2']);
112assertEquals('012', RegExp['$3']);
113for (var i = 4; i < 10; ++i) {
114  assertEquals('', RegExp['$' + i]);
115}
116
117// String.prototype.replace must interleave matching and replacing when a
118// global regexp is matched and replaced with the result of a function, in
119// case the function uses the static properties of the regexp constructor.
120re = /(.)/g;
121function f() { return RegExp.$1; };
122assertEquals('abcd', 'abcd'.replace(re, f));
123
124// lastParen where the last parenthesis didn't match.
125assertEquals(["foo",undefined], /foo(?:a(x))?/.exec("foobx"),
126             "lastParen setup");
127assertEquals("", RegExp.lastParen, "lastParen");
128
129// The same test for $1 to $9.
130for (var i = 1; i <= 9; i++) {
131  var haystack = "foo";
132  var re_text = "^foo";
133  for (var j = 0; j < i - 1; j++) {
134    haystack += "x";
135    re_text += "(x)";
136  }
137  re_text += "(?:a(x))?";
138  haystack += "bx";
139  var re = new RegExp(re_text);
140  assertTrue(re.test(haystack), "$" + i + " setup");
141  for (var j = 1; j < i - 1; j++) {
142    assertEquals("x", RegExp['$' + j], "$" + j + " in $" + i + " setup");
143  }
144  assertEquals("", RegExp['$' + (i)], "$" + i);
145}
146
147RegExp.multiline = "foo";
148assertTrue(typeof RegExp.multiline == typeof Boolean(), "RegExp.multiline coerces values to booleans");
149RegExp.input = Number();
150assertTrue(typeof RegExp.input == typeof String(), "RegExp.input coerces values to booleans");
151
152// Ensure that we save the correct string as the last subject when
153// we do a match on a sliced string (the top one not the underlying).
154var foo = "lsdfj sldkfj sdklfj læsdfjl sdkfjlsdk fjsdl fjsdljskdj flsj flsdkj flskd regexp: /foobar/\nldkfj sdlkfj sdkl";
155assertTrue(/^([a-z]+): (.*)/.test(foo.substring(foo.indexOf("regexp:"))), "regexp: setup");
156assertEquals("regexp", RegExp.$1, "RegExp.$1");
157
158
159// Check that calling with no argument is the same as calling with undefined.
160assertTrue(/^undefined$/.test());
161assertEquals(["undefined"], /^undefined$/.exec());
162