blob: 9015e92a4f08e1ea58bfbc5abcf9f49e93e17d29 [file] [log] [blame]
Abodunrinwa Toki65b25272017-04-13 17:25:59 +01001/*
2 * Copyright (C) 2017 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
17package android.view.textclassifier;
18
Richard Ledleydb18a572017-11-30 17:33:51 +000019import static org.hamcrest.CoreMatchers.not;
Abodunrinwa Toki65b25272017-04-13 17:25:59 +010020import static org.junit.Assert.assertEquals;
Abodunrinwa Toki253827f2018-04-24 19:19:48 +010021import static org.junit.Assert.assertFalse;
22import static org.junit.Assert.assertNotSame;
Abodunrinwa Toki65b25272017-04-13 17:25:59 +010023import static org.junit.Assert.assertThat;
Jan Althaus108aad32018-01-30 15:26:55 +010024import static org.junit.Assert.assertTrue;
Abodunrinwa Toki253827f2018-04-24 19:19:48 +010025import static org.mockito.Matchers.argThat;
26import static org.mockito.Mockito.any;
27import static org.mockito.Mockito.anyInt;
Abodunrinwa Toki65b25272017-04-13 17:25:59 +010028import static org.mockito.Mockito.mock;
Abodunrinwa Toki253827f2018-04-24 19:19:48 +010029import static org.mockito.Mockito.when;
Abodunrinwa Toki65b25272017-04-13 17:25:59 +010030
Abodunrinwa Tokic7073a42018-02-28 23:02:13 +000031import android.content.Context;
Abodunrinwa Toki253827f2018-04-24 19:19:48 +010032import android.content.ContextWrapper;
33import android.content.Intent;
34import android.content.pm.PackageManager;
35import android.content.pm.ResolveInfo;
36import android.net.Uri;
Abodunrinwa Toki65b25272017-04-13 17:25:59 +010037import android.os.LocaleList;
Abodunrinwa Tokic7073a42018-02-28 23:02:13 +000038import android.service.textclassifier.TextClassifierService;
Abodunrinwa Toki65b25272017-04-13 17:25:59 +010039import android.support.test.InstrumentationRegistry;
40import android.support.test.filters.SmallTest;
41import android.support.test.runner.AndroidJUnit4;
Abodunrinwa Tokia69950c2018-11-29 13:51:56 +000042import android.text.Spannable;
43import android.text.SpannableString;
Abodunrinwa Toki65b25272017-04-13 17:25:59 +010044
45import org.hamcrest.BaseMatcher;
46import org.hamcrest.Description;
47import org.hamcrest.Matcher;
48import org.junit.Before;
49import org.junit.Test;
50import org.junit.runner.RunWith;
Abodunrinwa Toki253827f2018-04-24 19:19:48 +010051import org.mockito.ArgumentMatcher;
Abodunrinwa Toki65b25272017-04-13 17:25:59 +010052
Jan Althaus108aad32018-01-30 15:26:55 +010053import java.util.Arrays;
Richard Ledley1fc998b2018-02-16 15:45:06 +000054import java.util.Collections;
Abodunrinwa Toki080c8542018-03-27 00:04:06 +010055import java.util.List;
Jan Althaus108aad32018-01-30 15:26:55 +010056
Abodunrinwa Toki65b25272017-04-13 17:25:59 +010057@SmallTest
58@RunWith(AndroidJUnit4.class)
59public class TextClassificationManagerTest {
60
Lukas Zilkaf8c36bf2018-02-07 20:30:08 +010061 private static final LocaleList LOCALES = LocaleList.forLanguageTags("en-US");
Abodunrinwa Tokib4162972017-05-05 18:07:17 +010062 private static final String NO_TYPE = null;
Abodunrinwa Toki65b25272017-04-13 17:25:59 +010063
Abodunrinwa Tokic7073a42018-02-28 23:02:13 +000064 private Context mContext;
Abodunrinwa Toki65b25272017-04-13 17:25:59 +010065 private TextClassificationManager mTcm;
66 private TextClassifier mClassifier;
67
68 @Before
69 public void setup() {
Abodunrinwa Tokic7073a42018-02-28 23:02:13 +000070 mContext = InstrumentationRegistry.getTargetContext();
71 mTcm = mContext.getSystemService(TextClassificationManager.class);
Abodunrinwa Toki080c8542018-03-27 00:04:06 +010072 // Test with the local textClassifier only. (We only bundle "en" model by default).
73 // It's hard to reliably test the results of the device's TextClassifierServiceImpl here.
74 mClassifier = mTcm.getTextClassifier(TextClassifier.LOCAL);
Abodunrinwa Toki65b25272017-04-13 17:25:59 +010075 }
76
77 @Test
78 public void testSmartSelection() {
79 if (isTextClassifierDisabled()) return;
80
81 String text = "Contact me at droid@android.com";
82 String selected = "droid";
83 String suggested = "droid@android.com";
84 int startIndex = text.indexOf(selected);
85 int endIndex = startIndex + selected.length();
86 int smartStartIndex = text.indexOf(suggested);
87 int smartEndIndex = smartStartIndex + suggested.length();
Abodunrinwa Toki080c8542018-03-27 00:04:06 +010088 TextSelection.Request request = new TextSelection.Request.Builder(
89 text, startIndex, endIndex)
90 .setDefaultLocales(LOCALES)
91 .build();
Abodunrinwa Toki65b25272017-04-13 17:25:59 +010092
Abodunrinwa Toki080c8542018-03-27 00:04:06 +010093 TextSelection selection = mClassifier.suggestSelection(request);
Abodunrinwa Toki4d232d62017-11-23 12:22:45 +000094 assertThat(selection,
Abodunrinwa Tokia2df6e52017-04-13 09:56:52 +010095 isTextSelection(smartStartIndex, smartEndIndex, TextClassifier.TYPE_EMAIL));
96 }
97
98 @Test
Abodunrinwa Toki65b25272017-04-13 17:25:59 +010099 public void testSmartSelection_url() {
100 if (isTextClassifierDisabled()) return;
101
102 String text = "Visit http://www.android.com for more information";
103 String selected = "http";
104 String suggested = "http://www.android.com";
105 int startIndex = text.indexOf(selected);
106 int endIndex = startIndex + selected.length();
107 int smartStartIndex = text.indexOf(suggested);
108 int smartEndIndex = smartStartIndex + suggested.length();
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100109 TextSelection.Request request = new TextSelection.Request.Builder(
110 text, startIndex, endIndex)
111 .setDefaultLocales(LOCALES)
112 .build();
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100113
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100114 TextSelection selection = mClassifier.suggestSelection(request);
Abodunrinwa Toki4d232d62017-11-23 12:22:45 +0000115 assertThat(selection,
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100116 isTextSelection(smartStartIndex, smartEndIndex, TextClassifier.TYPE_URL));
117 }
118
119 @Test
Abodunrinwa Tokib4162972017-05-05 18:07:17 +0100120 public void testSmartSelection_withEmoji() {
121 if (isTextClassifierDisabled()) return;
122
123 String text = "\uD83D\uDE02 Hello.";
124 String selected = "Hello";
125 int startIndex = text.indexOf(selected);
126 int endIndex = startIndex + selected.length();
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100127 TextSelection.Request request = new TextSelection.Request.Builder(
128 text, startIndex, endIndex)
129 .setDefaultLocales(LOCALES)
130 .build();
Abodunrinwa Tokib4162972017-05-05 18:07:17 +0100131
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100132 TextSelection selection = mClassifier.suggestSelection(request);
Abodunrinwa Toki4d232d62017-11-23 12:22:45 +0000133 assertThat(selection,
Abodunrinwa Tokib4162972017-05-05 18:07:17 +0100134 isTextSelection(startIndex, endIndex, NO_TYPE));
135 }
136
137 @Test
Abodunrinwa Tokie0b57892017-04-28 19:59:57 +0100138 public void testClassifyText() {
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100139 if (isTextClassifierDisabled()) return;
140
141 String text = "Contact me at droid@android.com";
142 String classifiedText = "droid@android.com";
143 int startIndex = text.indexOf(classifiedText);
144 int endIndex = startIndex + classifiedText.length();
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100145 TextClassification.Request request = new TextClassification.Request.Builder(
146 text, startIndex, endIndex)
147 .setDefaultLocales(LOCALES)
148 .build();
Abodunrinwa Toki4d232d62017-11-23 12:22:45 +0000149
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100150 TextClassification classification = mClassifier.classifyText(request);
Jan Althaus20d346e2018-03-23 14:03:52 +0100151 assertThat(classification, isTextClassification(classifiedText, TextClassifier.TYPE_EMAIL));
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100152 }
153
154 @Test
Abodunrinwa Tokie0b57892017-04-28 19:59:57 +0100155 public void testTextClassifyText_url() {
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100156 if (isTextClassifierDisabled()) return;
157
Abodunrinwa Toki86ef9822017-05-11 20:05:50 +0100158 String text = "Visit www.android.com for more information";
Abodunrinwa Toki70d41cd2017-05-02 21:43:41 +0100159 String classifiedText = "www.android.com";
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100160 int startIndex = text.indexOf(classifiedText);
161 int endIndex = startIndex + classifiedText.length();
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100162 TextClassification.Request request = new TextClassification.Request.Builder(
163 text, startIndex, endIndex)
164 .setDefaultLocales(LOCALES)
165 .build();
Abodunrinwa Toki4d232d62017-11-23 12:22:45 +0000166
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100167 TextClassification classification = mClassifier.classifyText(request);
Jan Althaus20d346e2018-03-23 14:03:52 +0100168 assertThat(classification, isTextClassification(classifiedText, TextClassifier.TYPE_URL));
Abodunrinwa Toki86ef9822017-05-11 20:05:50 +0100169 }
170
171 @Test
Jan Althauseaff57e2018-02-12 12:47:27 +0100172 public void testTextClassifyText_address() {
173 if (isTextClassifierDisabled()) return;
174
175 String text = "Brandschenkestrasse 110, Zürich, Switzerland";
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100176 TextClassification.Request request = new TextClassification.Request.Builder(
177 text, 0, text.length())
178 .setDefaultLocales(LOCALES)
179 .build();
180
181 TextClassification classification = mClassifier.classifyText(request);
Jan Althaus20d346e2018-03-23 14:03:52 +0100182 assertThat(classification, isTextClassification(text, TextClassifier.TYPE_ADDRESS));
Jan Althauseaff57e2018-02-12 12:47:27 +0100183 }
184
185 @Test
Abodunrinwa Toki86ef9822017-05-11 20:05:50 +0100186 public void testTextClassifyText_url_inCaps() {
187 if (isTextClassifierDisabled()) return;
188
189 String text = "Visit HTTP://ANDROID.COM for more information";
190 String classifiedText = "HTTP://ANDROID.COM";
191 int startIndex = text.indexOf(classifiedText);
192 int endIndex = startIndex + classifiedText.length();
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100193 TextClassification.Request request = new TextClassification.Request.Builder(
194 text, startIndex, endIndex)
195 .setDefaultLocales(LOCALES)
196 .build();
Abodunrinwa Toki4d232d62017-11-23 12:22:45 +0000197
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100198 TextClassification classification = mClassifier.classifyText(request);
Jan Althaus20d346e2018-03-23 14:03:52 +0100199 assertThat(classification, isTextClassification(classifiedText, TextClassifier.TYPE_URL));
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100200 }
201
202 @Test
Lukas Zilkaf8c36bf2018-02-07 20:30:08 +0100203 public void testTextClassifyText_date() {
204 if (isTextClassifierDisabled()) return;
205
206 String text = "Let's meet on January 9, 2018.";
207 String classifiedText = "January 9, 2018";
208 int startIndex = text.indexOf(classifiedText);
209 int endIndex = startIndex + classifiedText.length();
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100210 TextClassification.Request request = new TextClassification.Request.Builder(
211 text, startIndex, endIndex)
212 .setDefaultLocales(LOCALES)
213 .build();
Lukas Zilkaf8c36bf2018-02-07 20:30:08 +0100214
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100215 TextClassification classification = mClassifier.classifyText(request);
Jan Althaus20d346e2018-03-23 14:03:52 +0100216 assertThat(classification, isTextClassification(classifiedText, TextClassifier.TYPE_DATE));
Lukas Zilkaf8c36bf2018-02-07 20:30:08 +0100217 }
218
219 @Test
220 public void testTextClassifyText_datetime() {
221 if (isTextClassifierDisabled()) return;
222
223 String text = "Let's meet 2018/01/01 10:30:20.";
224 String classifiedText = "2018/01/01 10:30:20";
225 int startIndex = text.indexOf(classifiedText);
226 int endIndex = startIndex + classifiedText.length();
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100227 TextClassification.Request request = new TextClassification.Request.Builder(
228 text, startIndex, endIndex)
229 .setDefaultLocales(LOCALES)
230 .build();
Lukas Zilkaf8c36bf2018-02-07 20:30:08 +0100231
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100232 TextClassification classification = mClassifier.classifyText(request);
Lukas Zilkaf8c36bf2018-02-07 20:30:08 +0100233 assertThat(classification,
Jan Althaus20d346e2018-03-23 14:03:52 +0100234 isTextClassification(classifiedText, TextClassifier.TYPE_DATE_TIME));
Lukas Zilkaf8c36bf2018-02-07 20:30:08 +0100235 }
236
237 @Test
Richard Ledleydb18a572017-11-30 17:33:51 +0000238 public void testGenerateLinks_phone() {
Richard Ledley68d94522017-10-05 10:52:19 +0100239 if (isTextClassifierDisabled()) return;
Richard Ledleydb18a572017-11-30 17:33:51 +0000240 String text = "The number is +12122537077. See you tonight!";
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100241 TextLinks.Request request = new TextLinks.Request.Builder(text).build();
242 assertThat(mClassifier.generateLinks(request),
Richard Ledleydb18a572017-11-30 17:33:51 +0000243 isTextLinksContaining(text, "+12122537077", TextClassifier.TYPE_PHONE));
244 }
Richard Ledley68d94522017-10-05 10:52:19 +0100245
Richard Ledleydb18a572017-11-30 17:33:51 +0000246 @Test
247 public void testGenerateLinks_exclude() {
248 if (isTextClassifierDisabled()) return;
249 String text = "The number is +12122537077. See you tonight!";
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100250 List<String> hints = Collections.EMPTY_LIST;
251 List<String> included = Collections.EMPTY_LIST;
252 List<String> excluded = Arrays.asList(TextClassifier.TYPE_PHONE);
253 TextLinks.Request request = new TextLinks.Request.Builder(text)
254 .setEntityConfig(TextClassifier.EntityConfig.create(hints, included, excluded))
255 .setDefaultLocales(LOCALES)
256 .build();
257 assertThat(mClassifier.generateLinks(request),
Richard Ledleydb18a572017-11-30 17:33:51 +0000258 not(isTextLinksContaining(text, "+12122537077", TextClassifier.TYPE_PHONE)));
259 }
Richard Ledley68d94522017-10-05 10:52:19 +0100260
Richard Ledleydb18a572017-11-30 17:33:51 +0000261 @Test
Richard Ledley1fc998b2018-02-16 15:45:06 +0000262 public void testGenerateLinks_explicit_address() {
Richard Ledleydb18a572017-11-30 17:33:51 +0000263 if (isTextClassifierDisabled()) return;
Richard Ledley1fc998b2018-02-16 15:45:06 +0000264 String text = "The address is 1600 Amphitheater Parkway, Mountain View, CA. See you!";
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100265 List<String> explicit = Arrays.asList(TextClassifier.TYPE_ADDRESS);
266 TextLinks.Request request = new TextLinks.Request.Builder(text)
267 .setEntityConfig(TextClassifier.EntityConfig.createWithExplicitEntityList(explicit))
268 .setDefaultLocales(LOCALES)
269 .build();
270 assertThat(mClassifier.generateLinks(request),
Richard Ledley1fc998b2018-02-16 15:45:06 +0000271 isTextLinksContaining(text, "1600 Amphitheater Parkway, Mountain View, CA",
272 TextClassifier.TYPE_ADDRESS));
273 }
Jan Althaus108aad32018-01-30 15:26:55 +0100274
Richard Ledley1fc998b2018-02-16 15:45:06 +0000275 @Test
276 public void testGenerateLinks_exclude_override() {
277 if (isTextClassifierDisabled()) return;
Richard Ledleydb18a572017-11-30 17:33:51 +0000278 String text = "The number is +12122537077. See you tonight!";
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100279 List<String> hints = Collections.EMPTY_LIST;
280 List<String> included = Arrays.asList(TextClassifier.TYPE_PHONE);
281 List<String> excluded = Arrays.asList(TextClassifier.TYPE_PHONE);
282 TextLinks.Request request = new TextLinks.Request.Builder(text)
283 .setEntityConfig(TextClassifier.EntityConfig.create(hints, included, excluded))
284 .setDefaultLocales(LOCALES)
285 .build();
286 assertThat(mClassifier.generateLinks(request),
Richard Ledleydb18a572017-11-30 17:33:51 +0000287 not(isTextLinksContaining(text, "+12122537077", TextClassifier.TYPE_PHONE)));
288 }
Richard Ledley68d94522017-10-05 10:52:19 +0100289
Richard Ledleydb18a572017-11-30 17:33:51 +0000290 @Test
Jan Althaus108aad32018-01-30 15:26:55 +0100291 public void testGenerateLinks_maxLength() {
292 if (isTextClassifierDisabled()) return;
293 char[] manySpaces = new char[mClassifier.getMaxGenerateLinksTextLength()];
294 Arrays.fill(manySpaces, ' ');
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100295 TextLinks.Request request = new TextLinks.Request.Builder(new String(manySpaces)).build();
296 TextLinks links = mClassifier.generateLinks(request);
Jan Althaus108aad32018-01-30 15:26:55 +0100297 assertTrue(links.getLinks().isEmpty());
298 }
299
300 @Test(expected = IllegalArgumentException.class)
301 public void testGenerateLinks_tooLong() {
302 if (isTextClassifierDisabled()) {
303 throw new IllegalArgumentException("pass if disabled");
304 }
305 char[] manySpaces = new char[mClassifier.getMaxGenerateLinksTextLength() + 1];
306 Arrays.fill(manySpaces, ' ');
Abodunrinwa Toki080c8542018-03-27 00:04:06 +0100307 TextLinks.Request request = new TextLinks.Request.Builder(new String(manySpaces)).build();
308 mClassifier.generateLinks(request);
Jan Althaus108aad32018-01-30 15:26:55 +0100309 }
310
311 @Test
Abodunrinwa Tokia69950c2018-11-29 13:51:56 +0000312 public void testApplyLinks_unsupportedCharacter() {
313 if (isTextClassifierDisabled()) return;
314 Spannable url = new SpannableString("\u202Emoc.diordna.com");
315 TextLinks.Request request = new TextLinks.Request.Builder(url).build();
316 assertEquals(
317 TextLinks.STATUS_NO_LINKS_APPLIED,
318 mClassifier.generateLinks(request).apply(url, 0, null));
319 }
320
321 @Test
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100322 public void testSetTextClassifier() {
323 TextClassifier classifier = mock(TextClassifier.class);
324 mTcm.setTextClassifier(classifier);
325 assertEquals(classifier, mTcm.getTextClassifier());
326 }
327
Abodunrinwa Tokic7073a42018-02-28 23:02:13 +0000328 @Test
329 public void testGetLocalTextClassifier() {
330 assertTrue(mTcm.getTextClassifier(TextClassifier.LOCAL) instanceof TextClassifierImpl);
331 }
Abodunrinwa Tokic7073a42018-02-28 23:02:13 +0000332 @Test
333 public void testGetSystemTextClassifier() {
334 assertTrue(
335 TextClassifierService.getServiceComponentName(mContext) == null
336 || mTcm.getTextClassifier(TextClassifier.SYSTEM) instanceof SystemTextClassifier);
337 }
338
Abodunrinwa Toki253827f2018-04-24 19:19:48 +0100339 @Test
340 public void testCannotResolveIntent() {
341 final PackageManager fakePackageMgr = mock(PackageManager.class);
342
343 ResolveInfo validInfo = mContext.getPackageManager().resolveActivity(
344 new Intent(Intent.ACTION_DIAL).setData(Uri.parse("tel:+12122537077")), 0);
345 // Make packageManager fail when it gets the following intent:
346 ArgumentMatcher<Intent> toFailIntent =
347 intent -> intent.getAction().equals(Intent.ACTION_INSERT_OR_EDIT);
348
349 when(fakePackageMgr.resolveActivity(any(Intent.class), anyInt())).thenReturn(validInfo);
350 when(fakePackageMgr.resolveActivity(argThat(toFailIntent), anyInt())).thenReturn(null);
351
352 ContextWrapper fakeContext = new ContextWrapper(mContext) {
353 @Override
354 public PackageManager getPackageManager() {
355 return fakePackageMgr;
356 }
357 };
358
359 TextClassifier fallback = TextClassifier.NO_OP;
360 TextClassifier classifier = new TextClassifierImpl(
361 fakeContext, TextClassificationConstants.loadFromString(null), fallback);
362
363 String text = "Contact me at +12122537077";
364 String classifiedText = "+12122537077";
365 int startIndex = text.indexOf(classifiedText);
366 int endIndex = startIndex + classifiedText.length();
367 TextClassification.Request request = new TextClassification.Request.Builder(
368 text, startIndex, endIndex)
369 .setDefaultLocales(LOCALES)
370 .build();
371
372 TextClassification result = classifier.classifyText(request);
373 TextClassification fallbackResult = fallback.classifyText(request);
374
375 // classifier should not totally fail in which case it returns a fallback result.
376 // It should skip the failing intent and return a result for non-failing intents.
377 assertFalse(result.getActions().isEmpty());
378 assertNotSame(result, fallbackResult);
379 }
380
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100381 private boolean isTextClassifierDisabled() {
382 return mClassifier == TextClassifier.NO_OP;
383 }
384
385 private static Matcher<TextSelection> isTextSelection(
386 final int startIndex, final int endIndex, final String type) {
387 return new BaseMatcher<TextSelection>() {
388 @Override
389 public boolean matches(Object o) {
390 if (o instanceof TextSelection) {
391 TextSelection selection = (TextSelection) o;
392 return startIndex == selection.getSelectionStartIndex()
393 && endIndex == selection.getSelectionEndIndex()
Abodunrinwa Tokib4162972017-05-05 18:07:17 +0100394 && typeMatches(selection, type);
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100395 }
396 return false;
397 }
398
Abodunrinwa Tokib4162972017-05-05 18:07:17 +0100399 private boolean typeMatches(TextSelection selection, String type) {
400 return type == null
401 || (selection.getEntityCount() > 0
402 && type.trim().equalsIgnoreCase(selection.getEntity(0)));
403 }
404
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100405 @Override
406 public void describeTo(Description description) {
407 description.appendValue(
408 String.format("%d, %d, %s", startIndex, endIndex, type));
409 }
410 };
411 }
412
Richard Ledleydb18a572017-11-30 17:33:51 +0000413 private static Matcher<TextLinks> isTextLinksContaining(
414 final String text, final String substring, final String type) {
415 return new BaseMatcher<TextLinks>() {
416
417 @Override
418 public void describeTo(Description description) {
419 description.appendText("text=").appendValue(text)
420 .appendText(", substring=").appendValue(substring)
421 .appendText(", type=").appendValue(type);
422 }
423
424 @Override
425 public boolean matches(Object o) {
426 if (o instanceof TextLinks) {
427 for (TextLinks.TextLink link : ((TextLinks) o).getLinks()) {
428 if (text.subSequence(link.getStart(), link.getEnd()).equals(substring)) {
429 return type.equals(link.getEntity(0));
430 }
431 }
432 }
433 return false;
434 }
435 };
436 }
437
Abodunrinwa Tokie0b57892017-04-28 19:59:57 +0100438 private static Matcher<TextClassification> isTextClassification(
Jan Althaus20d346e2018-03-23 14:03:52 +0100439 final String text, final String type) {
Abodunrinwa Tokie0b57892017-04-28 19:59:57 +0100440 return new BaseMatcher<TextClassification>() {
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100441 @Override
442 public boolean matches(Object o) {
Abodunrinwa Tokie0b57892017-04-28 19:59:57 +0100443 if (o instanceof TextClassification) {
444 TextClassification result = (TextClassification) o;
Jan Althaus20d346e2018-03-23 14:03:52 +0100445 return text.equals(result.getText())
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100446 && result.getEntityCount() > 0
Jan Althaus20d346e2018-03-23 14:03:52 +0100447 && type.equals(result.getEntity(0));
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100448 }
449 return false;
450 }
451
452 @Override
453 public void describeTo(Description description) {
454 description.appendText("text=").appendValue(text)
Jan Althaus20d346e2018-03-23 14:03:52 +0100455 .appendText(", type=").appendValue(type);
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100456 }
457 };
458 }
Abodunrinwa Toki65b25272017-04-13 17:25:59 +0100459}