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