1 /*
2  * Copyright (C) 2012 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 com.android.inputmethod.latin.utils;
18 
19 import android.test.AndroidTestCase;
20 import android.test.suitebuilder.annotation.SmallTest;
21 import android.text.SpannableString;
22 import android.text.Spanned;
23 import android.text.SpannedString;
24 
25 import com.android.inputmethod.latin.Constants;
26 
27 import java.util.Arrays;
28 import java.util.List;
29 import java.util.Locale;
30 
31 @SmallTest
32 public class StringAndJsonUtilsTests extends AndroidTestCase {
testContainsInArray()33     public void testContainsInArray() {
34         assertFalse("empty array", StringUtils.containsInArray("key", new String[0]));
35         assertFalse("not in 1 element", StringUtils.containsInArray("key", new String[] {
36                 "key1"
37         }));
38         assertFalse("not in 2 elements", StringUtils.containsInArray("key", new String[] {
39                 "key1", "key2"
40         }));
41 
42         assertTrue("in 1 element", StringUtils.containsInArray("key", new String[] {
43                 "key"
44         }));
45         assertTrue("in 2 elements", StringUtils.containsInArray("key", new String[] {
46                 "key1", "key"
47         }));
48     }
49 
testContainsInCommaSplittableText()50     public void testContainsInCommaSplittableText() {
51         assertFalse("null", StringUtils.containsInCommaSplittableText("key", null));
52         assertFalse("empty", StringUtils.containsInCommaSplittableText("key", ""));
53         assertFalse("not in 1 element",
54                 StringUtils.containsInCommaSplittableText("key", "key1"));
55         assertFalse("not in 2 elements",
56                 StringUtils.containsInCommaSplittableText("key", "key1,key2"));
57 
58         assertTrue("in 1 element", StringUtils.containsInCommaSplittableText("key", "key"));
59         assertTrue("in 2 elements", StringUtils.containsInCommaSplittableText("key", "key1,key"));
60     }
61 
testRemoveFromCommaSplittableTextIfExists()62     public void testRemoveFromCommaSplittableTextIfExists() {
63         assertEquals("null", "", StringUtils.removeFromCommaSplittableTextIfExists("key", null));
64         assertEquals("empty", "", StringUtils.removeFromCommaSplittableTextIfExists("key", ""));
65 
66         assertEquals("not in 1 element", "key1",
67                 StringUtils.removeFromCommaSplittableTextIfExists("key", "key1"));
68         assertEquals("not in 2 elements", "key1,key2",
69                 StringUtils.removeFromCommaSplittableTextIfExists("key", "key1,key2"));
70 
71         assertEquals("in 1 element", "",
72                 StringUtils.removeFromCommaSplittableTextIfExists("key", "key"));
73         assertEquals("in 2 elements at position 1", "key2",
74                 StringUtils.removeFromCommaSplittableTextIfExists("key", "key,key2"));
75         assertEquals("in 2 elements at position 2", "key1",
76                 StringUtils.removeFromCommaSplittableTextIfExists("key", "key1,key"));
77         assertEquals("in 3 elements at position 2", "key1,key3",
78                 StringUtils.removeFromCommaSplittableTextIfExists("key", "key1,key,key3"));
79 
80         assertEquals("in 3 elements at position 1,2,3", "",
81                 StringUtils.removeFromCommaSplittableTextIfExists("key", "key,key,key"));
82         assertEquals("in 5 elements at position 2,4", "key1,key3,key5",
83                 StringUtils.removeFromCommaSplittableTextIfExists(
84                         "key", "key1,key,key3,key,key5"));
85     }
86 
87 
testCapitalizeFirstCodePoint()88     public void testCapitalizeFirstCodePoint() {
89         assertEquals("SSaa",
90                 StringUtils.capitalizeFirstCodePoint("ßaa", Locale.GERMAN));
91         assertEquals("Aßa",
92                 StringUtils.capitalizeFirstCodePoint("aßa", Locale.GERMAN));
93         assertEquals("Iab",
94                 StringUtils.capitalizeFirstCodePoint("iab", Locale.ENGLISH));
95         assertEquals("CAmElCaSe",
96                 StringUtils.capitalizeFirstCodePoint("cAmElCaSe", Locale.ENGLISH));
97         assertEquals("İab",
98                 StringUtils.capitalizeFirstCodePoint("iab", new Locale("tr")));
99         assertEquals("AİB",
100                 StringUtils.capitalizeFirstCodePoint("AİB", new Locale("tr")));
101         assertEquals("A",
102                 StringUtils.capitalizeFirstCodePoint("a", Locale.ENGLISH));
103         assertEquals("A",
104                 StringUtils.capitalizeFirstCodePoint("A", Locale.ENGLISH));
105     }
106 
testCapitalizeFirstAndDowncaseRest()107     public void testCapitalizeFirstAndDowncaseRest() {
108         assertEquals("SSaa",
109                 StringUtils.capitalizeFirstAndDowncaseRest("ßaa", Locale.GERMAN));
110         assertEquals("Aßa",
111                 StringUtils.capitalizeFirstAndDowncaseRest("aßa", Locale.GERMAN));
112         assertEquals("Iab",
113                 StringUtils.capitalizeFirstAndDowncaseRest("iab", Locale.ENGLISH));
114         assertEquals("Camelcase",
115                 StringUtils.capitalizeFirstAndDowncaseRest("cAmElCaSe", Locale.ENGLISH));
116         assertEquals("İab",
117                 StringUtils.capitalizeFirstAndDowncaseRest("iab", new Locale("tr")));
118         assertEquals("Aib",
119                 StringUtils.capitalizeFirstAndDowncaseRest("AİB", new Locale("tr")));
120         assertEquals("A",
121                 StringUtils.capitalizeFirstAndDowncaseRest("a", Locale.ENGLISH));
122         assertEquals("A",
123                 StringUtils.capitalizeFirstAndDowncaseRest("A", Locale.ENGLISH));
124     }
125 
testGetCapitalizationType()126     public void testGetCapitalizationType() {
127         assertEquals(StringUtils.CAPITALIZE_NONE,
128                 StringUtils.getCapitalizationType("capitalize"));
129         assertEquals(StringUtils.CAPITALIZE_NONE,
130                 StringUtils.getCapitalizationType("cApITalize"));
131         assertEquals(StringUtils.CAPITALIZE_NONE,
132                 StringUtils.getCapitalizationType("capitalizE"));
133         assertEquals(StringUtils.CAPITALIZE_NONE,
134                 StringUtils.getCapitalizationType("__c a piu$@tali56ze"));
135         assertEquals(StringUtils.CAPITALIZE_FIRST,
136                 StringUtils.getCapitalizationType("A__c a piu$@tali56ze"));
137         assertEquals(StringUtils.CAPITALIZE_FIRST,
138                 StringUtils.getCapitalizationType("Capitalize"));
139         assertEquals(StringUtils.CAPITALIZE_FIRST,
140                 StringUtils.getCapitalizationType("     Capitalize"));
141         assertEquals(StringUtils.CAPITALIZE_ALL,
142                 StringUtils.getCapitalizationType("CAPITALIZE"));
143         assertEquals(StringUtils.CAPITALIZE_ALL,
144                 StringUtils.getCapitalizationType("  PI26LIE"));
145         assertEquals(StringUtils.CAPITALIZE_NONE,
146                 StringUtils.getCapitalizationType(""));
147     }
148 
testIsIdenticalAfterUpcaseIsIdenticalAfterDowncase()149     public void testIsIdenticalAfterUpcaseIsIdenticalAfterDowncase() {
150         assertFalse(StringUtils.isIdenticalAfterUpcase("capitalize"));
151         assertTrue(StringUtils.isIdenticalAfterDowncase("capitalize"));
152         assertFalse(StringUtils.isIdenticalAfterUpcase("cApITalize"));
153         assertFalse(StringUtils.isIdenticalAfterDowncase("cApITalize"));
154         assertFalse(StringUtils.isIdenticalAfterUpcase("capitalizE"));
155         assertFalse(StringUtils.isIdenticalAfterDowncase("capitalizE"));
156         assertFalse(StringUtils.isIdenticalAfterUpcase("__c a piu$@tali56ze"));
157         assertTrue(StringUtils.isIdenticalAfterDowncase("__c a piu$@tali56ze"));
158         assertFalse(StringUtils.isIdenticalAfterUpcase("A__c a piu$@tali56ze"));
159         assertFalse(StringUtils.isIdenticalAfterDowncase("A__c a piu$@tali56ze"));
160         assertFalse(StringUtils.isIdenticalAfterUpcase("Capitalize"));
161         assertFalse(StringUtils.isIdenticalAfterDowncase("Capitalize"));
162         assertFalse(StringUtils.isIdenticalAfterUpcase("     Capitalize"));
163         assertFalse(StringUtils.isIdenticalAfterDowncase("     Capitalize"));
164         assertTrue(StringUtils.isIdenticalAfterUpcase("CAPITALIZE"));
165         assertFalse(StringUtils.isIdenticalAfterDowncase("CAPITALIZE"));
166         assertTrue(StringUtils.isIdenticalAfterUpcase("  PI26LIE"));
167         assertFalse(StringUtils.isIdenticalAfterDowncase("  PI26LIE"));
168         assertTrue(StringUtils.isIdenticalAfterUpcase(""));
169         assertTrue(StringUtils.isIdenticalAfterDowncase(""));
170     }
171 
checkCapitalize(final String src, final String dst, final int[] sortedSeparators, final Locale locale)172     private static void checkCapitalize(final String src, final String dst,
173             final int[] sortedSeparators, final Locale locale) {
174         assertEquals(dst, StringUtils.capitalizeEachWord(src, sortedSeparators, locale));
175         assert(src.equals(dst)
176                 == StringUtils.isIdenticalAfterCapitalizeEachWord(src, sortedSeparators));
177     }
178 
179     private static final int[] SPACE = { Constants.CODE_SPACE };
180     private static final int[] SPACE_PERIOD = StringUtils.toSortedCodePointArray(" .");
181     private static final int[] SENTENCE_SEPARATORS =
182             StringUtils.toSortedCodePointArray(" \n.!?*()&");
183     private static final int[] WORD_SEPARATORS = StringUtils.toSortedCodePointArray(" \n.!?*,();&");
184 
testCapitalizeEachWord()185     public void testCapitalizeEachWord() {
186         checkCapitalize("", "", SPACE, Locale.ENGLISH);
187         checkCapitalize("test", "Test", SPACE, Locale.ENGLISH);
188         checkCapitalize("    test", "    Test", SPACE, Locale.ENGLISH);
189         checkCapitalize("Test", "Test", SPACE, Locale.ENGLISH);
190         checkCapitalize("    Test", "    Test", SPACE, Locale.ENGLISH);
191         checkCapitalize(".Test", ".test", SPACE, Locale.ENGLISH);
192         checkCapitalize(".Test", ".Test", SPACE_PERIOD, Locale.ENGLISH);
193         checkCapitalize("test and retest", "Test And Retest", SPACE_PERIOD, Locale.ENGLISH);
194         checkCapitalize("Test and retest", "Test And Retest", SPACE_PERIOD, Locale.ENGLISH);
195         checkCapitalize("Test And Retest", "Test And Retest", SPACE_PERIOD, Locale.ENGLISH);
196         checkCapitalize("Test And.Retest  ", "Test And.Retest  ", SPACE_PERIOD, Locale.ENGLISH);
197         checkCapitalize("Test And.retest  ", "Test And.Retest  ", SPACE_PERIOD, Locale.ENGLISH);
198         checkCapitalize("Test And.retest  ", "Test And.retest  ", SPACE, Locale.ENGLISH);
199         checkCapitalize("Test And.Retest  ", "Test And.retest  ", SPACE, Locale.ENGLISH);
200         checkCapitalize("test and ietest", "Test And İetest", SPACE_PERIOD, new Locale("tr"));
201         checkCapitalize("test and ietest", "Test And Ietest", SPACE_PERIOD, Locale.ENGLISH);
202         checkCapitalize("Test&Retest", "Test&Retest", SENTENCE_SEPARATORS, Locale.ENGLISH);
203         checkCapitalize("Test&retest", "Test&Retest", SENTENCE_SEPARATORS, Locale.ENGLISH);
204         checkCapitalize("test&Retest", "Test&Retest", SENTENCE_SEPARATORS, Locale.ENGLISH);
205         checkCapitalize("rest\nrecreation! And in the end...",
206                 "Rest\nRecreation! And In The End...", WORD_SEPARATORS, Locale.ENGLISH);
207         checkCapitalize("lorem ipsum dolor sit amet", "Lorem Ipsum Dolor Sit Amet",
208                 WORD_SEPARATORS, Locale.ENGLISH);
209         checkCapitalize("Lorem!Ipsum (Dolor) Sit * Amet", "Lorem!Ipsum (Dolor) Sit * Amet",
210                 WORD_SEPARATORS, Locale.ENGLISH);
211         checkCapitalize("Lorem!Ipsum (dolor) Sit * Amet", "Lorem!Ipsum (Dolor) Sit * Amet",
212                 WORD_SEPARATORS, Locale.ENGLISH);
213     }
214 
testLooksLikeURL()215     public void testLooksLikeURL() {
216         assertTrue(StringUtils.lastPartLooksLikeURL("http://www.google."));
217         assertFalse(StringUtils.lastPartLooksLikeURL("word wo"));
218         assertTrue(StringUtils.lastPartLooksLikeURL("/etc/foo"));
219         assertFalse(StringUtils.lastPartLooksLikeURL("left/right"));
220         assertTrue(StringUtils.lastPartLooksLikeURL("www.goo"));
221         assertTrue(StringUtils.lastPartLooksLikeURL("www."));
222         assertFalse(StringUtils.lastPartLooksLikeURL("U.S.A"));
223         assertFalse(StringUtils.lastPartLooksLikeURL("U.S.A."));
224         assertTrue(StringUtils.lastPartLooksLikeURL("rtsp://foo."));
225         assertTrue(StringUtils.lastPartLooksLikeURL("://"));
226         assertFalse(StringUtils.lastPartLooksLikeURL("abc/"));
227         assertTrue(StringUtils.lastPartLooksLikeURL("abc.def/ghi"));
228         assertFalse(StringUtils.lastPartLooksLikeURL("abc.def"));
229         // TODO: ideally this would not look like a URL, but to keep down the complexity of the
230         // code for now True is acceptable.
231         assertTrue(StringUtils.lastPartLooksLikeURL("abc./def"));
232         // TODO: ideally this would not look like a URL, but to keep down the complexity of the
233         // code for now True is acceptable.
234         assertTrue(StringUtils.lastPartLooksLikeURL(".abc/def"));
235     }
236 
testHexStringUtils()237     public void testHexStringUtils() {
238         final byte[] bytes = new byte[] { (byte)0x01, (byte)0x11, (byte)0x22, (byte)0x33,
239                 (byte)0x55, (byte)0x88, (byte)0xEE };
240         final String bytesStr = StringUtils.byteArrayToHexString(bytes);
241         final byte[] bytes2 = StringUtils.hexStringToByteArray(bytesStr);
242         for (int i = 0; i < bytes.length; ++i) {
243             assertTrue(bytes[i] == bytes2[i]);
244         }
245         final String bytesStr2 = StringUtils.byteArrayToHexString(bytes2);
246         assertTrue(bytesStr.equals(bytesStr2));
247     }
248 
testJsonUtils()249     public void testJsonUtils() {
250         final Object[] objs = new Object[] { 1, "aaa", "bbb", 3 };
251         final List<Object> objArray = Arrays.asList(objs);
252         final String str = JsonUtils.listToJsonStr(objArray);
253         final List<Object> newObjArray = JsonUtils.jsonStrToList(str);
254         for (int i = 0; i < objs.length; ++i) {
255             assertEquals(objs[i], newObjArray.get(i));
256         }
257     }
258 
testToCodePointArray()259     public void testToCodePointArray() {
260         final String STR_WITH_SUPPLEMENTARY_CHAR = "abcde\uD861\uDED7fgh\u0000\u2002\u2003\u3000xx";
261         final int[] EXPECTED_RESULT = new int[] { 'a', 'b', 'c', 'd', 'e', 0x286D7, 'f', 'g', 'h',
262                 0, 0x2002, 0x2003, 0x3000, 'x', 'x'};
263         final int[] codePointArray = StringUtils.toCodePointArray(STR_WITH_SUPPLEMENTARY_CHAR, 0,
264                 STR_WITH_SUPPLEMENTARY_CHAR.length());
265         assertEquals("toCodePointArray, size matches", codePointArray.length,
266                 EXPECTED_RESULT.length);
267         for (int i = 0; i < EXPECTED_RESULT.length; ++i) {
268             assertEquals("toCodePointArray position " + i, codePointArray[i], EXPECTED_RESULT[i]);
269         }
270     }
271 
testCopyCodePointsAndReturnCodePointCount()272     public void testCopyCodePointsAndReturnCodePointCount() {
273         final String STR_WITH_SUPPLEMENTARY_CHAR = "AbcDE\uD861\uDED7fGh\u0000\u2002\u3000あx";
274         final int[] EXPECTED_RESULT = new int[] { 'A', 'b', 'c', 'D', 'E', 0x286D7,
275                 'f', 'G', 'h', 0, 0x2002, 0x3000, 'あ', 'x'};
276         final int[] EXPECTED_RESULT_DOWNCASE = new int[] { 'a', 'b', 'c', 'd', 'e', 0x286D7,
277                 'f', 'g', 'h', 0, 0x2002, 0x3000, 'あ', 'x'};
278 
279         int[] codePointArray = new int[50];
280         int codePointCount = StringUtils.copyCodePointsAndReturnCodePointCount(codePointArray,
281                 STR_WITH_SUPPLEMENTARY_CHAR, 0,
282                 STR_WITH_SUPPLEMENTARY_CHAR.length(), false /* downCase */);
283         assertEquals("copyCodePointsAndReturnCodePointCount, size matches", codePointCount,
284                 EXPECTED_RESULT.length);
285         for (int i = 0; i < codePointCount; ++i) {
286             assertEquals("copyCodePointsAndReturnCodePointCount position " + i, codePointArray[i],
287                     EXPECTED_RESULT[i]);
288         }
289 
290         codePointCount = StringUtils.copyCodePointsAndReturnCodePointCount(codePointArray,
291                 STR_WITH_SUPPLEMENTARY_CHAR, 0,
292                 STR_WITH_SUPPLEMENTARY_CHAR.length(), true /* downCase */);
293         assertEquals("copyCodePointsAndReturnCodePointCount downcase, size matches", codePointCount,
294                 EXPECTED_RESULT_DOWNCASE.length);
295         for (int i = 0; i < codePointCount; ++i) {
296             assertEquals("copyCodePointsAndReturnCodePointCount position " + i, codePointArray[i],
297                     EXPECTED_RESULT_DOWNCASE[i]);
298         }
299 
300         final int JAVA_CHAR_COUNT = 8;
301         final int CODEPOINT_COUNT = 7;
302         codePointCount = StringUtils.copyCodePointsAndReturnCodePointCount(codePointArray,
303                 STR_WITH_SUPPLEMENTARY_CHAR, 0, JAVA_CHAR_COUNT, false /* downCase */);
304         assertEquals("copyCodePointsAndReturnCodePointCount, size matches", codePointCount,
305                 CODEPOINT_COUNT);
306         for (int i = 0; i < codePointCount; ++i) {
307             assertEquals("copyCodePointsAndReturnCodePointCount position " + i, codePointArray[i],
308                     EXPECTED_RESULT[i]);
309         }
310 
311         boolean exceptionHappened = false;
312         codePointArray = new int[5];
313         try {
314             codePointCount = StringUtils.copyCodePointsAndReturnCodePointCount(codePointArray,
315                     STR_WITH_SUPPLEMENTARY_CHAR, 0, JAVA_CHAR_COUNT, false /* downCase */);
316         } catch (ArrayIndexOutOfBoundsException e) {
317             exceptionHappened = true;
318         }
319         assertTrue("copyCodePointsAndReturnCodePointCount throws when array is too small",
320                 exceptionHappened);
321     }
322 
testGetTrailingSingleQuotesCount()323     public void testGetTrailingSingleQuotesCount() {
324         assertEquals(0, StringUtils.getTrailingSingleQuotesCount(""));
325         assertEquals(1, StringUtils.getTrailingSingleQuotesCount("'"));
326         assertEquals(5, StringUtils.getTrailingSingleQuotesCount("'''''"));
327         assertEquals(0, StringUtils.getTrailingSingleQuotesCount("a"));
328         assertEquals(0, StringUtils.getTrailingSingleQuotesCount("'this"));
329         assertEquals(1, StringUtils.getTrailingSingleQuotesCount("'word'"));
330         assertEquals(0, StringUtils.getTrailingSingleQuotesCount("I'm"));
331     }
332 
assertSpanCount(final int expectedCount, final CharSequence cs)333     private static void assertSpanCount(final int expectedCount, final CharSequence cs) {
334         final int actualCount;
335         if (cs instanceof Spanned) {
336             final Spanned spanned = (Spanned) cs;
337             actualCount = spanned.getSpans(0, spanned.length(), Object.class).length;
338         } else {
339             actualCount = 0;
340         }
341         assertEquals(expectedCount, actualCount);
342     }
343 
assertSpan(final CharSequence cs, final Object expectedSpan, final int expectedStart, final int expectedEnd, final int expectedFlags)344     private static void assertSpan(final CharSequence cs, final Object expectedSpan,
345             final int expectedStart, final int expectedEnd, final int expectedFlags) {
346         assertTrue(cs instanceof Spanned);
347         final Spanned spanned = (Spanned) cs;
348         final Object[] actualSpans = spanned.getSpans(0, spanned.length(), Object.class);
349         for (Object actualSpan : actualSpans) {
350             if (actualSpan == expectedSpan) {
351                 final int actualStart = spanned.getSpanStart(actualSpan);
352                 final int actualEnd = spanned.getSpanEnd(actualSpan);
353                 final int actualFlags = spanned.getSpanFlags(actualSpan);
354                 assertEquals(expectedStart, actualStart);
355                 assertEquals(expectedEnd, actualEnd);
356                 assertEquals(expectedFlags, actualFlags);
357                 return;
358             }
359         }
360         assertTrue(false);
361     }
362 
testSplitCharSequenceWithSpan()363     public void testSplitCharSequenceWithSpan() {
364         // text:  " a bcd efg hij  "
365         // span1:  ^^^^^^^
366         // span2:  ^^^^^
367         // span3:              ^
368         final SpannableString spannableString = new SpannableString(" a bcd efg hij  ");
369         final Object span1 = new Object();
370         final Object span2 = new Object();
371         final Object span3 = new Object();
372         final int SPAN1_FLAGS = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
373         final int SPAN2_FLAGS = Spanned.SPAN_EXCLUSIVE_INCLUSIVE;
374         final int SPAN3_FLAGS = Spanned.SPAN_INCLUSIVE_INCLUSIVE;
375         spannableString.setSpan(span1, 0, 7, SPAN1_FLAGS);
376         spannableString.setSpan(span2, 0, 5, SPAN2_FLAGS);
377         spannableString.setSpan(span3, 12, 13, SPAN3_FLAGS);
378         final CharSequence[] charSequencesFromSpanned = StringUtils.split(
379                 spannableString, " ", true /* preserveTrailingEmptySegmengs */);
380         final CharSequence[] charSequencesFromString = StringUtils.split(
381                 spannableString.toString(), " ", true /* preserveTrailingEmptySegmengs */);
382 
383 
384         assertEquals(7, charSequencesFromString.length);
385         assertEquals(7, charSequencesFromSpanned.length);
386 
387         // text:  ""
388         // span1: ^
389         // span2: ^
390         // span3:
391         assertEquals("", charSequencesFromString[0].toString());
392         assertSpanCount(0, charSequencesFromString[0]);
393         assertEquals("", charSequencesFromSpanned[0].toString());
394         assertSpanCount(2, charSequencesFromSpanned[0]);
395         assertSpan(charSequencesFromSpanned[0], span1, 0, 0, SPAN1_FLAGS);
396         assertSpan(charSequencesFromSpanned[0], span2, 0, 0, SPAN2_FLAGS);
397 
398         // text:  "a"
399         // span1:  ^
400         // span2:  ^
401         // span3:
402         assertEquals("a", charSequencesFromString[1].toString());
403         assertSpanCount(0, charSequencesFromString[1]);
404         assertEquals("a", charSequencesFromSpanned[1].toString());
405         assertSpanCount(2, charSequencesFromSpanned[1]);
406         assertSpan(charSequencesFromSpanned[1], span1, 0, 1, SPAN1_FLAGS);
407         assertSpan(charSequencesFromSpanned[1], span2, 0, 1, SPAN2_FLAGS);
408 
409         // text:  "bcd"
410         // span1:  ^^^
411         // span2:  ^^
412         // span3:
413         assertEquals("bcd", charSequencesFromString[2].toString());
414         assertSpanCount(0, charSequencesFromString[2]);
415         assertEquals("bcd", charSequencesFromSpanned[2].toString());
416         assertSpanCount(2, charSequencesFromSpanned[2]);
417         assertSpan(charSequencesFromSpanned[2], span1, 0, 3, SPAN1_FLAGS);
418         assertSpan(charSequencesFromSpanned[2], span2, 0, 2, SPAN2_FLAGS);
419 
420         // text:  "efg"
421         // span1:
422         // span2:
423         // span3:
424         assertEquals("efg", charSequencesFromString[3].toString());
425         assertSpanCount(0, charSequencesFromString[3]);
426         assertEquals("efg", charSequencesFromSpanned[3].toString());
427         assertSpanCount(0, charSequencesFromSpanned[3]);
428 
429         // text:  "hij"
430         // span1:
431         // span2:
432         // span3:   ^
433         assertEquals("hij", charSequencesFromString[4].toString());
434         assertSpanCount(0, charSequencesFromString[4]);
435         assertEquals("hij", charSequencesFromSpanned[4].toString());
436         assertSpanCount(1, charSequencesFromSpanned[4]);
437         assertSpan(charSequencesFromSpanned[4], span3, 1, 2, SPAN3_FLAGS);
438 
439         // text:  ""
440         // span1:
441         // span2:
442         // span3:
443         assertEquals("", charSequencesFromString[5].toString());
444         assertSpanCount(0, charSequencesFromString[5]);
445         assertEquals("", charSequencesFromSpanned[5].toString());
446         assertSpanCount(0, charSequencesFromSpanned[5]);
447 
448         // text:  ""
449         // span1:
450         // span2:
451         // span3:
452         assertEquals("", charSequencesFromString[6].toString());
453         assertSpanCount(0, charSequencesFromString[6]);
454         assertEquals("", charSequencesFromSpanned[6].toString());
455         assertSpanCount(0, charSequencesFromSpanned[6]);
456     }
457 
testSplitCharSequencePreserveTrailingEmptySegmengs()458     public void testSplitCharSequencePreserveTrailingEmptySegmengs() {
459         assertEquals(1, StringUtils.split("", " ",
460                 false /* preserveTrailingEmptySegmengs */).length);
461         assertEquals(1, StringUtils.split(new SpannedString(""), " ",
462                 false /* preserveTrailingEmptySegmengs */).length);
463 
464         assertEquals(1, StringUtils.split("", " ",
465                 true /* preserveTrailingEmptySegmengs */).length);
466         assertEquals(1, StringUtils.split(new SpannedString(""), " ",
467                 true /* preserveTrailingEmptySegmengs */).length);
468 
469         assertEquals(0, StringUtils.split(" ", " ",
470                 false /* preserveTrailingEmptySegmengs */).length);
471         assertEquals(0, StringUtils.split(new SpannedString(" "), " ",
472                 false /* preserveTrailingEmptySegmengs */).length);
473 
474         assertEquals(2, StringUtils.split(" ", " ",
475                 true /* preserveTrailingEmptySegmengs */).length);
476         assertEquals(2, StringUtils.split(new SpannedString(" "), " ",
477                 true /* preserveTrailingEmptySegmengs */).length);
478 
479         assertEquals(3, StringUtils.split("a b c  ", " ",
480                 false /* preserveTrailingEmptySegmengs */).length);
481         assertEquals(3, StringUtils.split(new SpannedString("a b c  "), " ",
482                 false /* preserveTrailingEmptySegmengs */).length);
483 
484         assertEquals(5, StringUtils.split("a b c  ", " ",
485                 true /* preserveTrailingEmptySegmengs */).length);
486         assertEquals(5, StringUtils.split(new SpannedString("a b c  "), " ",
487                 true /* preserveTrailingEmptySegmengs */).length);
488 
489         assertEquals(6, StringUtils.split("a     b ", " ",
490                 false /* preserveTrailingEmptySegmengs */).length);
491         assertEquals(6, StringUtils.split(new SpannedString("a     b "), " ",
492                 false /* preserveTrailingEmptySegmengs */).length);
493 
494         assertEquals(7, StringUtils.split("a     b ", " ",
495                 true /* preserveTrailingEmptySegmengs */).length);
496         assertEquals(7, StringUtils.split(new SpannedString("a     b "), " ",
497                 true /* preserveTrailingEmptySegmengs */).length);
498     }
499 }
500