1 /* 2 * Copyright (C) 2013 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.style.SuggestionSpan; 22 import android.text.style.URLSpan; 23 import android.text.SpannableString; 24 import android.text.SpannableStringBuilder; 25 import android.text.Spanned; 26 import android.text.SpannedString; 27 28 @SmallTest 29 public class SpannableStringUtilsTests extends AndroidTestCase { 30 public void testConcatWithSuggestionSpansOnly() { 31 SpannableStringBuilder s = new SpannableStringBuilder("test string\ntest string\n" 32 + "test string\ntest string\ntest string\ntest string\ntest string\ntest string\n" 33 + "test string\ntest string\n"); 34 final int N = 10; 35 for (int i = 0; i < N; ++i) { 36 // Put a PARAGRAPH-flagged span that should not be found in the result. 37 s.setSpan(new SuggestionSpan(getContext(), 38 new String[] {"" + i}, Spanned.SPAN_PARAGRAPH), 39 i * 12, i * 12 + 12, Spanned.SPAN_PARAGRAPH); 40 // Put a normal suggestion span that should be found in the result. 41 s.setSpan(new SuggestionSpan(getContext(), new String[] {"" + i}, 0), i, i * 2, 0); 42 // Put a URL span than should not be found in the result. 43 s.setSpan(new URLSpan("http://a"), i, i * 2, 0); 44 } 45 46 final CharSequence a = s.subSequence(0, 15); 47 final CharSequence b = s.subSequence(15, s.length()); 48 final Spanned result = 49 (Spanned)SpannableStringUtils.concatWithNonParagraphSuggestionSpansOnly(a, b); 50 51 Object[] spans = result.getSpans(0, result.length(), SuggestionSpan.class); 52 for (int i = 0; i < spans.length; i++) { 53 final int flags = result.getSpanFlags(spans[i]); 54 assertEquals("Should not find a span with PARAGRAPH flag", 55 flags & Spanned.SPAN_PARAGRAPH, 0); 56 assertTrue("Should be a SuggestionSpan", spans[i] instanceof SuggestionSpan); 57 } 58 } 59 60 private static void assertSpanCount(final int expectedCount, final CharSequence cs) { 61 final int actualCount; 62 if (cs instanceof Spanned) { 63 final Spanned spanned = (Spanned) cs; 64 actualCount = spanned.getSpans(0, spanned.length(), Object.class).length; 65 } else { 66 actualCount = 0; 67 } 68 assertEquals(expectedCount, actualCount); 69 } 70 71 private static void assertSpan(final CharSequence cs, final Object expectedSpan, 72 final int expectedStart, final int expectedEnd, final int expectedFlags) { 73 assertTrue(cs instanceof Spanned); 74 final Spanned spanned = (Spanned) cs; 75 final Object[] actualSpans = spanned.getSpans(0, spanned.length(), Object.class); 76 for (Object actualSpan : actualSpans) { 77 if (actualSpan == expectedSpan) { 78 final int actualStart = spanned.getSpanStart(actualSpan); 79 final int actualEnd = spanned.getSpanEnd(actualSpan); 80 final int actualFlags = spanned.getSpanFlags(actualSpan); 81 assertEquals(expectedStart, actualStart); 82 assertEquals(expectedEnd, actualEnd); 83 assertEquals(expectedFlags, actualFlags); 84 return; 85 } 86 } 87 assertTrue(false); 88 } 89 90 public void testSplitCharSequenceWithSpan() { 91 // text: " a bcd efg hij " 92 // span1: ^^^^^^^ 93 // span2: ^^^^^ 94 // span3: ^ 95 final SpannableString spannableString = new SpannableString(" a bcd efg hij "); 96 final Object span1 = new Object(); 97 final Object span2 = new Object(); 98 final Object span3 = new Object(); 99 final int SPAN1_FLAGS = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE; 100 final int SPAN2_FLAGS = Spanned.SPAN_EXCLUSIVE_INCLUSIVE; 101 final int SPAN3_FLAGS = Spanned.SPAN_INCLUSIVE_INCLUSIVE; 102 spannableString.setSpan(span1, 0, 7, SPAN1_FLAGS); 103 spannableString.setSpan(span2, 0, 5, SPAN2_FLAGS); 104 spannableString.setSpan(span3, 12, 13, SPAN3_FLAGS); 105 final CharSequence[] charSequencesFromSpanned = SpannableStringUtils.split( 106 spannableString, " ", true /* preserveTrailingEmptySegmengs */); 107 final CharSequence[] charSequencesFromString = SpannableStringUtils.split( 108 spannableString.toString(), " ", true /* preserveTrailingEmptySegmengs */); 109 110 111 assertEquals(7, charSequencesFromString.length); 112 assertEquals(7, charSequencesFromSpanned.length); 113 114 // text: "" 115 // span1: ^ 116 // span2: ^ 117 // span3: 118 assertEquals("", charSequencesFromString[0].toString()); 119 assertSpanCount(0, charSequencesFromString[0]); 120 assertEquals("", charSequencesFromSpanned[0].toString()); 121 assertSpanCount(2, charSequencesFromSpanned[0]); 122 assertSpan(charSequencesFromSpanned[0], span1, 0, 0, SPAN1_FLAGS); 123 assertSpan(charSequencesFromSpanned[0], span2, 0, 0, SPAN2_FLAGS); 124 125 // text: "a" 126 // span1: ^ 127 // span2: ^ 128 // span3: 129 assertEquals("a", charSequencesFromString[1].toString()); 130 assertSpanCount(0, charSequencesFromString[1]); 131 assertEquals("a", charSequencesFromSpanned[1].toString()); 132 assertSpanCount(2, charSequencesFromSpanned[1]); 133 assertSpan(charSequencesFromSpanned[1], span1, 0, 1, SPAN1_FLAGS); 134 assertSpan(charSequencesFromSpanned[1], span2, 0, 1, SPAN2_FLAGS); 135 136 // text: "bcd" 137 // span1: ^^^ 138 // span2: ^^ 139 // span3: 140 assertEquals("bcd", charSequencesFromString[2].toString()); 141 assertSpanCount(0, charSequencesFromString[2]); 142 assertEquals("bcd", charSequencesFromSpanned[2].toString()); 143 assertSpanCount(2, charSequencesFromSpanned[2]); 144 assertSpan(charSequencesFromSpanned[2], span1, 0, 3, SPAN1_FLAGS); 145 assertSpan(charSequencesFromSpanned[2], span2, 0, 2, SPAN2_FLAGS); 146 147 // text: "efg" 148 // span1: 149 // span2: 150 // span3: 151 assertEquals("efg", charSequencesFromString[3].toString()); 152 assertSpanCount(0, charSequencesFromString[3]); 153 assertEquals("efg", charSequencesFromSpanned[3].toString()); 154 assertSpanCount(0, charSequencesFromSpanned[3]); 155 156 // text: "hij" 157 // span1: 158 // span2: 159 // span3: ^ 160 assertEquals("hij", charSequencesFromString[4].toString()); 161 assertSpanCount(0, charSequencesFromString[4]); 162 assertEquals("hij", charSequencesFromSpanned[4].toString()); 163 assertSpanCount(1, charSequencesFromSpanned[4]); 164 assertSpan(charSequencesFromSpanned[4], span3, 1, 2, SPAN3_FLAGS); 165 166 // text: "" 167 // span1: 168 // span2: 169 // span3: 170 assertEquals("", charSequencesFromString[5].toString()); 171 assertSpanCount(0, charSequencesFromString[5]); 172 assertEquals("", charSequencesFromSpanned[5].toString()); 173 assertSpanCount(0, charSequencesFromSpanned[5]); 174 175 // text: "" 176 // span1: 177 // span2: 178 // span3: 179 assertEquals("", charSequencesFromString[6].toString()); 180 assertSpanCount(0, charSequencesFromString[6]); 181 assertEquals("", charSequencesFromSpanned[6].toString()); 182 assertSpanCount(0, charSequencesFromSpanned[6]); 183 } 184 185 public void testSplitCharSequencePreserveTrailingEmptySegmengs() { 186 assertEquals(1, SpannableStringUtils.split("", " ", 187 false /* preserveTrailingEmptySegmengs */).length); 188 assertEquals(1, SpannableStringUtils.split(new SpannedString(""), " ", 189 false /* preserveTrailingEmptySegmengs */).length); 190 191 assertEquals(1, SpannableStringUtils.split("", " ", 192 true /* preserveTrailingEmptySegmengs */).length); 193 assertEquals(1, SpannableStringUtils.split(new SpannedString(""), " ", 194 true /* preserveTrailingEmptySegmengs */).length); 195 196 assertEquals(0, SpannableStringUtils.split(" ", " ", 197 false /* preserveTrailingEmptySegmengs */).length); 198 assertEquals(0, SpannableStringUtils.split(new SpannedString(" "), " ", 199 false /* preserveTrailingEmptySegmengs */).length); 200 201 assertEquals(2, SpannableStringUtils.split(" ", " ", 202 true /* preserveTrailingEmptySegmengs */).length); 203 assertEquals(2, SpannableStringUtils.split(new SpannedString(" "), " ", 204 true /* preserveTrailingEmptySegmengs */).length); 205 206 assertEquals(3, SpannableStringUtils.split("a b c ", " ", 207 false /* preserveTrailingEmptySegmengs */).length); 208 assertEquals(3, SpannableStringUtils.split(new SpannedString("a b c "), " ", 209 false /* preserveTrailingEmptySegmengs */).length); 210 211 assertEquals(5, SpannableStringUtils.split("a b c ", " ", 212 true /* preserveTrailingEmptySegmengs */).length); 213 assertEquals(5, SpannableStringUtils.split(new SpannedString("a b c "), " ", 214 true /* preserveTrailingEmptySegmengs */).length); 215 216 assertEquals(6, SpannableStringUtils.split("a b ", " ", 217 false /* preserveTrailingEmptySegmengs */).length); 218 assertEquals(6, SpannableStringUtils.split(new SpannedString("a b "), " ", 219 false /* preserveTrailingEmptySegmengs */).length); 220 221 assertEquals(7, SpannableStringUtils.split("a b ", " ", 222 true /* preserveTrailingEmptySegmengs */).length); 223 assertEquals(7, SpannableStringUtils.split(new SpannedString("a b "), " ", 224 true /* preserveTrailingEmptySegmengs */).length); 225 } 226 } 227