1/*
2 * Copyright (C) 2010 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 */
16package android.util;
17
18import android.support.test.filters.SmallTest;
19
20import java.util.regex.Matcher;
21import java.util.regex.Pattern;
22
23import junit.framework.TestCase;
24
25public class PatternsTest extends TestCase {
26
27    // Tests for Patterns.TOP_LEVEL_DOMAIN
28
29    @SmallTest
30    public void testTldPattern() throws Exception {
31        boolean t;
32
33        t = Patterns.TOP_LEVEL_DOMAIN.matcher("com").matches();
34        assertTrue("Missed valid TLD", t);
35
36        // One of the new top level domain.
37        t = Patterns.TOP_LEVEL_DOMAIN.matcher("me").matches();
38        assertTrue("Missed valid TLD", t);
39
40        // One of the new top level test domain.
41        t = Patterns.TOP_LEVEL_DOMAIN.matcher("xn--0zwm56d").matches();
42        assertTrue("Missed valid TLD", t);
43
44        // One of the new top level unicode domain.
45        t = Patterns.TOP_LEVEL_DOMAIN.matcher("\uD55C\uAD6D").matches();
46        assertTrue("Missed valid TLD", t);
47
48        t = Patterns.TOP_LEVEL_DOMAIN.matcher("mem").matches();
49        assertFalse("Matched invalid TLD!", t);
50
51        t = Patterns.TOP_LEVEL_DOMAIN.matcher("xn").matches();
52        assertFalse("Matched invalid TLD!", t);
53
54        t = Patterns.TOP_LEVEL_DOMAIN.matcher("xer").matches();
55        assertFalse("Matched invalid TLD!", t);
56    }
57
58    // Tests for Patterns.IANA_TOP_LEVEL_DOMAINS
59
60    @SmallTest
61    public void testIanaTopLevelDomains_matchesValidTld() throws Exception {
62        Pattern pattern = Pattern.compile(Patterns.IANA_TOP_LEVEL_DOMAINS);
63        assertTrue("Should match 'com'", pattern.matcher("com").matches());
64    }
65
66    @SmallTest
67    public void testIanaTopLevelDomains_matchesValidNewTld() throws Exception {
68        Pattern pattern = Pattern.compile(Patterns.IANA_TOP_LEVEL_DOMAINS);
69        assertTrue("Should match 'me'", pattern.matcher("me").matches());
70    }
71
72    @SmallTest
73    public void testIanaTopLevelDomains_matchesPunycodeTld() throws Exception {
74        Pattern pattern = Pattern.compile(Patterns.IANA_TOP_LEVEL_DOMAINS);
75        assertTrue("Should match Punycode TLD", pattern.matcher("xn--qxam").matches());
76    }
77
78    @SmallTest
79    public void testIanaTopLevelDomains_matchesIriTLD() throws Exception {
80        Pattern pattern = Pattern.compile(Patterns.IANA_TOP_LEVEL_DOMAINS);
81        assertTrue("Should match IRI TLD", pattern.matcher("\uD55C\uAD6D").matches());
82    }
83
84    @SmallTest
85    public void testIanaTopLevelDomains_doesNotMatchWrongTld() throws Exception {
86        Pattern pattern = Pattern.compile(Patterns.IANA_TOP_LEVEL_DOMAINS);
87        assertFalse("Should not match 'mem'", pattern.matcher("mem").matches());
88    }
89
90    @SmallTest
91    public void testIanaTopLevelDomains_doesNotMatchWrongPunycodeTld() throws Exception {
92        Pattern pattern = Pattern.compile(Patterns.IANA_TOP_LEVEL_DOMAINS);
93        assertFalse("Should not match invalid Punycode TLD", pattern.matcher("xn").matches());
94    }
95
96    // Tests for Patterns.WEB_URL
97
98    @SmallTest
99    public void testWebUrl_matchesValidUrlWithSchemeAndHostname() throws Exception {
100        String url = "http://www.android.com";
101        assertTrue("Should match URL with scheme and hostname",
102                Patterns.WEB_URL.matcher(url).matches());
103    }
104
105    @SmallTest
106    public void testWebUrl_matchesValidUrlWithSchemeHostnameAndNewTld() throws Exception {
107        String url = "http://www.android.me";
108        assertTrue("Should match URL with scheme, hostname and new TLD",
109                Patterns.WEB_URL.matcher(url).matches());
110    }
111
112    @SmallTest
113    public void testWebUrl_matchesValidUrlWithHostnameAndNewTld() throws Exception {
114        String url = "android.me";
115        assertTrue("Should match URL with hostname and new TLD",
116                Patterns.WEB_URL.matcher(url).matches());
117    }
118
119    @SmallTest
120    public void testWebUrl_matchesChinesePunycodeUrlWithProtocol() throws Exception {
121        String url = "http://xn--fsqu00a.xn--0zwm56d";
122        assertTrue("Should match Chinese Punycode URL with protocol",
123                Patterns.WEB_URL.matcher(url).matches());
124    }
125
126    @SmallTest
127    public void testWebUrl_matchesChinesePunycodeUrlWithoutProtocol() throws Exception {
128        String url = "xn--fsqu00a.xn--0zwm56d";
129        assertTrue("Should match Chinese Punycode URL without protocol",
130                Patterns.WEB_URL.matcher(url).matches());
131    }
132
133    @SmallTest
134    public void testWebUrl_matchesArabicPunycodeUrlWithProtocol() throws Exception {
135        String url = "http://xn--4gbrim.xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c/ar/default.aspx";
136        assertTrue("Should match arabic Punycode URL with protocol",
137                Patterns.WEB_URL.matcher(url).matches());
138    }
139
140    @SmallTest
141    public void testWebUrl_matchesArabicPunycodeUrlWithoutProtocol() throws Exception {
142        String url = "xn--4gbrim.xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c/ar/default.aspx";
143        assertTrue("Should match Arabic Punycode URL without protocol",
144                Patterns.WEB_URL.matcher(url).matches());
145    }
146
147    @SmallTest
148    public void testWebUrl_matchesUrlWithUnicodeDomainNameWithProtocol() throws Exception {
149        String url = "http://\uD604\uAE08\uC601\uC218\uC99D.kr";
150        assertTrue("Should match URL with Unicode domain name",
151                Patterns.WEB_URL.matcher(url).matches());
152    }
153
154    @SmallTest
155    public void testWebUrl_matchesUrlWithUnicodeDomainNameWithoutProtocol() throws Exception {
156        String url = "\uD604\uAE08\uC601\uC218\uC99D.kr";
157        assertTrue("Should match URL without protocol and with Unicode domain name",
158                Patterns.WEB_URL.matcher(url).matches());
159    }
160
161    @SmallTest
162    public void testWebUrl_matchesUrlWithUnicodeTld() throws Exception {
163        String url = "\uB3C4\uBA54\uC778.\uD55C\uAD6D";
164        assertTrue("Should match URL with Unicode TLD",
165                Patterns.WEB_URL.matcher(url).matches());
166    }
167
168    @SmallTest
169    public void testWebUrl_matchesUrlWithUnicodePath() throws Exception {
170        String url = "http://brainstormtech.blogs.fortune.cnn.com/2010/03/11/" +
171                "top-five-moments-from-eric-schmidt\u2019s-talk-in-abu-dhabi/";
172        assertTrue("Should match URL with Unicode path",
173                Patterns.WEB_URL.matcher(url).matches());
174    }
175
176    @SmallTest
177    public void testWebUrl_doesNotMatchValidUrlWithInvalidProtocol() throws Exception {
178        String url = "ftp://www.example.com";
179        assertFalse("Should not match URL with invalid protocol",
180                Patterns.WEB_URL.matcher(url).matches());
181    }
182
183    @SmallTest
184    public void testWebUrl_matchesValidUrlWithPort() throws Exception {
185        String url = "http://www.example.com:8080";
186        assertTrue("Should match URL with port", Patterns.WEB_URL.matcher(url).matches());
187    }
188
189    @SmallTest
190    public void testWebUrl_matchesUrlWithPortAndQuery() throws Exception {
191        String url = "http://www.example.com:8080/?foo=bar";
192        assertTrue("Should match URL with port and query",
193                Patterns.WEB_URL.matcher(url).matches());
194    }
195
196    @SmallTest
197    public void testWebUrl_matchesUrlWithTilde() throws Exception {
198        String url = "http://www.example.com:8080/~user/?foo=bar";
199        assertTrue("Should match URL with tilde", Patterns.WEB_URL.matcher(url).matches());
200    }
201
202    @SmallTest
203    public void testWebUrl_matchesProtocolCaseInsensitive() throws Exception {
204        String url = "hTtP://android.com";
205        assertTrue("Protocol matching should be case insensitive",
206                Patterns.WEB_URL.matcher(url).matches());
207    }
208
209    @SmallTest
210    public void testWebUrl_matchesDomainNameWithDash() throws Exception {
211        String url = "http://a-nd.r-oid.com";
212        assertTrue("Should match dash in domain name",
213                Patterns.WEB_URL.matcher(url).matches());
214
215        url = "a-nd.r-oid.com";
216        assertTrue("Should match dash in domain name",
217                Patterns.WEB_URL.matcher(url).matches());
218    }
219
220    @SmallTest
221    public void testWebUrl_matchesDomainNameWithUnderscore() throws Exception {
222        String url = "http://a_nd.r_oid.com";
223        assertTrue("Should match underscore in domain name",
224                Patterns.WEB_URL.matcher(url).matches());
225
226        url = "a_nd.r_oid.com";
227        assertTrue("Should match underscore in domain name",
228                Patterns.WEB_URL.matcher(url).matches());
229    }
230
231    @SmallTest
232    public void testWebUrl_matchesPathAndQueryWithDollarSign() throws Exception {
233        String url = "http://android.com/path$?v=$val";
234        assertTrue("Should match dollar sign in path/query",
235                Patterns.WEB_URL.matcher(url).matches());
236
237        url = "android.com/path$?v=$val";
238        assertTrue("Should match dollar sign in path/query",
239                Patterns.WEB_URL.matcher(url).matches());
240    }
241
242    @SmallTest
243    public void testWebUrl_matchesEmptyPathWithQueryParams() throws Exception {
244        String url = "http://android.com?q=v";
245        assertTrue("Should match empty path with query param",
246                Patterns.WEB_URL.matcher(url).matches());
247
248        url = "android.com?q=v";
249        assertTrue("Should match empty path with query param",
250                Patterns.WEB_URL.matcher(url).matches());
251
252        url = "http://android.com/?q=v";
253        assertTrue("Should match empty path with query param",
254                Patterns.WEB_URL.matcher(url).matches());
255
256        url = "android.com/?q=v";
257        assertTrue("Should match empty path with query param",
258                Patterns.WEB_URL.matcher(url).matches());
259    }
260
261    // Tests for Patterns.AUTOLINK_WEB_URL
262
263    @SmallTest
264    public void testAutoLinkWebUrl_matchesValidUrlWithSchemeAndHostname() throws Exception {
265        String url = "http://www.android.com";
266        assertTrue("Should match URL with scheme and hostname",
267                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
268    }
269
270    @SmallTest
271    public void testAutoLinkWebUrl_matchesValidUrlWithSchemeHostnameAndNewTld() throws Exception {
272        String url = "http://www.android.me";
273        assertTrue("Should match URL with scheme, hostname and new TLD",
274                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
275    }
276
277    @SmallTest
278    public void testAutoLinkWebUrl_matchesValidUrlWithHostnameAndNewTld() throws Exception {
279        String url = "android.me";
280        assertTrue("Should match URL with hostname and new TLD",
281                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
282
283        url = "android.camera";
284        assertTrue("Should match URL with hostname and new TLD",
285                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
286    }
287
288    @SmallTest
289    public void testAutoLinkWebUrl_matchesChinesePunycodeUrlWithProtocol() throws Exception {
290        String url = "http://xn--fsqu00a.xn--0zwm56d";
291        assertTrue("Should match Chinese Punycode URL with protocol",
292                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
293    }
294
295    @SmallTest
296    public void testAutoLinkWebUrl_matchesChinesePunycodeUrlWithoutProtocol() throws Exception {
297        String url = "xn--fsqu00a.xn--0zwm56d";
298        assertTrue("Should match Chinese Punycode URL without protocol",
299                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
300    }
301
302    @SmallTest
303    public void testAutoLinkWebUrl_matchesArabicPunycodeUrlWithProtocol() throws Exception {
304        String url = "http://xn--4gbrim.xn--rmckbbajlc6dj7bxne2c.xn--wgbh1c/ar/default.aspx";
305        assertTrue("Should match Arabic Punycode URL with protocol",
306                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
307    }
308
309    @SmallTest
310    public void testAutoLinkWebUrl_matchesArabicPunycodeUrlWithoutProtocol() throws Exception {
311        String url = "xn--4gbrim.xn--rmckbbajlc6dj7bxne2c.xn--wgbh1c/ar/default.aspx";
312        assertTrue("Should match Arabic Punycode URL without protocol",
313                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
314    }
315
316    @SmallTest
317    public void testAutoLinkWebUrl_doesNotMatchPunycodeTldThatStartsWithDash() throws Exception {
318        String url = "http://xn--fsqu00a.-xn--0zwm56d";
319        assertFalse("Should not match Punycode TLD that starts with dash",
320                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
321    }
322
323    @SmallTest
324    public void testAutoLinkWebUrl_doesNotMatchPunycodeTldThatEndsWithDash() throws Exception {
325        String url = "http://xn--fsqu00a.xn--0zwm56d-";
326        assertFalse("Should not match Punycode TLD that ends with dash",
327                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
328    }
329
330    @SmallTest
331    public void testAutoLinkWebUrl_matchesUrlWithUnicodeDomainName() throws Exception {
332        String url = "http://\uD604\uAE08\uC601\uC218\uC99D.kr";
333        assertTrue("Should match URL with Unicode domain name",
334                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
335
336        url = "\uD604\uAE08\uC601\uC218\uC99D.kr";
337        assertTrue("hould match URL without protocol and with Unicode domain name",
338                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
339    }
340
341    @SmallTest
342    public void testAutoLinkWebUrl_matchesUrlWithUnicodeTld() throws Exception {
343        String url = "\uB3C4\uBA54\uC778.\uD55C\uAD6D";
344        assertTrue("Should match URL with Unicode TLD",
345                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
346    }
347
348    @SmallTest
349    public void testAutoLinkWebUrl_matchesUrlWithUnicodePath() throws Exception {
350        String url = "http://brainstormtech.blogs.fortune.cnn.com/2010/03/11/" +
351                "top-five-moments-from-eric-schmidt\u2019s-talk-in-abu-dhabi/";
352        assertTrue("Should match URL with Unicode path",
353                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
354    }
355
356    @SmallTest
357    public void testAutoLinkWebUrl_doesNotMatchValidUrlWithInvalidProtocol() throws Exception {
358        String url = "ftp://www.example.com";
359        assertFalse("Should not match URL with invalid protocol",
360                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
361    }
362
363    @SmallTest
364    public void testAutoLinkWebUrl_matchesValidUrlWithPort() throws Exception {
365        String url = "http://www.example.com:8080";
366        assertTrue("Should match URL with port",
367                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
368    }
369
370    @SmallTest
371    public void testAutoLinkWebUrl_matchesUrlWithPortAndQuery() throws Exception {
372        String url = "http://www.example.com:8080/?foo=bar";
373        assertTrue("Should match URL with port and query",
374                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
375    }
376
377    @SmallTest
378    public void testAutoLinkWebUrl_matchesUrlWithTilde() throws Exception {
379        String url = "http://www.example.com:8080/~user/?foo=bar";
380        assertTrue("Should match URL with tilde",
381                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
382    }
383
384    @SmallTest
385    public void testAutoLinkWebUrl_matchesProtocolCaseInsensitive() throws Exception {
386        String url = "hTtP://android.com";
387        assertTrue("Protocol matching should be case insensitive",
388                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
389    }
390
391    @SmallTest
392    public void testAutoLinkWebUrl_matchesUrlStartingWithHttpAndDoesNotHaveTld() throws Exception {
393        String url = "http://android/#notld///a/n/d/r/o/i/d&p1=1&p2=2";
394        assertTrue("Should match URL without a TLD and starting with http ",
395                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
396    }
397
398    @SmallTest
399    public void testAutoLinkWebUrl_doesNotMatchUrlsWithoutProtocolAndWithUnknownTld()
400            throws Exception {
401        String url = "thank.you";
402        assertFalse("Should not match URL that does not start with a protocol and " +
403                "does not contain a known TLD",
404                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
405    }
406
407    @SmallTest
408    public void testAutoLinkWebUrl_doesNotPartiallyMatchUnknownProtocol() throws Exception {
409        String url = "ftp://foo.bar/baz";
410        assertFalse("Should not partially match URL with unknown protocol",
411                Patterns.AUTOLINK_WEB_URL.matcher(url).find());
412    }
413
414    @SmallTest
415    public void testAutoLinkWebUrl_matchesValidUrlWithEmoji() throws Exception {
416        String url = "Thank\u263A.com";
417        assertTrue("Should match URL with emoji",
418                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
419    }
420
421    @SmallTest
422    public void testAutoLinkWebUrl_doesNotMatchUrlsWithEmojiWithoutProtocolAndWithoutKnownTld()
423            throws Exception {
424        String url = "Thank\u263A.you";
425        assertFalse("Should not match URLs containing emoji and with unknown TLD",
426                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
427    }
428
429    @SmallTest
430    public void testAutoLinkWebUrl_doesNotMatchEmailAddress()
431            throws Exception {
432        String url = "android@android.com";
433        assertFalse("Should not match email address",
434                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
435    }
436
437    @SmallTest
438    public void testAutoLinkWebUrl_matchesDomainNameWithSurrogatePairs() throws Exception {
439        String url = "android\uD83C\uDF38.com";
440        assertTrue("Should match domain name with Unicode surrogate pairs",
441                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
442    }
443
444    @SmallTest
445    public void testAutoLinkWebUrl_matchesTldWithSurrogatePairs() throws Exception {
446        String url = "http://android.\uD83C\uDF38com";
447        assertTrue("Should match TLD with Unicode surrogate pairs",
448                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
449    }
450
451    @SmallTest
452    public void testAutoLinkWebUrl_matchesPathWithSurrogatePairs() throws Exception {
453        String url = "http://android.com/path-with-\uD83C\uDF38?v=\uD83C\uDF38";
454        assertTrue("Should match path and query with Unicode surrogate pairs",
455                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
456    }
457
458    @SmallTest
459    public void testAutoLinkWebUrl_doesNotMatchUrlWithExcludedSurrogate() throws Exception {
460        String url = "http://android\uD83F\uDFFE.com";
461        assertFalse("Should not match URL with excluded Unicode surrogate pair",
462                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
463    }
464
465    @SmallTest
466    public void testAutoLinkWebUrl_doesNotMatchUnicodeSpaces() throws Exception {
467        String part1 = "http://and";
468        String part2 = "roid";
469        String[] emptySpaces = new String[]{
470                "\u00A0", // no-break space
471                "\u2000", // en quad
472                "\u2001", // em quad
473                "\u2002", // en space
474                "\u2003", // em space
475                "\u2004", // three-per-em space
476                "\u2005", // four-per-em space
477                "\u2006", // six-per-em space
478                "\u2007", // figure space
479                "\u2008", // punctuation space
480                "\u2009", // thin space
481                "\u200A", // hair space
482                "\u2028", // line separator
483                "\u2029", // paragraph separator
484                "\u202F", // narrow no-break space
485                "\u3000" // ideographic space
486        };
487
488        for (String emptySpace : emptySpaces) {
489            String url = part1 + emptySpace + part2;
490            assertFalse("Should not match empty space - code:" + emptySpace.codePointAt(0),
491                    Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
492        }
493    }
494
495    @SmallTest
496    public void testAutoLinkWebUrl_matchesDomainNameWithDash() throws Exception {
497        String url = "http://a-nd.r-oid.com";
498        assertTrue("Should match dash in domain name",
499                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
500
501        url = "a-nd.r-oid.com";
502        assertTrue("Should match dash in domain name",
503                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
504    }
505
506    @SmallTest
507    public void testAutoLinkWebUrl_matchesDomainNameWithUnderscore() throws Exception {
508        String url = "http://a_nd.r_oid.com";
509        assertTrue("Should match underscore in domain name",
510                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
511
512        url = "a_nd.r_oid.com";
513        assertTrue("Should match underscore in domain name",
514                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
515    }
516
517    @SmallTest
518    public void testAutoLinkWebUrl_matchesPathAndQueryWithDollarSign() throws Exception {
519        String url = "http://android.com/path$?v=$val";
520        assertTrue("Should match dollar sign in path/query",
521                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
522
523        url = "android.com/path$?v=$val";
524        assertTrue("Should match dollar sign in path/query",
525                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
526    }
527
528    @SmallTest
529    public void testAutoLinkWebUrl_matchesEmptyPathWithQueryParams() throws Exception {
530        String url = "http://android.com?q=v";
531        assertTrue("Should match empty path with query param",
532                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
533
534        url = "android.com?q=v";
535        assertTrue("Should match empty path with query param",
536                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
537
538        url = "http://android.com/?q=v";
539        assertTrue("Should match empty path with query param",
540                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
541
542        url = "android.com/?q=v";
543        assertTrue("Should match empty path with query param",
544                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
545    }
546
547    // Tests for Patterns.IP_ADDRESS
548
549    @SmallTest
550    public void testIpPattern() throws Exception {
551        boolean t;
552
553        t = Patterns.IP_ADDRESS.matcher("172.29.86.3").matches();
554        assertTrue("Valid IP", t);
555
556        t = Patterns.IP_ADDRESS.matcher("1234.4321.9.9").matches();
557        assertFalse("Invalid IP", t);
558    }
559
560    // Tests for Patterns.DOMAIN_NAME
561
562    @SmallTest
563    public void testDomain_matchesPunycodeTld() throws Exception {
564        String domain = "xn--fsqu00a.xn--0zwm56d";
565        assertTrue("Should match domain name in Punycode",
566                Patterns.DOMAIN_NAME.matcher(domain).matches());
567    }
568
569    @SmallTest
570    public void testDomain_doesNotMatchPunycodeThatStartsWithDash() throws Exception {
571        String domain = "xn--fsqu00a.-xn--0zwm56d";
572        assertFalse("Should not match Punycode TLD that starts with a dash",
573                Patterns.DOMAIN_NAME.matcher(domain).matches());
574    }
575
576    @SmallTest
577    public void testDomain_doesNotMatchPunycodeThatEndsWithDash() throws Exception {
578        String domain = "xn--fsqu00a.xn--0zwm56d-";
579        assertFalse("Should not match Punycode TLD that ends with a dash",
580                Patterns.DOMAIN_NAME.matcher(domain).matches());
581    }
582
583    @SmallTest
584    public void testDomain_doesNotMatchPunycodeLongerThanAllowed() throws Exception {
585        String tld = "xn--";
586        for(int i=0; i<=6; i++) {
587            tld += "0123456789";
588        }
589        String domain = "xn--fsqu00a." + tld;
590        assertFalse("Should not match Punycode TLD that is longer than 63 chars",
591                Patterns.DOMAIN_NAME.matcher(domain).matches());
592    }
593
594    @SmallTest
595    public void testDomain_matchesObsoleteTld() throws Exception {
596        String domain = "test.yu";
597        assertTrue("Should match domain names with obsolete TLD",
598                Patterns.DOMAIN_NAME.matcher(domain).matches());
599    }
600
601    @SmallTest
602    public void testDomain_matchesWithSubDomain() throws Exception {
603        String domain = "mail.example.com";
604        assertTrue("Should match domain names with subdomains",
605                Patterns.DOMAIN_NAME.matcher(domain).matches());
606    }
607
608    @SmallTest
609    public void testDomain_matchesWithoutSubDomain() throws Exception {
610        String domain = "android.me";
611        assertTrue("Should match domain names without subdomains",
612                Patterns.DOMAIN_NAME.matcher(domain).matches());
613    }
614
615    @SmallTest
616    public void testDomain_matchesUnicodeDomainNames() throws Exception {
617        String domain = "\uD604\uAE08\uC601\uC218\uC99D.kr";
618        assertTrue("Should match unicodedomain names",
619                Patterns.DOMAIN_NAME.matcher(domain).matches());
620    }
621
622    @SmallTest
623    public void testDomain_doesNotMatchInvalidDomain() throws Exception {
624        String domain = "__+&42.xer";
625        assertFalse("Should not match invalid domain name",
626                Patterns.DOMAIN_NAME.matcher(domain).matches());
627    }
628
629    @SmallTest
630    public void testDomain_matchesPunycodeArabicDomainName() throws Exception {
631        String domain = "xn--4gbrim.xn----rmckbbajlc6dj7bxne2c.xn--wgbh1c";
632        assertTrue("Should match Punycode Arabic domain name",
633                Patterns.DOMAIN_NAME.matcher(domain).matches());
634    }
635
636    @SmallTest
637    public void testDomain_matchesDomainNameWithDash() throws Exception {
638        String url = "http://a-nd.r-oid.com";
639        assertTrue("Should match dash in domain name",
640                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
641
642        url = "a-nd.r-oid.com";
643        assertTrue("Should match dash in domain name",
644                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
645    }
646
647    @SmallTest
648    public void testDomain_matchesDomainNameWithUnderscore() throws Exception {
649        String url = "http://a_nd.r_oid.com";
650        assertTrue("Should match underscore in domain name",
651                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
652
653        url = "a_nd.r_oid.com";
654        assertTrue("Should match underscore in domain name",
655                Patterns.AUTOLINK_WEB_URL.matcher(url).matches());
656    }
657
658    // Tests for Patterns.AUTOLINK_EMAIL_ADDRESS
659
660    @SmallTest
661    public void testAutoLinkEmailAddress_matchesShortValidEmail() throws Exception {
662        String email = "a@a.co";
663        assertTrue("Should match short valid email: " + email,
664                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
665    }
666
667    @SmallTest
668    public void testAutoLinkEmailAddress_matchesRegularEmail() throws Exception {
669        String email = "email@android.com";
670        assertTrue("Should match email: " + email,
671                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
672    }
673
674    @SmallTest
675    public void testAutoLinkEmailAddress_matchesEmailWithMultipleSubdomains() throws Exception {
676        String email = "email@e.somelongdomainnameforandroid.abc.uk";
677        assertTrue("Should match email: " + email,
678                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
679    }
680
681    @SmallTest
682    public void testAutoLinkEmailAddress_matchesLocalPartWithDot() throws Exception {
683        String email = "e.mail@android.com";
684        assertTrue("Should match email: " + email,
685                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
686    }
687
688    @SmallTest
689    public void testAutoLinkEmailAddress_matchesLocalPartWithPlus() throws Exception {
690        String email = "e+mail@android.com";
691        assertTrue("Should match email: " + email,
692                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
693    }
694
695    @SmallTest
696    public void testAutoLinkEmailAddress_matchesLocalPartWithUnderscore() throws Exception {
697        String email = "e_mail@android.com";
698        assertTrue("Should match email: " + email,
699                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
700    }
701
702    @SmallTest
703    public void testAutoLinkEmailAddress_matchesLocalPartWithDash() throws Exception {
704        String email = "e-mail@android.com";
705        assertTrue("Should match email: " + email,
706                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
707    }
708
709    @SmallTest
710    public void testAutoLinkEmailAddress_matchesLocalPartWithApostrophe() throws Exception {
711        String email = "e'mail@android.com";
712        assertTrue("Should match email: " + email,
713                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
714    }
715
716    @SmallTest
717    public void testAutoLinkEmailAddress_matchesLocalPartWithDigits() throws Exception {
718        String email = "123@android.com";
719        assertTrue("Should match email: " + email,
720                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
721    }
722
723    @SmallTest
724    public void testAutoLinkEmailAddress_matchesUnicodeLocalPart() throws Exception {
725        String email = "\uD604\uAE08\uC601\uC218\uC99D@android.kr";
726        assertTrue("Should match email: " + email,
727                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
728    }
729
730    @SmallTest
731    public void testAutoLinkEmailAddress_matchesLocalPartWithEmoji() throws Exception {
732        String email = "smiley\u263A@android.com";
733        assertTrue("Should match email: " + email,
734                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
735    }
736
737    @SmallTest
738    public void testAutoLinkEmailAddress_matchesLocalPartWithSurrogatePairs() throws Exception {
739        String email = "\uD83C\uDF38@android.com";
740        assertTrue("Should match email: " + email,
741                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
742    }
743
744    @SmallTest
745    public void testAutoLinkEmailAddress_matchesDomainWithDash() throws Exception {
746        String email = "email@an-droid.com";
747        assertTrue("Should match email: " + email,
748                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
749    }
750
751    @SmallTest
752    public void testAutoLinkEmailAddress_matchesUnicodeDomain() throws Exception {
753        String email = "email@\uD604\uAE08\uC601\uC218\uC99D.kr";
754        assertTrue("Should match email: " + email,
755                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
756    }
757
758    @SmallTest
759    public void testAutoLinkEmailAddress_matchesUnicodeLocalPartAndDomain() throws Exception {
760        String email = "\uD604\uAE08\uC601\uC218\uC99D@\uD604\uAE08\uC601\uC218\uC99D.kr";
761        assertTrue("Should match email: " + email,
762                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
763    }
764
765    @SmallTest
766    public void testAutoLinkEmailAddress_matchesDomainWithEmoji() throws Exception {
767        String email = "smiley@\u263Aandroid.com";
768        assertTrue("Should match email: " + email,
769                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
770    }
771
772    @SmallTest
773    public void testAutoLinkEmailAddress_matchesDomainWithSurrogatePairs() throws Exception {
774        String email = "email@\uD83C\uDF38android.com";
775        assertTrue("Should match email: " + email,
776                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
777    }
778
779    @SmallTest
780    public void testAutoLinkEmailAddress_matchesLocalPartAndDomainWithSurrogatePairs()
781            throws Exception {
782        String email = "\uD83C\uDF38@\uD83C\uDF38android.com";
783        assertTrue("Should match email: " + email,
784                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
785    }
786
787    @SmallTest
788    public void testAutoLinkEmailAddress_doesNotMatchStringWithoutAtSign() throws Exception {
789        String email = "android.com";
790        assertFalse("Should not match email: " + email,
791                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
792    }
793
794    @SmallTest
795    public void testAutoLinkEmailAddress_doesNotMatchPlainString() throws Exception {
796        String email = "email";
797        assertFalse("Should not match email: " + email,
798                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
799    }
800
801    @SmallTest
802    public void testAutoLinkEmailAddress_doesNotMatchStringWithMultipleAtSigns() throws Exception {
803        String email = "email@android@android.com";
804        assertFalse("Should not match email: " + email,
805                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
806    }
807
808    @SmallTest
809    public void testAutoLinkEmailAddress_doesNotMatchEmailWithoutTld() throws Exception {
810        String email = "email@android";
811        assertFalse("Should not match email: " + email,
812                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
813    }
814
815    @SmallTest
816    public void testAutoLinkEmailAddress_doesNotMatchLocalPartEndingWithDot() throws Exception {
817        String email = "email.@android.com";
818        assertFalse("Should not match email: " + email,
819                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
820    }
821
822    @SmallTest
823    public void testAutoLinkEmailAddress_doesNotMatchLocalPartStartingWithDot() throws Exception {
824        String email = ".email@android.com";
825        assertFalse("Should not match email: " + email,
826                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
827    }
828
829    @SmallTest
830    public void testAutoLinkEmailAddress_doesNotMatchDomainStartingWithDash() throws Exception {
831        String email = "email@-android.com";
832        assertFalse("Should not match email: " + email,
833                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
834    }
835
836    @SmallTest
837    public void testAutoLinkEmailAddress_doesNotMatchDomainWithConsecutiveDots() throws Exception {
838        String email = "email@android..com";
839        assertFalse("Should not match email: " + email,
840                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
841    }
842
843    @SmallTest
844    public void testAutoLinkEmailAddress_doesNotMatchEmailWithIpAsDomain() throws Exception {
845        String email = "email@127.0.0.1";
846        assertFalse("Should not match email: " + email,
847                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
848    }
849
850    @SmallTest
851    public void testAutoLinkEmailAddress_doesNotMatchEmailWithInvalidTld() throws Exception {
852        String email = "email@android.c";
853        assertFalse("Should not match email: " + email,
854                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
855    }
856
857    @SmallTest
858    public void testAutoLinkEmailAddress_matchesLocalPartUpTo64Chars() throws Exception {
859        String localPart = "";
860        for (int i = 0; i < 64; i++) {
861            localPart += "a";
862        }
863        String email = localPart + "@android.com";
864
865        assertTrue("Should match local part of length: " + localPart.length(),
866                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
867
868        email = localPart + "a@android.com";
869        assertFalse("Should not match local part of length: " + localPart.length(),
870                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
871    }
872
873    @SmallTest
874    public void testAutoLinkEmailAddress_matchesSubdomainUpTo63Chars() throws Exception {
875        String subdomain = "";
876        for (int i = 0; i < 63; i++) {
877            subdomain += "a";
878        }
879        String email = "email@" + subdomain + ".com";
880
881        assertTrue("Should match subdomain of length: " + subdomain.length(),
882                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
883
884        subdomain += "a";
885        email = "email@" + subdomain + ".com";
886        assertFalse("Should not match local part of length: " + subdomain.length(),
887                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
888    }
889
890    @SmallTest
891    public void testAutoLinkEmailAddress_matchesDomainUpTo255Chars() throws Exception {
892        String longDomain = "";
893        while (longDomain.length() <= 250) {
894            longDomain += "d.";
895        }
896        longDomain += "com";
897        assertEquals(255, longDomain.length());
898        String email = "a@" + longDomain;
899
900        assertTrue("Should match domain of length: " + longDomain.length(),
901                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
902
903        email = email + "m";
904        assertEquals(258, email.length());
905        assertFalse("Should not match domain of length: " + longDomain.length(),
906                Patterns.AUTOLINK_EMAIL_ADDRESS.matcher(email).matches());
907    }
908
909    // Tests for Patterns.PHONE
910
911    @SmallTest
912    public void testPhonePattern() throws Exception {
913        boolean t;
914
915        t = Patterns.PHONE.matcher("(919) 555-1212").matches();
916        assertTrue("Valid phone", t);
917
918        t = Patterns.PHONE.matcher("2334 9323/54321").matches();
919        assertFalse("Invalid phone", t);
920
921        String[] tests = {
922                "Me: 16505551212 this\n",
923                "Me: 6505551212 this\n",
924                "Me: 5551212 this\n",
925                "Me: 2211 this\n",
926                "Me: 112 this\n",
927
928                "Me: 1-650-555-1212 this\n",
929                "Me: (650) 555-1212 this\n",
930                "Me: +1 (650) 555-1212 this\n",
931                "Me: +1-650-555-1212 this\n",
932                "Me: 650-555-1212 this\n",
933                "Me: 555-1212 this\n",
934
935                "Me: 1.650.555.1212 this\n",
936                "Me: (650) 555.1212 this\n",
937                "Me: +1 (650) 555.1212 this\n",
938                "Me: +1.650.555.1212 this\n",
939                "Me: 650.555.1212 this\n",
940                "Me: 555.1212 this\n",
941
942                "Me: 1 650 555 1212 this\n",
943                "Me: (650) 555 1212 this\n",
944                "Me: +1 (650) 555 1212 this\n",
945                "Me: +1 650 555 1212 this\n",
946                "Me: 650 555 1212 this\n",
947                "Me: 555 1212 this\n",
948        };
949
950        for (String test : tests) {
951            Matcher m = Patterns.PHONE.matcher(test);
952
953            assertTrue("Valid phone " + test, m.find());
954        }
955    }
956}
957