LocaleSpanCompatUtilsTests.java revision ece4548eb51cfeedee7d0323d451374629080019
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
17package com.android.inputmethod.compat;
18
19import android.graphics.Typeface;
20import android.os.Build;
21import android.test.AndroidTestCase;
22import android.test.suitebuilder.annotation.SmallTest;
23import android.text.Spannable;
24import android.text.SpannableString;
25import android.text.Spanned;
26import android.text.style.StyleSpan;
27
28import java.util.Locale;
29
30@SmallTest
31public class LocaleSpanCompatUtilsTests extends AndroidTestCase {
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
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
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
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
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