Home | History | Annotate | Download | only in textclassifier
      1 /*
      2  * Copyright (C) 2018 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 androidx.textclassifier;
     18 
     19 import static org.junit.Assert.assertEquals;
     20 import static org.junit.Assert.assertTrue;
     21 
     22 import android.os.Parcel;
     23 import android.support.test.filters.SmallTest;
     24 import android.support.test.runner.AndroidJUnit4;
     25 import android.text.Spannable;
     26 import android.text.SpannableString;
     27 import android.text.style.ClickableSpan;
     28 import android.view.View;
     29 
     30 import androidx.annotation.Nullable;
     31 import androidx.collection.ArrayMap;
     32 import androidx.core.os.LocaleListCompat;
     33 
     34 import org.junit.Before;
     35 import org.junit.Test;
     36 import org.junit.runner.RunWith;
     37 
     38 import java.util.ArrayList;
     39 import java.util.Arrays;
     40 import java.util.List;
     41 import java.util.Map;
     42 
     43 /** Instrumentation unit tests for {@link TextLinks}. */
     44 @SmallTest
     45 @RunWith(AndroidJUnit4.class)
     46 public final class TextLinksTest {
     47 
     48     private static class NoOpSpan extends ClickableSpan {
     49         @Override
     50         public void onClick(View v) {
     51             // Do nothing.
     52         }
     53     }
     54 
     55     private static class CustomTextLinkSpan extends TextLinks.TextLinkSpan {
     56         CustomTextLinkSpan(@Nullable TextLinks.TextLink textLink) {
     57             super(textLink);
     58         }
     59     }
     60 
     61     private static class CustomSpanFactory implements TextLinks.SpanFactory {
     62         @Override
     63         public TextLinks.TextLinkSpan createSpan(TextLinks.TextLink textLink) {
     64             return new CustomTextLinkSpan(textLink);
     65         }
     66     }
     67 
     68     private TextClassifier mClassifier;
     69     private Map<String, Float> mDummyEntityScores;
     70 
     71     @Before
     72     public void setup() {
     73         mClassifier = new TextClassifier();
     74         mDummyEntityScores = new ArrayMap<>();
     75         mDummyEntityScores.put(TextClassifier.TYPE_ADDRESS, 0.2f);
     76         mDummyEntityScores.put(TextClassifier.TYPE_PHONE, 0.7f);
     77         mDummyEntityScores.put(TextClassifier.TYPE_OTHER, 0.3f);
     78     }
     79 
     80     private Map<String, Float> getEntityScores(float address, float phone, float other) {
     81         final Map<String, Float> result = new ArrayMap<>();
     82         if (address > 0.f) {
     83             result.put(TextClassifier.TYPE_ADDRESS, address);
     84         }
     85         if (phone > 0.f) {
     86             result.put(TextClassifier.TYPE_PHONE, phone);
     87         }
     88         if (other > 0.f) {
     89             result.put(TextClassifier.TYPE_OTHER, other);
     90         }
     91         return result;
     92     }
     93 
     94     @Test
     95     public void testParcel() {
     96         final String fullText = "this is just a test";
     97         final TextLinks reference = new TextLinks.Builder(fullText)
     98                 .addLink(0, 4, getEntityScores(0.f, 0.f, 1.f))
     99                 .addLink(5, 12, getEntityScores(.8f, .1f, .5f))
    100                 .build();
    101 
    102         // Parcel and unparcel.
    103         final Parcel parcel = Parcel.obtain();
    104         reference.writeToParcel(parcel, reference.describeContents());
    105         parcel.setDataPosition(0);
    106         final TextLinks result = TextLinks.CREATOR.createFromParcel(parcel);
    107         final List<TextLinks.TextLink> resultList = new ArrayList<>(result.getLinks());
    108 
    109         assertEquals(2, resultList.size());
    110         assertEquals(0, resultList.get(0).getStart());
    111         assertEquals(4, resultList.get(0).getEnd());
    112         assertEquals(1, resultList.get(0).getEntityCount());
    113         assertEquals(TextClassifier.TYPE_OTHER, resultList.get(0).getEntity(0));
    114         assertEquals(1.f, resultList.get(0).getConfidenceScore(TextClassifier.TYPE_OTHER),
    115                 1e-7f);
    116         assertEquals(5, resultList.get(1).getStart());
    117         assertEquals(12, resultList.get(1).getEnd());
    118         assertEquals(3, resultList.get(1).getEntityCount());
    119         assertEquals(TextClassifier.TYPE_ADDRESS, resultList.get(1).getEntity(0));
    120         assertEquals(TextClassifier.TYPE_OTHER, resultList.get(1).getEntity(1));
    121         assertEquals(TextClassifier.TYPE_PHONE, resultList.get(1).getEntity(2));
    122         assertEquals(.8f, resultList.get(1).getConfidenceScore(TextClassifier.TYPE_ADDRESS), 1e-7f);
    123         assertEquals(.5f, resultList.get(1).getConfidenceScore(TextClassifier.TYPE_OTHER), 1e-7f);
    124         assertEquals(.1f, resultList.get(1).getConfidenceScore(TextClassifier.TYPE_PHONE), 1e-7f);
    125     }
    126 
    127     @Test
    128     public void testParcelOptions() {
    129         TextClassifier.EntityConfig entityConfig = new TextClassifier.EntityConfig(
    130                 TextClassifier.ENTITY_PRESET_NONE);
    131         entityConfig.includeEntities("a", "b", "c");
    132         entityConfig.excludeEntities("b");
    133         final String callingPackageName = "packageName";
    134         TextLinks.Options reference = new TextLinks.Options()
    135                 .setDefaultLocales(LocaleListCompat.forLanguageTags("en-US,de-DE"))
    136                 .setEntityConfig(entityConfig)
    137                 .setApplyStrategy(TextLinks.APPLY_STRATEGY_REPLACE)
    138                 .setSpanFactory(new CustomSpanFactory())
    139                 .setCallingPackageName(callingPackageName);
    140 
    141         final Parcel parcel = Parcel.obtain();
    142         reference.writeToParcel(parcel, reference.describeContents());
    143         parcel.setDataPosition(0);
    144         TextLinks.Options result = TextLinks.Options.CREATOR.createFromParcel(parcel);
    145 
    146         assertEquals("en-US,de-DE", result.getDefaultLocales().toLanguageTags());
    147         assertEquals(Arrays.asList("a", "c"), result.getEntityConfig().getEntities(mClassifier));
    148         assertEquals(TextLinks.APPLY_STRATEGY_REPLACE, result.getApplyStrategy());
    149         assertEquals(null, result.getSpanFactory());
    150         assertEquals(callingPackageName, result.getCallingPackageName());
    151     }
    152 
    153     @Test
    154     public void testApplyDifferentText() {
    155         SpannableString text = new SpannableString("foo");
    156         TextLinks links = new TextLinks.Builder("bar").build();
    157         assertEquals(links.apply(text, TextLinks.APPLY_STRATEGY_REPLACE, null),
    158                 TextLinks.STATUS_DIFFERENT_TEXT);
    159     }
    160 
    161     @Test
    162     public void testApplyNoLinks() {
    163         SpannableString text = new SpannableString("foo");
    164         TextLinks links = new TextLinks.Builder(text.toString()).build();
    165         assertEquals(links.apply(text, TextLinks.APPLY_STRATEGY_REPLACE, null),
    166                 TextLinks.STATUS_NO_LINKS_FOUND);
    167     }
    168 
    169     @Test
    170     public void testApplyNoApplied() {
    171         SpannableString text = new SpannableString("foo");
    172         text.setSpan(new NoOpSpan(), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    173         TextLinks links = new TextLinks.Builder(text.toString()).addLink(
    174                 0, 3, mDummyEntityScores).build();
    175         assertEquals(links.apply(text, TextLinks.APPLY_STRATEGY_IGNORE, null),
    176                 TextLinks.STATUS_NO_LINKS_APPLIED);
    177     }
    178 
    179     @Test
    180     public void testApplyAppliedDefaultSpanFactory() {
    181         SpannableString text = new SpannableString("foo");
    182         TextLinks links = new TextLinks.Builder(text.toString()).addLink(
    183                 0, 3, mDummyEntityScores).build();
    184         assertEquals(links.apply(text, TextLinks.APPLY_STRATEGY_IGNORE, null),
    185                 TextLinks.STATUS_LINKS_APPLIED);
    186         TextLinks.TextLinkSpan[] spans = text.getSpans(0, 3, TextLinks.TextLinkSpan.class);
    187         assertEquals(spans.length, 1);
    188         assertTrue(links.getLinks().contains(spans[0].getTextLink()));
    189     }
    190 
    191     @Test
    192     public void testApplyAppliedDefaultSpanFactoryReplace() {
    193         SpannableString text = new SpannableString("foo");
    194         text.setSpan(new NoOpSpan(), 0, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    195         TextLinks links = new TextLinks.Builder(text.toString()).addLink(
    196                 0, 3, mDummyEntityScores).build();
    197         assertEquals(links.apply(text, TextLinks.APPLY_STRATEGY_REPLACE, null),
    198                 TextLinks.STATUS_LINKS_APPLIED);
    199         TextLinks.TextLinkSpan[] spans = text.getSpans(0, 3, TextLinks.TextLinkSpan.class);
    200         assertEquals(spans.length, 1);
    201         assertTrue(links.getLinks().contains(spans[0].getTextLink()));
    202     }
    203 
    204     @Test
    205     public void testApplyAppliedCustomSpanFactory() {
    206         SpannableString text = new SpannableString("foo");
    207         TextLinks links = new TextLinks.Builder(text.toString()).addLink(
    208                 0, 3, mDummyEntityScores).build();
    209         assertEquals(links.apply(text, TextLinks.APPLY_STRATEGY_IGNORE, new CustomSpanFactory()),
    210                 TextLinks.STATUS_LINKS_APPLIED);
    211         CustomTextLinkSpan[] spans = text.getSpans(0, 3, CustomTextLinkSpan.class);
    212         assertEquals(spans.length, 1);
    213         assertTrue(links.getLinks().contains(spans[0].getTextLink()));
    214     }
    215 }
    216