1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package libcore.java.util.regex;
18
19import java.util.regex.Matcher;
20import java.util.regex.Pattern;
21import junit.framework.TestCase;
22
23public final class OldAndroidRegexTest extends TestCase {
24    public void testMatches() throws Exception {
25        /* Tests class Matcher */
26
27        Pattern p = Pattern.compile("bcd");
28        Matcher m = p.matcher("bcd");
29        assertTrue("Should match.", m.matches());
30
31        /* Pattern in the middle */
32        p = Pattern.compile("bcd");
33        m = p.matcher("abcdefg");
34        assertFalse("Should not match.", m.matches());
35
36        /* Pattern at the head */
37        m = p.matcher("bcdefg");
38        assertFalse("Should not match.", m.matches());
39
40        /* Pattern at the tail */
41        m = p.matcher("abcd");
42        assertFalse("Should not match.", m.matches());
43
44        /* Make sure matches() doesn't change after calls to find() */
45        p = Pattern.compile(".*");
46        m = p.matcher("abc");
47        assertTrue(m.matches());
48        assertTrue(m.find());
49        assertTrue(m.matches());
50
51        p = Pattern.compile(".");
52        m = p.matcher("abc");
53        assertFalse(m.matches());
54        assertTrue(m.find());
55        assertFalse(m.matches());
56
57        /* Make sure matches() agrees after a reset() */
58        m.reset("z");
59        assertTrue(m.matches());
60
61        m.reset("xyz");
62        assertFalse(m.matches());
63
64        /* Tests class Pattern */
65
66        assertFalse("Erroneously matched partial string.  " +
67                "See http://b/issue?id=754601", Pattern.matches("er", "xer"));
68        assertFalse("Erroneously matched partial string.  " +
69                "See http://b/issue?id=754601", Pattern.matches("xe", "xer"));
70        assertTrue("Generic regex should match.",
71                Pattern.matches(".*", "bcd"));
72        assertTrue("Grouped regex should match.",
73                Pattern.matches("(b(c(d)))", "bcd"));
74        assertTrue("Grouped regex should match.",
75                Pattern.matches("(b)(c)(d)", "bcd"));
76    }
77
78    public void testGroupCount() throws Exception {
79        Pattern p = Pattern.compile(
80                "\\b(?:\\+?1)?"
81                        + "(?:[ -\\.])?"
82                        + "\\(?(\\d{3})?\\)?"
83                        + "(?:[ -\\.\\/])?"
84                        + "(\\d{3})"
85                        + "(?:[ -\\.])?"
86                        + "(\\d{4})\\b"
87        );
88
89        Matcher m = p.matcher("1 (919) 555-1212");
90
91        assertEquals("groupCount is incorrect, see http://b/issue?id=759412",
92                3, m.groupCount());
93    }
94
95    public void testGroups() throws Exception {
96        Pattern p = Pattern.compile("(b)([c|d])(z*)");
97        Matcher m = p.matcher("abcdefg");
98
99        /* Must call find() first, otherwise group*() are undefined. */
100        assertTrue(m.find());
101
102        assertEquals(3, m.groupCount());
103
104        assertEquals("bc", m.group(0));
105        assertEquals("b", m.group(1));
106        assertEquals("c", m.group(2));
107        assertEquals("", m.group(3));
108    }
109
110    public void testFind() throws Exception {
111        Pattern p = Pattern.compile(".");
112        Matcher m = p.matcher("abc");
113
114        assertTrue(m.find());
115        assertEquals("a", m.group(0));
116
117        assertTrue(m.find());
118        assertEquals("b", m.group(0));
119
120        assertTrue(m.find());
121        assertEquals("c", m.group(0));
122
123        assertFalse(m.find());
124    }
125
126    public void testReplaceAll() throws Exception {
127        // Begins with non-matching text, ends with matching text
128        Pattern p = Pattern.compile("a*b");
129        Matcher m = p.matcher("fooaabfooaabfooabfoob");
130
131        String r = m.replaceAll("-");
132        assertEquals("foo-foo-foo-foo-", r);
133
134        // Begins with matching text, ends with non-matching text
135        p = Pattern.compile("a*b");
136        m = p.matcher("aabfooaabfooabfoobfoo");
137
138        r = m.replaceAll("-");
139        assertEquals("-foo-foo-foo-foo", r);
140    }
141
142    public void testReplaceFirst() throws Exception {
143        // Begins with non-matching text, ends with matching text
144        Pattern p = Pattern.compile("a*b");
145        Matcher m = p.matcher("fooaabfooaabfooabfoob");
146
147        String r = m.replaceFirst("-");
148        assertEquals("foo-fooaabfooabfoob", r);
149
150        // Begins with matching text, ends with non-matching text
151        p = Pattern.compile("a*b");
152        m = p.matcher("aabfooaabfooabfoobfoo");
153
154        r = m.replaceFirst("-");
155        assertEquals("-fooaabfooabfoobfoo", r);
156    }
157
158    public void testSplit() throws Exception {
159        Pattern p = Pattern.compile(":");
160        String[] strings;
161
162        strings = p.split("boo:and:foo");
163        assertEquals(3, strings.length);
164        assertEquals("boo", strings[0]);
165        assertEquals("and", strings[1]);
166        assertEquals("foo", strings[2]);
167
168        strings = p.split("boo:and:foo", 2);
169        assertEquals(2, strings.length);
170        assertEquals("boo", strings[0]);
171        assertEquals("and:foo", strings[1]);
172
173        strings = p.split("boo:and:foo", 5);
174        assertEquals(3, strings.length);
175        assertEquals("boo", strings[0]);
176        assertEquals("and", strings[1]);
177        assertEquals("foo", strings[2]);
178
179        strings = p.split("boo:and:foo", -2);
180        assertEquals(3, strings.length);
181        assertEquals("boo", strings[0]);
182        assertEquals("and", strings[1]);
183        assertEquals("foo", strings[2]);
184
185        p = Pattern.compile("o");
186
187        strings = p.split("boo:and:foo");
188        assertEquals(3, strings.length);
189        assertEquals("b", strings[0]);
190        assertEquals("", strings[1]);
191        assertEquals(":and:f", strings[2]);
192
193        strings = p.split("boo:and:foo", 5);
194        assertEquals(5, strings.length);
195        assertEquals("b", strings[0]);
196        assertEquals("", strings[1]);
197        assertEquals(":and:f", strings[2]);
198        assertEquals("", strings[3]);
199        assertEquals("", strings[4]);
200
201        strings = p.split("boo:and:foo", -2);
202        assertEquals(5, strings.length);
203        assertEquals("b", strings[0]);
204        assertEquals("", strings[1]);
205        assertEquals(":and:f", strings[2]);
206        assertEquals("", strings[3]);
207        assertEquals("", strings[4]);
208
209        strings = p.split("boo:and:foo", 0);
210        assertEquals(3, strings.length);
211        assertEquals("b", strings[0]);
212        assertEquals("", strings[1]);
213        assertEquals(":and:f", strings[2]);
214    }
215
216    // -------------------------------------------------------------------
217    // Regression test for #1172774: Bug in Regex.java
218    // Regression test for #1216887: Regular expression match is very slow
219    public static final Pattern TOP_LEVEL_DOMAIN_PATTERN = Pattern.compile(
220            "((aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
221            + "|(biz|b[abdefghijmnorstvwyz])"
222            + "|(cat|com|coop|c[acdfghiklmnoruvxyz])"
223            + "|d[ejkmoz]"
224            + "|(edu|e[cegrstu])"
225            + "|f[ijkmor]"
226            + "|(gov|g[abdefghilmnpqrstuwy])"
227            + "|h[kmnrtu]"
228            + "|(info|int|i[delmnoqrst])"
229            + "|(jobs|j[emop])"
230            + "|k[eghimnrwyz]"
231            + "|l[abcikrstuvy]"
232            + "|(mil|mobi|museum|m[acdghklmnopqrstuvwxyz])"
233            + "|(name|net|n[acefgilopruz])"
234            + "|(org|om)"
235            + "|(pro|p[aefghklmnrstwy])"
236            + "|qa"
237            + "|r[eouw]"
238            + "|s[abcdeghijklmnortuvyz]"
239            + "|(tel|travel|t[cdfghjklmnoprtvwz])"
240            + "|u[agkmsyz]"
241            + "|v[aceginu]"
242            + "|w[fs]"
243            + "|y[etu]"
244            + "|z[amw])");
245
246    public static final Pattern EMAIL_ADDRESS_PATTERN = Pattern.compile(
247            "[\\+a-zA-Z0-9\\.\\_\\%\\-]+\\@"
248            + "(("
249            + "[a-zA-Z0-9]\\.|"
250            + "([a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9]\\.)+)"
251            + TOP_LEVEL_DOMAIN_PATTERN
252            + ")");
253
254    public void testMonsterRegexCorrectness() {
255        assertTrue(EMAIL_ADDRESS_PATTERN.matcher("a+b@gmail.com").matches());
256    }
257
258    public void testMonsterRegexPerformance() {
259        long t0 = System.currentTimeMillis();
260        Matcher m = EMAIL_ADDRESS_PATTERN.matcher("donot repeate@RC8jjjjjjjjjjjjjjj");
261        assertFalse(m.find());
262        long t1 = System.currentTimeMillis();
263        System.out.println("RegEx performance test finished, took " + (t1 - t0) + " ms.");
264    }
265}
266