1ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// Copyright 2009 the V8 project authors. All rights reserved.
2ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// Redistribution and use in source and binary forms, with or without
3ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// modification, are permitted provided that the following conditions are
4ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// met:
5ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org//
6ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org//     * Redistributions of source code must retain the above copyright
7ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org//       notice, this list of conditions and the following disclaimer.
8ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org//     * Redistributions in binary form must reproduce the above
9ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org//       copyright notice, this list of conditions and the following
10ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org//       disclaimer in the documentation and/or other materials provided
11ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org//       with the distribution.
12ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org//     * Neither the name of Google Inc. nor the names of its
13ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org//       contributors may be used to endorse or promote products derived
14ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org//       from this software without specific prior written permission.
15ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org//
16ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
28ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// Tests captures in positive and negative look-ahead in regular expressions.
29ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
30ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgfunction stringEscape(string) {
31ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  // Converts string to source literal.
32ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  return '"' + string.replace(/["\\]/g, "\\$1") + '"';
33ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org}
34ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
35ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgfunction testRE(re, input, expected_result) {
36ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  var testName = re + ".test(" + stringEscape(input) +")";
37ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  if (expected_result) {
38ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    assertTrue(re.test(input), testName);
39ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  } else {
40ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    assertFalse(re.test(input), testName);
41ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  }
42ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org}
43ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
44ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgfunction execRE(re, input, expected_result) {
45ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  var testName = re + ".exec('" + stringEscape(input) +"')";
46ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  assertEquals(expected_result, re.exec(input), testName);
47ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org}
48ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
49ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// Test of simple positive lookahead.
50ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
51ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgvar re = /^(?=a)/;
52ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "a", true);
53ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "b", false);
54ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "a", [""]);
55ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
56ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgre = /^(?=\woo)f\w/;
57ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "foo", true);
58ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "boo", false);
59ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "fao", false);
60ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "foa", false);
61ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "foo", ["fo"]);
62ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
63ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgre = /(?=\w).(?=\W)/;
64ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, ".a! ", true);
65ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, ".! ", false);
66ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, ".ab! ", true);
67ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, ".ab! ", ["b"]);
68ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
69ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgre = /(?=f(?=[^f]o))../;
70ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, ", foo!", true);
71ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, ", fo!", false);
72ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, ", ffo", false);
73ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, ", foo!", ["fo"]);
74ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
75ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// Positive lookahead with captures.
76ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgre = /^[^\'\"]*(?=([\'\"])).*\1(\w+)\1/;
77ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "  'foo' ", true);
78ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, '  "foo" ', true);
79ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, " \" 'foo' ", false);
80ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, " ' \"foo\" ", false);
81ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "  'foo\" ", false);
82ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "  \"foo' ", false);
83ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "  'foo' ", ["  'foo'", "'", "foo"]);
84ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, '  "foo" ', ['  "foo"', '"', 'foo']);
85ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
86ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// Captures are cleared on backtrack past the look-ahead.
87ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgre = /^(?:(?=(.))a|b)\1$/;
88ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "aa", true);
89ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "b", true);
90ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "bb", false);
91ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "a", false);
92ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "aa", ["aa", "a"]);
93ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "b", ["b", undefined]);
94ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
95ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgre = /^(?=(.)(?=(.)\1\2)\2\1)\1\2/;
96ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "abab", true);
97ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "ababxxxxxxxx", true);
98ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "aba", false);
99ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "abab", ["ab", "a", "b"]);
100ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
101ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgre = /^(?:(?=(.))a|b|c)$/;
102ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "a", true);
103ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "b", true);
104ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "c", true);
105ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "d", false);
106ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "a", ["a", "a"]);
107ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "b", ["b", undefined]);
108ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "c", ["c", undefined]);
109ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
110ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(/^(?=(b))b/, "b", ["b", "b"]);
111ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(/^(?:(?=(b))|a)b/, "ab", ["ab", undefined]);
112ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(/^(?:(?=(b)(?:(?=(c))|d))|)bd/, "bd", ["bd", "b", undefined]);
113ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
114ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
115ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
116ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// Test of Negative Look-Ahead.
117ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
118ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgre = /(?!x)./;
119ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "y", true);
120ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "x", false);
121ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "y", ["y"]);
122ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
123ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgre = /(?!(\d))|\d/;
124ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "4", true);
125ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "4", ["4", undefined]);
126ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "x", ["", undefined]);
127ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
128ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
129ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// Test mixed nested look-ahead with captures.
130ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
131ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgre = /^(?=(x)(?=(y)))/;
132ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "xy", true);
133ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "xz", false);
134ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "xy", ["", "x", "y"]);
135ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
136ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgre = /^(?!(x)(?!(y)))/;
137ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "xy", true);
138ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "xz", false);
139ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "xy", ["", undefined, undefined]);
140ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
141ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgre = /^(?=(x)(?!(y)))/;
142ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "xz", true);
143ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "xy", false)
144ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "xz", ["", "x", undefined]);
145ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
146ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgre = /^(?!(x)(?=(y)))/;
147ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "xz", true);
148ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "xy", false);
149ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "xz", ["", undefined, undefined]);
150ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
151ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgre = /^(?=(x)(?!(y)(?=(z))))/;
152ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "xaz", true);
153ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "xya", true);
154ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "xyz", false);
155ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "a", false);
156ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "xaz", ["", "x", undefined, undefined]);
157ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "xya", ["", "x", undefined, undefined]);
158ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
159ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgre = /^(?!(x)(?=(y)(?!(z))))/;
160ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "a", true);
161ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "xa", true);
162ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "xyz", true);
163ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgtestRE(re, "xya", false);
164ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "a", ["", undefined, undefined, undefined]);
165ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "xa", ["", undefined, undefined, undefined]);
166ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgexecRE(re, "xyz", ["", undefined, undefined, undefined]);
167