Home | History | Annotate | Download | only in utils
      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