1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Redistribution and use in source and binary forms, with or without
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modification, are permitted provided that the following conditions are
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// met:
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//     * Redistributions of source code must retain the above copyright
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       notice, this list of conditions and the following disclaimer.
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//     * Redistributions in binary form must reproduce the above
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       copyright notice, this list of conditions and the following
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       disclaimer in the documentation and/or other materials provided
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       with the distribution.
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//     * Neither the name of Google Inc. nor the names of its
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       contributors may be used to endorse or promote products derived
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//       from this software without specific prior written permission.
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test that an optional capture is cleared between two matches.
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar str = "ABX X";
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = str.replace(/(\w)?X/g, function(match, capture) {
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               assertTrue(match.indexOf(capture) >= 0 ||
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           capture === undefined);
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               return capture ? capture.toLowerCase() : "-";
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             });
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals("Ab -", str);
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test zero-length matches.
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = "Als Gregor Samsa eines Morgens";
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = str.replace(/\b/g, function(match, capture) {
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           return "/";
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         });
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals("/Als/ /Gregor/ /Samsa/ /eines/ /Morgens/", str);
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test zero-length matches that have non-zero-length sub-captures.
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = "It was a pleasure to burn.";
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = str.replace(/(?=(\w+))\b/g, function(match, capture) {
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    return capture.length;
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  });
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals("2It 3was 1a 8pleasure 2to 4burn.", str);
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test multiple captures.
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = "Try not. Do, or do not. There is no try.";
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = str.replace(/(not?)|(do)|(try)/gi,
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  function(match, c1, c2, c3) {
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    assertTrue((c1 === undefined && c2 === undefined) ||
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               (c2 === undefined && c3 === undefined) ||
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               (c1 === undefined && c3 === undefined));
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    if (c1) return "-";
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    if (c2) return "+";
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    if (c3) return "="
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  });
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals("= -. +, or + -. There is - =.", str);
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test multiple alternate captures.
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = "FOUR LEGS GOOD, TWO LEGS BAD!";
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = str.replace(/(FOUR|TWO) LEGS (GOOD|BAD)/g,
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  function(match, num_legs, likeability) {
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    assertTrue(num_legs !== undefined);
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    assertTrue(likeability !== undefined);
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    if (num_legs == "FOUR") assertTrue(likeability == "GOOD");
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    if (num_legs == "TWO") assertTrue(likeability == "BAD");
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    return match.length - 10;
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  });
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals("4, 2!", str);
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The same tests with UC16.
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch//Test that an optional capture is cleared between two matches.
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = "AB\u1234 \u1234";
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = str.replace(/(\w)?\u1234/g,
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  function(match, capture) {
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    assertTrue(match.indexOf(capture) >= 0 ||
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               capture === undefined);
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    return capture ? capture.toLowerCase() : "-";
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  });
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals("Ab -", str);
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test zero-length matches.
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = "Als \u2623\u2642 eines Morgens";
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = str.replace(/\b/g, function(match, capture) {
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           return "/";
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         });
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals("/Als/ \u2623\u2642 /eines/ /Morgens/", str);
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test zero-length matches that have non-zero-length sub-captures.
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = "It was a pleasure to \u70e7.";
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = str.replace(/(?=(\w+))\b/g, function(match, capture) {
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    return capture.length;
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  });
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals("2It 3was 1a 8pleasure 2to \u70e7.", str);
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test multiple captures.
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = "Try not. D\u26aa, or d\u26aa not. There is no try.";
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = str.replace(/(not?)|(d\u26aa)|(try)/gi,
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  function(match, c1, c2, c3) {
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    assertTrue((c1 === undefined && c2 === undefined) ||
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               (c2 === undefined && c3 === undefined) ||
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               (c1 === undefined && c3 === undefined));
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    if (c1) return "-";
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    if (c2) return "+";
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    if (c3) return "="
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  });
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals("= -. +, or + -. There is - =.", str);
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test multiple alternate captures.
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = "FOUR \u817f GOOD, TWO \u817f BAD!";
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = str.replace(/(FOUR|TWO) \u817f (GOOD|BAD)/g,
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  function(match, num_legs, likeability) {
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    assertTrue(num_legs !== undefined);
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    assertTrue(likeability !== undefined);
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    if (num_legs == "FOUR") assertTrue(likeability == "GOOD");
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    if (num_legs == "TWO") assertTrue(likeability == "BAD");
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    return match.length - 7;
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  });
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals("4, 2!", str);
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test capture that is a real substring.
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar str = "Beasts of England, beasts of Ireland";
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = str.replace(/(.*)/g, function(match) { return '~'; });
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals("~~", str);
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test zero-length matches that have non-zero-length sub-captures that do not
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// start at the match start position.
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = "up up up up";
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstr = str.replace(/\b(?=u(p))/g, function(match, capture) {
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    return capture.length;
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  });
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochassertEquals("1up 1up 1up 1up", str);
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Create regexp that has a *lot* of captures.
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar re_string = "(a)";
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfor (var i = 0; i < 500; i++) {
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  re_string = "(" + re_string + ")";
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochre_string = re_string + "1";
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// re_string = "(((...((a))...)))1"
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar regexps = new Array();
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar last_match_expectations = new Array();
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar first_capture_expectations = new Array();
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Atomic regexp.
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochregexps.push(/a1/g);
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochlast_match_expectations.push("a1");
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfirst_capture_expectations.push("");
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Small regexp (no capture);
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochregexps.push(/\w1/g);
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochlast_match_expectations.push("a1");
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfirst_capture_expectations.push("");
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Small regexp (one capture).
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochregexps.push(/(a)1/g);
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochlast_match_expectations.push("a1");
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfirst_capture_expectations.push("a");
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Large regexp (a lot of captures).
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochregexps.push(new RegExp(re_string, "g"));
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochlast_match_expectations.push("a1");
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfirst_capture_expectations.push("a");
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction test_replace(result_expectation,
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      subject,
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      regexp,
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      replacement) {
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (var i = 0; i < regexps.length; i++) {
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Overwrite last match info.
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "deadbeef".replace(/(dead)beef/, "$1holeycow");
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Conduct tests.
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assertEquals(result_expectation, subject.replace(regexps[i], replacement));
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (subject.length == 0) {
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals("deadbeef", RegExp.lastMatch);
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals("dead", RegExp["$1"]);
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(last_match_expectations[i], RegExp.lastMatch);
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(first_capture_expectations[i], RegExp["$1"]);
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfunction test_match(result_expectation,
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    subject,
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    regexp) {
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (var i = 0; i < regexps.length; i++) {
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Overwrite last match info.
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    "deadbeef".replace(/(dead)beef/, "$1holeycow");
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Conduct tests.
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (result_expectation == null) {
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertNull(subject.match(regexps[i]));
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertArrayEquals(result_expectation, subject.match(regexps[i]));
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (subject.length == 0) {
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals("deadbeef", RegExp.lastMatch);
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals("dead", RegExp["$1"]);
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(last_match_expectations[i], RegExp.lastMatch);
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assertEquals(first_capture_expectations[i], RegExp["$1"]);
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test for different number of matches.
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfor (var m = 0; m < 33; m++) {
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Create string that matches m times.
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var subject = "";
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var test_1_expectation = "";
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var test_2_expectation = "";
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  var test_3_expectation = (m == 0) ? null : new Array();
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (var i = 0; i < m; i++) {
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    subject += "a11";
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    test_1_expectation += "x1";
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    test_2_expectation += "1";
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    test_3_expectation.push("a1");
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Test 1a: String.replace with string.
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  test_replace(test_1_expectation, subject, /a1/g, "x");
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Test 1b: String.replace with function.
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  function f() { return "x"; }
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  test_replace(test_1_expectation, subject, /a1/g, f);
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Test 2a: String.replace with empty string.
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  test_replace(test_2_expectation, subject, /a1/g, "");
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Test 3a: String.match.
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  test_match(test_3_expectation, subject, /a1/g);
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test String hashing (compiling regular expression includes hashing).
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar crosscheck = "\x80";
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfor (var i = 0; i < 12; i++) crosscheck += crosscheck;
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnew RegExp(crosscheck);
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar subject = "ascii~only~string~here~";
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar replacement = "\x80";
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvar result = subject.replace(/~/g, replacement);
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfor (var i = 0; i < 5; i++) result += result;
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnew RegExp(result);
255