1/*
2 * Copyright (C) 2011 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.latin.utils;
18
19import android.content.Context;
20import android.content.res.Resources;
21import android.test.AndroidTestCase;
22import android.test.suitebuilder.annotation.SmallTest;
23import android.view.inputmethod.InputMethodInfo;
24import android.view.inputmethod.InputMethodSubtype;
25
26import com.android.inputmethod.latin.RichInputMethodManager;
27
28import java.util.ArrayList;
29import java.util.Locale;
30
31@SmallTest
32public class SubtypeLocaleUtilsTests extends AndroidTestCase {
33    // All input method subtypes of LatinIME.
34    private final ArrayList<InputMethodSubtype> mSubtypesList = new ArrayList<>();
35
36    private RichInputMethodManager mRichImm;
37    private Resources mRes;
38
39    InputMethodSubtype EN_US;
40    InputMethodSubtype EN_GB;
41    InputMethodSubtype ES_US;
42    InputMethodSubtype FR;
43    InputMethodSubtype FR_CA;
44    InputMethodSubtype FR_CH;
45    InputMethodSubtype DE;
46    InputMethodSubtype DE_CH;
47    InputMethodSubtype ZZ;
48    InputMethodSubtype DE_QWERTY;
49    InputMethodSubtype FR_QWERTZ;
50    InputMethodSubtype EN_US_AZERTY;
51    InputMethodSubtype EN_UK_DVORAK;
52    InputMethodSubtype ES_US_COLEMAK;
53    InputMethodSubtype ZZ_AZERTY;
54    InputMethodSubtype ZZ_PC;
55
56    @Override
57    protected void setUp() throws Exception {
58        super.setUp();
59        final Context context = getContext();
60        RichInputMethodManager.init(context);
61        mRichImm = RichInputMethodManager.getInstance();
62        mRes = context.getResources();
63        SubtypeLocaleUtils.init(context);
64
65        final InputMethodInfo imi = mRichImm.getInputMethodInfoOfThisIme();
66        final int subtypeCount = imi.getSubtypeCount();
67        for (int index = 0; index < subtypeCount; index++) {
68            final InputMethodSubtype subtype = imi.getSubtypeAt(index);
69            mSubtypesList.add(subtype);
70        }
71
72        EN_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
73                Locale.US.toString(), "qwerty");
74        EN_GB = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
75                Locale.UK.toString(), "qwerty");
76        ES_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
77                "es_US", "spanish");
78        FR = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
79                Locale.FRENCH.toString(), "azerty");
80        FR_CA = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
81                Locale.CANADA_FRENCH.toString(), "qwerty");
82        FR_CH = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
83                "fr_CH", "swiss");
84        DE = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
85                Locale.GERMAN.toString(), "qwertz");
86        DE_CH = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
87                "de_CH", "swiss");
88        ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
89                SubtypeLocaleUtils.NO_LANGUAGE, "qwerty");
90        DE_QWERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
91                Locale.GERMAN.toString(), "qwerty");
92        FR_QWERTZ = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
93                Locale.FRENCH.toString(), "qwertz");
94        EN_US_AZERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
95                Locale.US.toString(), "azerty");
96        EN_UK_DVORAK = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
97                Locale.UK.toString(), "dvorak");
98        ES_US_COLEMAK = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
99                "es_US", "colemak");
100        ZZ_AZERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
101                SubtypeLocaleUtils.NO_LANGUAGE, "azerty");
102        ZZ_PC = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
103                SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty");
104    }
105
106    public void testAllFullDisplayName() {
107        for (final InputMethodSubtype subtype : mSubtypesList) {
108            final String subtypeName = SubtypeLocaleUtils
109                    .getSubtypeDisplayNameInSystemLocale(subtype);
110            if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
111                final String layoutName = SubtypeLocaleUtils
112                        .getKeyboardLayoutSetDisplayName(subtype);
113                assertTrue(subtypeName, subtypeName.contains(layoutName));
114            } else {
115                final String languageName = SubtypeLocaleUtils
116                        .getSubtypeLocaleDisplayNameInSystemLocale(subtype.getLocale());
117                assertTrue(subtypeName, subtypeName.contains(languageName));
118            }
119        }
120    }
121
122    public void testKeyboardLayoutSetName() {
123        assertEquals("en_US", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(EN_US));
124        assertEquals("en_GB", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(EN_GB));
125        assertEquals("es_US", "spanish", SubtypeLocaleUtils.getKeyboardLayoutSetName(ES_US));
126        assertEquals("fr", "azerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR));
127        assertEquals("fr_CA", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR_CA));
128        assertEquals("fr_CH", "swiss", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR_CH));
129        assertEquals("de", "qwertz", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE));
130        assertEquals("de_CH", "swiss", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE_CH));
131        assertEquals("zz", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(ZZ));
132
133        assertEquals("de qwerty", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE_QWERTY));
134        assertEquals("fr qwertz", "qwertz", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR_QWERTZ));
135        assertEquals("en_US azerty", "azerty",
136                SubtypeLocaleUtils.getKeyboardLayoutSetName(EN_US_AZERTY));
137        assertEquals("en_UK dvorak", "dvorak",
138                SubtypeLocaleUtils.getKeyboardLayoutSetName(EN_UK_DVORAK));
139        assertEquals("es_US colemak", "colemak",
140                SubtypeLocaleUtils.getKeyboardLayoutSetName(ES_US_COLEMAK));
141        assertEquals("zz azerty", "azerty",
142                SubtypeLocaleUtils.getKeyboardLayoutSetName(ZZ_AZERTY));
143    }
144
145    // InputMethodSubtype's display name in system locale (en_US).
146    //        isAdditionalSubtype (T=true, F=false)
147    // locale layout  |  display name
148    // ------ ------- - ----------------------
149    //  en_US qwerty  F  English (US)            exception
150    //  en_GB qwerty  F  English (UK)            exception
151    //  es_US spanish F  Spanish (US)            exception
152    //  fr    azerty  F  French
153    //  fr_CA qwerty  F  French (Canada)
154    //  fr_CH swiss   F  French (Switzerland)
155    //  de    qwertz  F  German
156    //  de_CH swiss   F  German (Switzerland)
157    //  zz    qwerty  F  Alphabet (QWERTY)
158    //  fr    qwertz  T  French (QWERTZ)
159    //  de    qwerty  T  German (QWERTY)
160    //  en_US azerty  T  English (US) (AZERTY)   exception
161    //  en_UK dvorak  T  English (UK) (Dvorak)   exception
162    //  es_US colemak T  Spanish (US) (Colemak)  exception
163    //  zz    pc      T  Alphabet (PC)
164
165    public void testPredefinedSubtypesInEnglishSystemLocale() {
166        final RunInLocale<Void> tests = new RunInLocale<Void>() {
167            @Override
168            protected Void job(final Resources res) {
169                assertEquals("en_US", "English (US)",
170                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_US));
171                assertEquals("en_GB", "English (UK)",
172                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_GB));
173                assertEquals("es_US", "Spanish (US)",
174                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ES_US));
175                assertEquals("fr", "French",
176                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR));
177                assertEquals("fr_CA", "French (Canada)",
178                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CA));
179                assertEquals("fr_CH", "French (Switzerland)",
180                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CH));
181                assertEquals("de", "German",
182                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE));
183                assertEquals("de_CH", "German (Switzerland)",
184                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_CH));
185                assertEquals("zz", "Alphabet (QWERTY)",
186                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ));
187                return null;
188            }
189        };
190        tests.runInLocale(mRes, Locale.ENGLISH);
191    }
192
193    public void testAdditionalSubtypesInEnglishSystemLocale() {
194        final RunInLocale<Void> tests = new RunInLocale<Void>() {
195            @Override
196            protected Void job(final Resources res) {
197                assertEquals("fr qwertz", "French (QWERTZ)",
198                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_QWERTZ));
199                assertEquals("de qwerty", "German (QWERTY)",
200                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_QWERTY));
201                assertEquals("en_US azerty", "English (US) (AZERTY)",
202                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_US_AZERTY));
203                assertEquals("en_UK dvorak","English (UK) (Dvorak)",
204                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_UK_DVORAK));
205                assertEquals("es_US colemak", "Spanish (US) (Colemak)",
206                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ES_US_COLEMAK));
207                assertEquals("zz azerty", "Alphabet (AZERTY)",
208                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ_AZERTY));
209                assertEquals("zz pc", "Alphabet (PC)",
210                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ_PC));
211                return null;
212            }
213        };
214        tests.runInLocale(mRes, Locale.ENGLISH);
215    }
216
217    // InputMethodSubtype's display name in system locale (fr).
218    //        isAdditionalSubtype (T=true, F=false)
219    // locale layout  |  display name
220    // ------ ------- - ----------------------
221    //  en_US qwerty  F  Anglais (États-Unis)            exception
222    //  en_GB qwerty  F  Anglais (Royaume-Uni)            exception
223    //  es_US spanish F  Espagnol (États-Unis)            exception
224    //  fr    azerty  F  Français
225    //  fr_CA qwerty  F  Français (Canada)
226    //  fr_CH swiss   F  Français (Suisse)
227    //  de    qwertz  F  Allemand
228    //  de_CH swiss   F  Allemand (Suisse)
229    //  zz    qwerty  F  Alphabet latin (QWERTY)
230    //  fr    qwertz  T  Français (QWERTZ)
231    //  de    qwerty  T  Allemand (QWERTY)
232    //  en_US azerty  T  Anglais (États-Unis) (AZERTY)   exception
233    //  en_UK dvorak  T  Anglais (Royaume-Uni) (Dvorak)   exception
234    //  es_US colemak T  Espagnol (États-Unis) (Colemak)  exception
235    //  zz    pc      T  Alphabet latin (PC)
236
237    public void testPredefinedSubtypesInFrenchSystemLocale() {
238        final RunInLocale<Void> tests = new RunInLocale<Void>() {
239            @Override
240            protected Void job(final Resources res) {
241                assertEquals("en_US", "Anglais (États-Unis)",
242                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_US));
243                assertEquals("en_GB", "Anglais (Royaume-Uni)",
244                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_GB));
245                assertEquals("es_US", "Espagnol (États-Unis)",
246                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ES_US));
247                assertEquals("fr", "Français",
248                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR));
249                assertEquals("fr_CA", "Français (Canada)",
250                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CA));
251                assertEquals("fr_CH", "Français (Suisse)",
252                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CH));
253                assertEquals("de", "Allemand",
254                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE));
255                assertEquals("de_CH", "Allemand (Suisse)",
256                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_CH));
257                assertEquals("zz", "Alphabet latin (QWERTY)",
258                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ));
259                return null;
260            }
261        };
262        tests.runInLocale(mRes, Locale.FRENCH);
263    }
264
265    public void testAdditionalSubtypesInFrenchSystemLocale() {
266        final RunInLocale<Void> tests = new RunInLocale<Void>() {
267            @Override
268            protected Void job(final Resources res) {
269                assertEquals("fr qwertz", "Français (QWERTZ)",
270                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_QWERTZ));
271                assertEquals("de qwerty", "Allemand (QWERTY)",
272                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_QWERTY));
273                assertEquals("en_US azerty", "Anglais (États-Unis) (AZERTY)",
274                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_US_AZERTY));
275                assertEquals("en_UK dvorak", "Anglais (Royaume-Uni) (Dvorak)",
276                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_UK_DVORAK));
277                assertEquals("es_US colemak", "Espagnol (États-Unis) (Colemak)",
278                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ES_US_COLEMAK));
279                assertEquals("zz azerty", "Alphabet latin (AZERTY)",
280                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ_AZERTY));
281                assertEquals("zz pc", "Alphabet latin (PC)",
282                        SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ_PC));
283                return null;
284            }
285        };
286        tests.runInLocale(mRes, Locale.FRENCH);
287    }
288
289    public void testIsRtlLanguage() {
290        // Known Right-to-Left language subtypes.
291        final InputMethodSubtype ARABIC = mRichImm
292                .findSubtypeByLocaleAndKeyboardLayoutSet("ar", "arabic");
293        assertNotNull("Arabic", ARABIC);
294        final InputMethodSubtype FARSI = mRichImm
295                .findSubtypeByLocaleAndKeyboardLayoutSet("fa", "farsi");
296        assertNotNull("Farsi", FARSI);
297        final InputMethodSubtype HEBREW = mRichImm
298                .findSubtypeByLocaleAndKeyboardLayoutSet("iw", "hebrew");
299        assertNotNull("Hebrew", HEBREW);
300
301        for (final InputMethodSubtype subtype : mSubtypesList) {
302            final String subtypeName = SubtypeLocaleUtils
303                    .getSubtypeDisplayNameInSystemLocale(subtype);
304            if (subtype.equals(ARABIC) || subtype.equals(FARSI) || subtype.equals(HEBREW)) {
305                assertTrue(subtypeName, SubtypeLocaleUtils.isRtlLanguage(subtype));
306            } else {
307                assertFalse(subtypeName, SubtypeLocaleUtils.isRtlLanguage(subtype));
308            }
309        }
310    }
311}
312