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