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