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