Home | History | Annotate | Download | only in compat
      1 /*
      2  * Copyright (C) 2014 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.compat;
     18 
     19 import android.graphics.Typeface;
     20 import android.os.Build;
     21 import android.test.AndroidTestCase;
     22 import android.test.suitebuilder.annotation.SmallTest;
     23 import android.text.SpannableString;
     24 import android.text.Spanned;
     25 import android.text.style.StyleSpan;
     26 
     27 import java.util.Locale;
     28 
     29 @SmallTest
     30 public class LocaleSpanCompatUtilsTests extends AndroidTestCase {
     31     public void testInstantiatable() {
     32         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
     33             // LocaleSpan isn't yet available.
     34             return;
     35         }
     36         assertTrue(LocaleSpanCompatUtils.isLocaleSpanAvailable());
     37         final Object japaneseLocaleSpan = LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE);
     38         assertNotNull(japaneseLocaleSpan);
     39         assertEquals(Locale.JAPANESE,
     40                 LocaleSpanCompatUtils.getLocaleFromLocaleSpan(japaneseLocaleSpan));
     41     }
     42 
     43     private static void assertLocaleSpan(final Spanned spanned, final int index,
     44             final int expectedStart, final int expectedEnd,
     45             final Locale expectedLocale, final int expectedSpanFlags) {
     46         final Object span = spanned.getSpans(0, spanned.length(), Object.class)[index];
     47         assertEquals(expectedLocale, LocaleSpanCompatUtils.getLocaleFromLocaleSpan(span));
     48         assertEquals(expectedStart, spanned.getSpanStart(span));
     49         assertEquals(expectedEnd, spanned.getSpanEnd(span));
     50         assertEquals(expectedSpanFlags, spanned.getSpanFlags(span));
     51     }
     52 
     53     private static void assertSpanEquals(final Object expectedSpan, final Spanned spanned,
     54             final int index) {
     55         final Object[] spans = spanned.getSpans(0, spanned.length(), Object.class);
     56         assertEquals(expectedSpan, spans[index]);
     57     }
     58 
     59     private static void assertSpanCount(final int expectedCount, final Spanned spanned) {
     60         final Object[] spans = spanned.getSpans(0, spanned.length(), Object.class);
     61         assertEquals(expectedCount, spans.length);
     62     }
     63 
     64     public void testUpdateLocaleSpan() {
     65         if (!LocaleSpanCompatUtils.isLocaleSpanAvailable()) {
     66             return;
     67         }
     68 
     69         // Test if the simplest case works.
     70         {
     71             final SpannableString text = new SpannableString("0123456789");
     72             LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 5, Locale.JAPANESE);
     73             assertSpanCount(1, text);
     74             assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
     75         }
     76 
     77         // Test if only LocaleSpans are updated.
     78         {
     79             final SpannableString text = new SpannableString("0123456789");
     80             final StyleSpan styleSpan = new StyleSpan(Typeface.BOLD);
     81             text.setSpan(styleSpan, 0, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
     82             LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 5, Locale.JAPANESE);
     83             assertSpanCount(2, text);
     84             assertSpanEquals(styleSpan, text, 0);
     85             assertLocaleSpan(text, 1, 1, 5, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
     86         }
     87 
     88         // Test if two jointed spans are merged into one span.
     89         {
     90             final SpannableString text = new SpannableString("0123456789");
     91             text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 3,
     92                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
     93             LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 5, Locale.JAPANESE);
     94             assertSpanCount(1, text);
     95             assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
     96         }
     97 
     98         // Test if two overlapped spans are merged into one span.
     99         {
    100             final SpannableString text = new SpannableString("0123456789");
    101             text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 4,
    102                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    103             LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 5, Locale.JAPANESE);
    104             assertSpanCount(1, text);
    105             assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    106         }
    107 
    108         // Test if three overlapped spans are merged into one span.
    109         {
    110             final SpannableString text = new SpannableString("0123456789");
    111             text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 4,
    112                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    113             text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 5, 6,
    114                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    115             LocaleSpanCompatUtils.updateLocaleSpan(text, 2, 8, Locale.JAPANESE);
    116             assertSpanCount(1, text);
    117             assertLocaleSpan(text, 0, 1, 8, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    118         }
    119 
    120         // Test if disjoint spans remain disjoint.
    121         {
    122             final SpannableString text = new SpannableString("0123456789");
    123             text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 3,
    124                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    125             text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 5, 6,
    126                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    127             LocaleSpanCompatUtils.updateLocaleSpan(text, 8, 9, Locale.JAPANESE);
    128             assertSpanCount(3, text);
    129             assertLocaleSpan(text, 0, 1, 3, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    130             assertLocaleSpan(text, 1, 5, 6, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    131             assertLocaleSpan(text, 2, 8, 9, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    132         }
    133 
    134         // Test if existing span flags are preserved during merge.
    135         {
    136             final SpannableString text = new SpannableString("0123456789");
    137             text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 5,
    138                     Spanned.SPAN_INCLUSIVE_INCLUSIVE | Spanned.SPAN_INTERMEDIATE);
    139             LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 4, Locale.JAPANESE);
    140             assertSpanCount(1, text);
    141             assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE,
    142                     Spanned.SPAN_INCLUSIVE_INCLUSIVE | Spanned.SPAN_INTERMEDIATE);
    143         }
    144 
    145         // Test if existing span flags are preserved even when partially overlapped (leading edge).
    146         {
    147             final SpannableString text = new SpannableString("0123456789");
    148             text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 5,
    149                     Spanned.SPAN_INCLUSIVE_INCLUSIVE | Spanned.SPAN_INTERMEDIATE);
    150             LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 7, Locale.JAPANESE);
    151             assertSpanCount(1, text);
    152             assertLocaleSpan(text, 0, 1, 7, Locale.JAPANESE,
    153                     Spanned.SPAN_INCLUSIVE_EXCLUSIVE | Spanned.SPAN_INTERMEDIATE);
    154         }
    155 
    156         // Test if existing span flags are preserved even when partially overlapped (trailing edge).
    157         {
    158             final SpannableString text = new SpannableString("0123456789");
    159             text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 3, 7,
    160                     Spanned.SPAN_INCLUSIVE_INCLUSIVE | Spanned.SPAN_INTERMEDIATE);
    161             LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 5, Locale.JAPANESE);
    162             assertSpanCount(1, text);
    163             assertLocaleSpan(text, 0, 1, 7, Locale.JAPANESE,
    164                     Spanned.SPAN_EXCLUSIVE_INCLUSIVE | Spanned.SPAN_INTERMEDIATE);
    165         }
    166 
    167         // Test if existing locale span will be removed when the locale doesn't match.
    168         {
    169             final SpannableString text = new SpannableString("0123456789");
    170             text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 5,
    171                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    172             LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 7, Locale.JAPANESE);
    173             assertSpanCount(1, text);
    174             assertLocaleSpan(text, 0, 1, 7, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    175         }
    176 
    177         // Test if existing locale span will be removed when the locale doesn't match. (case 2)
    178         {
    179             final SpannableString text = new SpannableString("0123456789");
    180             text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 7,
    181                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    182             LocaleSpanCompatUtils.updateLocaleSpan(text, 5, 6, Locale.JAPANESE);
    183             assertSpanCount(3, text);
    184             assertLocaleSpan(text, 0, 3, 5, Locale.ENGLISH, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    185             assertLocaleSpan(text, 1, 6, 7, Locale.ENGLISH, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    186             assertLocaleSpan(text, 2, 5, 6, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    187         }
    188 
    189         // Test if existing locale span will be removed when the locale doesn't match. (case 3)
    190         {
    191             final SpannableString text = new SpannableString("0123456789");
    192             text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 7,
    193                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    194             LocaleSpanCompatUtils.updateLocaleSpan(text, 2, 5, Locale.JAPANESE);
    195             assertSpanCount(2, text);
    196             assertLocaleSpan(text, 0, 5, 7, Locale.ENGLISH, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    197             assertLocaleSpan(text, 1, 2, 5, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    198         }
    199 
    200         // Test if existing locale span will be removed when the locale doesn't match. (case 3)
    201         {
    202             final SpannableString text = new SpannableString("0123456789");
    203             text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 7,
    204                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    205             LocaleSpanCompatUtils.updateLocaleSpan(text, 5, 8, Locale.JAPANESE);
    206             assertSpanCount(2, text);
    207             assertLocaleSpan(text, 0, 3, 5, Locale.ENGLISH, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    208             assertLocaleSpan(text, 1, 5, 8, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    209         }
    210     }
    211 }
    212