Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.text.util;
     18 
     19 import static org.junit.Assert.assertEquals;
     20 import static org.junit.Assert.assertFalse;
     21 import static org.junit.Assert.assertTrue;
     22 
     23 import android.content.Context;
     24 import android.content.res.Configuration;
     25 import android.os.LocaleList;
     26 import android.support.test.InstrumentationRegistry;
     27 import android.support.test.filters.SmallTest;
     28 import android.support.test.runner.AndroidJUnit4;
     29 import android.text.Spannable;
     30 import android.text.SpannableString;
     31 import android.text.method.LinkMovementMethod;
     32 import android.text.style.URLSpan;
     33 import android.util.Patterns;
     34 import android.view.textclassifier.SystemTextClassifier;
     35 import android.view.textclassifier.TextClassificationConstants;
     36 import android.view.textclassifier.TextClassifier;
     37 import android.view.textclassifier.TextClassifierImpl;
     38 import android.view.textclassifier.TextLinks.TextLinkSpan;
     39 import android.widget.TextView;
     40 
     41 import org.junit.After;
     42 import org.junit.Before;
     43 import org.junit.Test;
     44 import org.junit.runner.RunWith;
     45 
     46 import java.util.Arrays;
     47 import java.util.HashSet;
     48 import java.util.List;
     49 import java.util.Locale;
     50 import java.util.Set;
     51 
     52 /**
     53  * LinkifyTest tests {@link Linkify}.
     54  */
     55 @SmallTest
     56 @RunWith(AndroidJUnit4.class)
     57 public class LinkifyTest {
     58 
     59     private static final LocaleList LOCALE_LIST_US = new LocaleList(Locale.US);
     60     private LocaleList mOriginalLocales;
     61     private Context mContext;
     62 
     63     @Before
     64     public void setup() {
     65         mContext = InstrumentationRegistry.getContext();
     66         mOriginalLocales = LocaleList.getDefault();
     67         LocaleList.setDefault(LOCALE_LIST_US);
     68     }
     69 
     70     @After
     71     public void teardown() {
     72         LocaleList.setDefault(mOriginalLocales);
     73     }
     74 
     75     @Test
     76     public void testNothing() {
     77         TextView tv;
     78 
     79         tv = new TextView(createUsEnglishContext());
     80         tv.setText("Hey, foo (at) google.com, call 415-555-1212.");
     81 
     82         assertFalse(tv.getMovementMethod() instanceof LinkMovementMethod);
     83         assertTrue(tv.getUrls().length == 0);
     84     }
     85 
     86     @Test
     87     public void testNormal() {
     88         TextView tv;
     89 
     90         tv = new TextView(createUsEnglishContext());
     91         tv.setAutoLinkMask(Linkify.ALL);
     92         tv.setText("Hey, foo (at) google.com, call +1-415-555-1212.");
     93 
     94         assertTrue(tv.getMovementMethod() instanceof LinkMovementMethod);
     95         assertTrue(tv.getUrls().length == 2);
     96     }
     97 
     98     @Test
     99     public void testUnclickable() {
    100         TextView tv;
    101 
    102         tv = new TextView(createUsEnglishContext());
    103         tv.setAutoLinkMask(Linkify.ALL);
    104         tv.setLinksClickable(false);
    105         tv.setText("Hey, foo (at) google.com, call +1-415-555-1212.");
    106 
    107         assertFalse(tv.getMovementMethod() instanceof LinkMovementMethod);
    108         assertTrue(tv.getUrls().length == 2);
    109     }
    110 
    111     private Context createUsEnglishContext() {
    112         final Configuration overrideConfig = new Configuration();
    113         overrideConfig.setLocales(LOCALE_LIST_US);
    114         return mContext.createConfigurationContext(overrideConfig);
    115     }
    116 
    117     @Test
    118     public void testAddLinks_addsLinksWhenDefaultSchemeIsNull() {
    119         Spannable spannable = new SpannableString("any https://android.com any android.com any");
    120         Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, null, null, null);
    121 
    122         URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
    123         assertEquals("android.com and https://android.com should be linkified", 2, spans.length);
    124         assertEquals("https://android.com", spans[0].getURL());
    125         assertEquals("android.com", spans[1].getURL());
    126     }
    127 
    128     @Test
    129     public void testAddLinks_addsLinksWhenSchemesArrayIsNull() {
    130         Spannable spannable = new SpannableString("any https://android.com any android.com any");
    131         Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, "http://", null, null);
    132 
    133         URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
    134         assertEquals("android.com and https://android.com should be linkified", 2, spans.length);
    135         // expected behavior, passing null schemes array means: prepend defaultScheme to all links.
    136         assertEquals("http://https://android.com", spans[0].getURL());
    137         assertEquals("http://android.com", spans[1].getURL());
    138     }
    139 
    140     @Test
    141     public void testAddLinks_prependsDefaultSchemeToBeginingOfLink() {
    142         Spannable spannable = new SpannableString("any android.com any");
    143         Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, "http://",
    144                 new String[] { "http://", "https://"}, null, null);
    145 
    146         URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
    147         assertEquals("android.com should be linkified", 1, spans.length);
    148         assertEquals("http://android.com", spans[0].getURL());
    149     }
    150 
    151     @Test
    152     public void testAddLinks_doesNotPrependSchemeIfSchemeExists() {
    153         Spannable spannable = new SpannableString("any https://android.com any");
    154         Linkify.addLinks(spannable, Patterns.AUTOLINK_WEB_URL, "http://",
    155                 new String[] { "http://", "https://"}, null, null);
    156 
    157         URLSpan[] spans = spannable.getSpans(0, spannable.length(), URLSpan.class);
    158         assertEquals("android.com should be linkified", 1, spans.length);
    159         assertEquals("https://android.com", spans[0].getURL());
    160     }
    161 
    162     @Test
    163     public void testAddLinksAsync_useLegacyIfSmartDisabled_localTextClassifier()
    164             throws Exception {
    165         final TextClassificationConstants settings =
    166                 TextClassificationConstants.loadFromString("smart_linkify_enabled=false");
    167         final TextClassifier classifier = new TextClassifierImpl(mContext, settings);
    168         testAddLinksAsync_useLegacyIfSmartDisabled(classifier);
    169     }
    170 
    171     @Test
    172     public void testAddLinksAsync_useLegacyIfSmartDisabled_systemTextClassifier()
    173             throws Exception {
    174         final TextClassificationConstants settings =
    175                 TextClassificationConstants.loadFromString("smart_linkify_enabled=false");
    176         final TextClassifier classifier = new SystemTextClassifier(mContext, settings);
    177         testAddLinksAsync_useLegacyIfSmartDisabled(classifier);
    178     }
    179 
    180     private void testAddLinksAsync_useLegacyIfSmartDisabled(TextClassifier classifier)
    181             throws Exception {
    182         final int linkMask = Linkify.EMAIL_ADDRESSES | Linkify.PHONE_NUMBERS | Linkify.WEB_URLS;
    183         final String string = "example (at) android.com\n"
    184                 + "(415) 555-1212\n"
    185                 + "http://android.com\n"
    186                 + "100 Android Rd California";
    187         final Spannable expected = new SpannableString(string);
    188         final Spannable actual = new SpannableString(string);
    189 
    190         Linkify.addLinks(expected, linkMask);  // legacy.
    191         Linkify.addLinksAsync(actual, classifier, linkMask).get();
    192 
    193         final URLSpan[] expectedSpans = expected.getSpans(0, expected.length(), URLSpan.class);
    194         final TextLinkSpan[] actualSpans = actual.getSpans(0, actual.length(), TextLinkSpan.class);
    195         assertEquals(expectedSpans.length, actualSpans.length);
    196         final Set<List> expectedLinkSpec = new HashSet<>();
    197         final Set<List> actualLinkSpec = new HashSet<>();
    198         for (int i = 0; i < expectedSpans.length; i++) {
    199             final URLSpan expectedSpan = expectedSpans[i];
    200             final TextLinkSpan actualSpan = actualSpans[i];
    201             expectedLinkSpec.add(Arrays.asList(
    202                     expected.getSpanStart(expectedSpan),
    203                     expected.getSpanEnd(expectedSpan),
    204                     expectedSpan.getURL()));
    205             actualLinkSpec.add(Arrays.asList(
    206                     actual.getSpanStart(actualSpan),
    207                     actual.getSpanEnd(actualSpan),
    208                     actualSpan.getUrl()));
    209         }
    210         assertEquals(expectedLinkSpec, actualLinkSpec);
    211     }
    212 }
    213