MoreKeySpecSplitTests.java revision 3bbd50c36b1e9b9e3b26ab510853021515886498
1/*
2 * Copyright (C) 2010 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.keyboard.internal;
18
19import android.app.Instrumentation;
20import android.content.Context;
21import android.content.res.Resources;
22import android.test.InstrumentationTestCase;
23import android.test.suitebuilder.annotation.MediumTest;
24
25import com.android.inputmethod.latin.utils.CollectionUtils;
26import com.android.inputmethod.latin.utils.RunInLocale;
27
28import java.lang.reflect.Field;
29import java.util.ArrayList;
30import java.util.Arrays;
31import java.util.Locale;
32
33@MediumTest
34public class MoreKeySpecSplitTests extends InstrumentationTestCase {
35    private static final Locale TEST_LOCALE = Locale.ENGLISH;
36    final KeyboardTextsSet mTextsSet = new KeyboardTextsSet();
37
38    @Override
39    protected void setUp() throws Exception {
40        super.setUp();
41
42        final Instrumentation instrumentation = getInstrumentation();
43        final Context targetContext = instrumentation.getTargetContext();
44        mTextsSet.setLocale(TEST_LOCALE);
45        new RunInLocale<Void>() {
46            @Override
47            protected Void job(final Resources res) {
48                mTextsSet.loadStringResources(targetContext);
49                return null;
50            }
51        }.runInLocale(targetContext.getResources(), TEST_LOCALE);
52        final String[] testResourceNames = getAllResourceIdNames(
53                com.android.inputmethod.latin.tests.R.string.class);
54        mTextsSet.loadStringResourcesInternal(instrumentation.getContext(), testResourceNames,
55                // This dummy raw resource is needed to be able to load string resources from a test
56                // APK successfully.
57                com.android.inputmethod.latin.tests.R.raw.dummy_resource_for_testing);
58    }
59
60    private static String[] getAllResourceIdNames(final Class<?> resourceIdClass) {
61        final ArrayList<String> names = CollectionUtils.newArrayList();
62        for (final Field field : resourceIdClass.getFields()) {
63            if (field.getType() == Integer.TYPE) {
64                names.add(field.getName());
65            }
66        }
67        return names.toArray(new String[names.size()]);
68    }
69
70    private static <T> void assertArrayEquals(final String message, final T[] expected,
71            final T[] actual) {
72        if (expected == actual) {
73            return;
74        }
75        if (expected == null || actual == null) {
76            assertEquals(message, Arrays.toString(expected), Arrays.toString(actual));
77            return;
78        }
79        if (expected.length != actual.length) {
80            assertEquals(message + " [length]", Arrays.toString(expected), Arrays.toString(actual));
81            return;
82        }
83        for (int i = 0; i < expected.length; i++) {
84            final T e = expected[i];
85            final T a = actual[i];
86            if (e == a) {
87                continue;
88            }
89            assertEquals(message + " [" + i + "]", e, a);
90        }
91    }
92
93    private void assertTextArray(final String message, final String value,
94            final String ... expectedArray) {
95        final String resolvedActual = mTextsSet.resolveTextReference(value);
96        final String[] actual = MoreKeySpec.splitKeySpecs(resolvedActual);
97        final String[] expected = (expectedArray.length == 0) ? null : expectedArray;
98        assertArrayEquals(message, expected, actual);
99    }
100
101    private void assertError(final String message, final String value, final String ... expected) {
102        try {
103            assertTextArray(message, value, expected);
104            fail(message);
105        } catch (Exception pcpe) {
106            // success.
107        }
108    }
109
110    // \U001d11e: MUSICAL SYMBOL G CLEF
111    private static final String PAIR1 = "\ud834\udd1e";
112    // \U001d122: MUSICAL SYMBOL F CLEF
113    private static final String PAIR2 = "\ud834\udd22";
114    // \U002f8a6: CJK COMPATIBILITY IDEOGRAPH-2F8A6; variant character of \u6148.
115    private static final String PAIR3 = "\ud87e\udca6";
116    private static final String SURROGATE1 = PAIR1 + PAIR2;
117    private static final String SURROGATE2 = PAIR1 + PAIR2 + PAIR3;
118
119    public void testResolveNullText() {
120        assertNull("resolve null", mTextsSet.resolveTextReference(null));
121    }
122
123    public void testResolveEmptyText() {
124        assertNull("resolve empty text", mTextsSet.resolveTextReference("!text/empty_string"));
125    }
126
127    public void testSplitZero() {
128        assertTextArray("Empty string", "");
129        assertTextArray("Empty entry", ",");
130        assertTextArray("Empty entry at beginning", ",a", "a");
131        assertTextArray("Empty entry at end", "a,", "a");
132        assertTextArray("Empty entry at middle", "a,,b", "a", "b");
133        assertTextArray("Empty entries with escape", ",a,b\\,c,,d,", "a", "b\\,c", "d");
134    }
135
136    public void testSplitSingle() {
137        assertTextArray("Single char", "a", "a");
138        assertTextArray("Surrogate pair", PAIR1, PAIR1);
139        assertTextArray("Single escape", "\\", "\\");
140        assertTextArray("Space", " ", " ");
141        assertTextArray("Single label", "abc", "abc");
142        assertTextArray("Single surrogate pairs label", SURROGATE2, SURROGATE2);
143        assertTextArray("Spaces", "   ", "   ");
144        assertTextArray("Spaces in label", "a b c", "a b c");
145        assertTextArray("Spaces at beginning of label", " abc", " abc");
146        assertTextArray("Spaces at end of label", "abc ", "abc ");
147        assertTextArray("Label surrounded by spaces", " abc ", " abc ");
148        assertTextArray("Surrogate pair surrounded by space",
149                " " + PAIR1 + " ",
150                " " + PAIR1 + " ");
151        assertTextArray("Surrogate pair within characters",
152                "ab" + PAIR2 + "cd",
153                "ab" + PAIR2 + "cd");
154        assertTextArray("Surrogate pairs within characters",
155                "ab" + SURROGATE1 + "cd",
156                "ab" + SURROGATE1 + "cd");
157
158        assertTextArray("Incomplete resource reference 1", "text", "text");
159        assertTextArray("Incomplete resource reference 2", "!text", "!text");
160        assertTextArray("Incomplete RESOURCE REFERENCE 2", "!TEXT", "!TEXT");
161        assertTextArray("Incomplete resource reference 3", "text/", "text/");
162        assertTextArray("Incomplete resource reference 4", "!" + SURROGATE2, "!" + SURROGATE2);
163    }
164
165    public void testSplitSingleEscaped() {
166        assertTextArray("Escaped char", "\\a", "\\a");
167        assertTextArray("Escaped surrogate pair", "\\" + PAIR1, "\\" + PAIR1);
168        assertTextArray("Escaped comma", "\\,", "\\,");
169        assertTextArray("Escaped comma escape", "a\\,\\", "a\\,\\");
170        assertTextArray("Escaped escape", "\\\\", "\\\\");
171        assertTextArray("Escaped label", "a\\bc", "a\\bc");
172        assertTextArray("Escaped surrogate", "a\\" + PAIR1 + "c", "a\\" + PAIR1 + "c");
173        assertTextArray("Escaped label at beginning", "\\abc", "\\abc");
174        assertTextArray("Escaped surrogate at beginning", "\\" + SURROGATE2, "\\" + SURROGATE2);
175        assertTextArray("Escaped label at end", "abc\\", "abc\\");
176        assertTextArray("Escaped surrogate at end", SURROGATE2 + "\\", SURROGATE2 + "\\");
177        assertTextArray("Escaped label with comma", "a\\,c", "a\\,c");
178        assertTextArray("Escaped surrogate with comma",
179                PAIR1 + "\\," + PAIR2, PAIR1 + "\\," + PAIR2);
180        assertTextArray("Escaped label with comma at beginning", "\\,bc", "\\,bc");
181        assertTextArray("Escaped surrogate with comma at beginning",
182                "\\," + SURROGATE1, "\\," + SURROGATE1);
183        assertTextArray("Escaped label with comma at end", "ab\\,", "ab\\,");
184        assertTextArray("Escaped surrogate with comma at end",
185                SURROGATE2 + "\\,", SURROGATE2 + "\\,");
186        assertTextArray("Escaped label with successive", "\\,\\\\bc", "\\,\\\\bc");
187        assertTextArray("Escaped surrogate with successive",
188                "\\,\\\\" + SURROGATE1, "\\,\\\\" + SURROGATE1);
189        assertTextArray("Escaped label with escape", "a\\\\c", "a\\\\c");
190        assertTextArray("Escaped surrogate with escape",
191                PAIR1 + "\\\\" + PAIR2, PAIR1 + "\\\\" + PAIR2);
192
193        assertTextArray("Escaped !text", "\\!text", "\\!text");
194        assertTextArray("Escaped !text/", "\\!text/", "\\!text/");
195        assertTextArray("Escaped !TEXT/", "\\!TEXT/", "\\!TEXT/");
196        assertTextArray("Escaped !text/name", "\\!text/empty_string", "\\!text/empty_string");
197        assertTextArray("Escaped !TEXT/NAME", "\\!TEXT/EMPTY_STRING", "\\!TEXT/EMPTY_STRING");
198    }
199
200    public void testSplitMulti() {
201        assertTextArray("Multiple chars", "a,b,c", "a", "b", "c");
202        assertTextArray("Multiple chars", "a,b,\\c", "a", "b", "\\c");
203        assertTextArray("Multiple chars and escape at beginning and end",
204                "\\a,b,\\c\\", "\\a", "b", "\\c\\");
205        assertTextArray("Multiple surrogates", PAIR1 + "," + PAIR2 + "," + PAIR3,
206                PAIR1, PAIR2, PAIR3);
207        assertTextArray("Multiple chars surrounded by spaces", " a , b , c ", " a ", " b ", " c ");
208        assertTextArray("Multiple labels", "abc,def,ghi", "abc", "def", "ghi");
209        assertTextArray("Multiple surrogated", SURROGATE1 + "," + SURROGATE2,
210                SURROGATE1, SURROGATE2);
211        assertTextArray("Multiple labels surrounded by spaces", " abc , def , ghi ",
212                " abc ", " def ", " ghi ");
213    }
214
215    public void testSplitMultiEscaped() {
216        assertTextArray("Multiple chars with comma", "a,\\,,c", "a", "\\,", "c");
217        assertTextArray("Multiple chars with comma surrounded by spaces", " a , \\, , c ",
218                " a ", " \\, ", " c ");
219        assertTextArray("Multiple labels with escape",
220                "\\abc,d\\ef,gh\\i", "\\abc", "d\\ef", "gh\\i");
221        assertTextArray("Multiple labels with escape surrounded by spaces",
222                " \\abc , d\\ef , gh\\i ", " \\abc ", " d\\ef ", " gh\\i ");
223        assertTextArray("Multiple labels with comma and escape",
224                "ab\\\\,d\\\\\\,,g\\,i", "ab\\\\", "d\\\\\\,", "g\\,i");
225        assertTextArray("Multiple labels with comma and escape surrounded by spaces",
226                " ab\\\\ , d\\\\\\, , g\\,i ", " ab\\\\ ", " d\\\\\\, ", " g\\,i ");
227
228        assertTextArray("Multiple escaped !text", "\\!,\\!text/empty_string",
229                "\\!", "\\!text/empty_string");
230        assertTextArray("Multiple escaped !TEXT", "\\!,\\!TEXT/EMPTY_STRING",
231                "\\!", "\\!TEXT/EMPTY_STRING");
232    }
233
234    public void testSplitResourceError() {
235        assertError("Incomplete resource name", "!text/", "!text/");
236        assertError("Non existing resource", "!text/non_existing");
237    }
238
239    public void testSplitResourceZero() {
240        assertTextArray("Empty string",
241                "!text/empty_string");
242    }
243
244    public void testSplitResourceSingle() {
245        assertTextArray("Single char",
246                "!text/single_char", "a");
247        assertTextArray("Space",
248                "!text/space", " ");
249        assertTextArray("Single label",
250                "!text/single_label", "abc");
251        assertTextArray("Spaces",
252                "!text/spaces", "   ");
253        assertTextArray("Spaces in label",
254                "!text/spaces_in_label", "a b c");
255        assertTextArray("Spaces at beginning of label",
256                "!text/spaces_at_beginning_of_label", " abc");
257        assertTextArray("Spaces at end of label",
258                "!text/spaces_at_end_of_label", "abc ");
259        assertTextArray("label surrounded by spaces",
260                "!text/label_surrounded_by_spaces", " abc ");
261
262        assertTextArray("Escape and single char",
263                "\\\\!text/single_char", "\\\\a");
264    }
265
266    public void testSplitResourceSingleEscaped() {
267        assertTextArray("Escaped char",
268                "!text/escaped_char", "\\a");
269        assertTextArray("Escaped comma",
270                "!text/escaped_comma", "\\,");
271        assertTextArray("Escaped comma escape",
272                "!text/escaped_comma_escape", "a\\,\\");
273        assertTextArray("Escaped escape",
274                "!text/escaped_escape", "\\\\");
275        assertTextArray("Escaped label",
276                "!text/escaped_label", "a\\bc");
277        assertTextArray("Escaped label at beginning",
278                "!text/escaped_label_at_beginning", "\\abc");
279        assertTextArray("Escaped label at end",
280                "!text/escaped_label_at_end", "abc\\");
281        assertTextArray("Escaped label with comma",
282                "!text/escaped_label_with_comma", "a\\,c");
283        assertTextArray("Escaped label with comma at beginning",
284                "!text/escaped_label_with_comma_at_beginning", "\\,bc");
285        assertTextArray("Escaped label with comma at end",
286                "!text/escaped_label_with_comma_at_end", "ab\\,");
287        assertTextArray("Escaped label with successive",
288                "!text/escaped_label_with_successive", "\\,\\\\bc");
289        assertTextArray("Escaped label with escape",
290                "!text/escaped_label_with_escape", "a\\\\c");
291    }
292
293    public void testSplitResourceMulti() {
294        assertTextArray("Multiple chars",
295                "!text/multiple_chars", "a", "b", "c");
296        assertTextArray("Multiple chars surrounded by spaces",
297                "!text/multiple_chars_surrounded_by_spaces",
298                " a ", " b ", " c ");
299        assertTextArray("Multiple labels",
300                "!text/multiple_labels", "abc", "def", "ghi");
301        assertTextArray("Multiple labels surrounded by spaces",
302                "!text/multiple_labels_surrounded_by_spaces", " abc ", " def ", " ghi ");
303    }
304
305    public void testSplitResourcetMultiEscaped() {
306        assertTextArray("Multiple chars with comma",
307                "!text/multiple_chars_with_comma",
308                "a", "\\,", "c");
309        assertTextArray("Multiple chars with comma surrounded by spaces",
310                "!text/multiple_chars_with_comma_surrounded_by_spaces",
311                " a ", " \\, ", " c ");
312        assertTextArray("Multiple labels with escape",
313                "!text/multiple_labels_with_escape",
314                "\\abc", "d\\ef", "gh\\i");
315        assertTextArray("Multiple labels with escape surrounded by spaces",
316                "!text/multiple_labels_with_escape_surrounded_by_spaces",
317                " \\abc ", " d\\ef ", " gh\\i ");
318        assertTextArray("Multiple labels with comma and escape",
319                "!text/multiple_labels_with_comma_and_escape",
320                "ab\\\\", "d\\\\\\,", "g\\,i");
321        assertTextArray("Multiple labels with comma and escape surrounded by spaces",
322                "!text/multiple_labels_with_comma_and_escape_surrounded_by_spaces",
323                " ab\\\\ ", " d\\\\\\, ", " g\\,i ");
324    }
325
326    public void testSplitMultipleResources() {
327        assertTextArray("Literals and resources",
328                "1,!text/multiple_chars,z", "1", "a", "b", "c", "z");
329        assertTextArray("Literals and resources and escape at end",
330                "\\1,!text/multiple_chars,z\\", "\\1", "a", "b", "c", "z\\");
331        assertTextArray("Multiple single resource chars and labels",
332                "!text/single_char,!text/single_label,!text/escaped_comma",
333                "a", "abc", "\\,");
334        assertTextArray("Multiple single resource chars and labels 2",
335                "!text/single_char,!text/single_label,!text/escaped_comma_escape",
336                "a", "abc", "a\\,\\");
337        assertTextArray("Multiple multiple resource chars and labels",
338                "!text/multiple_chars,!text/multiple_labels,!text/multiple_chars_with_comma",
339                "a", "b", "c", "abc", "def", "ghi", "a", "\\,", "c");
340        assertTextArray("Concatenated resources",
341                "!text/multiple_chars!text/multiple_labels!text/multiple_chars_with_comma",
342                "a", "b", "cabc", "def", "ghia", "\\,", "c");
343        assertTextArray("Concatenated resource and literal",
344                "abc!text/multiple_labels",
345                "abcabc", "def", "ghi");
346    }
347
348    public void testSplitIndirectReference() {
349        assertTextArray("Indirect",
350                "!text/indirect_string", "a", "b", "c");
351        assertTextArray("Indirect with literal",
352                "1,!text/indirect_string_with_literal,2", "1", "x", "a", "b", "c", "y", "2");
353        assertTextArray("Indirect2",
354                "!text/indirect2_string", "a", "b", "c");
355    }
356
357    public void testSplitInfiniteIndirectReference() {
358        assertError("Infinite indirection",
359                "1,!text/infinite_indirection,2", "1", "infinite", "<infinite>", "loop", "2");
360    }
361
362    public void testLabelReferece() {
363        assertTextArray("Label time am", "!text/label_time_am", "AM");
364
365        assertTextArray("More keys for am pm", "!text/more_keys_for_am_pm",
366                "!fixedColumnOrder!2", "!hasLabels!", "AM", "PM");
367
368        assertTextArray("Settings as more key", "!text/settings_as_more_key",
369                "!icon/settings_key|!code/key_settings");
370
371        assertTextArray("Indirect naviagte actions as more key",
372                "!text/indirect_navigate_actions_as_more_key",
373                "!fixedColumnOrder!2",
374                "!hasLabels!", "Prev|!code/key_action_previous",
375                "!hasLabels!", "Next|!code/key_action_next");
376    }
377
378    public void testUselessUpperCaseSpecifier() {
379        assertTextArray("EMPTY STRING",
380                "!TEXT/EMPTY_STRING", "!TEXT/EMPTY_STRING");
381
382        assertTextArray("SINGLE CHAR",
383                "!TEXT/SINGLE_CHAR", "!TEXT/SINGLE_CHAR");
384        assertTextArray("Escape and SINGLE CHAR",
385                "\\\\!TEXT/SINGLE_CHAR", "\\\\!TEXT/SINGLE_CHAR");
386
387        assertTextArray("MULTIPLE CHARS",
388                "!TEXT/MULTIPLE_CHARS", "!TEXT/MULTIPLE_CHARS");
389
390        assertTextArray("Literals and RESOURCES",
391                "1,!TEXT/MULTIPLE_CHARS,z", "1", "!TEXT/MULTIPLE_CHARS", "z");
392        assertTextArray("Multiple single RESOURCE chars and LABELS 2",
393                "!TEXT/SINGLE_CHAR,!TEXT/SINGLE_LABEL,!TEXT/ESCAPED_COMMA_ESCAPE",
394                "!TEXT/SINGLE_CHAR", "!TEXT/SINGLE_LABEL", "!TEXT/ESCAPED_COMMA_ESCAPE");
395
396        assertTextArray("INDIRECT",
397                "!TEXT/INDIRECT_STRING", "!TEXT/INDIRECT_STRING");
398        assertTextArray("INDIRECT with literal",
399                "1,!TEXT/INDIRECT_STRING_WITH_LITERAL,2",
400                "1", "!TEXT/INDIRECT_STRING_WITH_LITERAL", "2");
401        assertTextArray("INDIRECT2",
402                "!TEXT/INDIRECT2_STRING", "!TEXT/INDIRECT2_STRING");
403
404        assertTextArray("Upper indirect",
405                "!text/upper_indirect_string", "!TEXT/MULTIPLE_CHARS");
406        assertTextArray("Upper indirect with literal",
407                "1,!text/upper_indirect_string_with_literal,2",
408                "1", "x", "!TEXT/MULTIPLE_CHARS", "y", "2");
409        assertTextArray("Upper indirect2",
410                "!text/upper_indirect2_string", "!TEXT/UPPER_INDIRECT_STRING");
411
412        assertTextArray("UPPER INDIRECT",
413                "!TEXT/upper_INDIRECT_STRING", "!TEXT/upper_INDIRECT_STRING");
414        assertTextArray("Upper INDIRECT with literal",
415                "1,!TEXT/upper_INDIRECT_STRING_WITH_LITERAL,2",
416                "1", "!TEXT/upper_INDIRECT_STRING_WITH_LITERAL", "2");
417        assertTextArray("Upper INDIRECT2",
418                "!TEXT/upper_INDIRECT2_STRING", "!TEXT/upper_INDIRECT2_STRING");
419
420        assertTextArray("INFINITE INDIRECTION",
421                "1,!TEXT/INFINITE_INDIRECTION,2", "1", "!TEXT/INFINITE_INDIRECTION", "2");
422
423        assertTextArray("Upper infinite indirection",
424                "1,!text/upper_infinite_indirection,2",
425                "1", "infinite", "!TEXT/INFINITE_INDIRECTION", "loop", "2");
426        assertTextArray("Upper INFINITE INDIRECTION",
427                "1,!TEXT/UPPER_INFINITE_INDIRECTION,2",
428                "1", "!TEXT/UPPER_INFINITE_INDIRECTION", "2");
429
430        assertTextArray("LABEL TIME AM", "!TEXT/LABEL_TIME_AM", "!TEXT/LABEL_TIME_AM");
431        assertTextArray("MORE KEYS FOR AM OM", "!TEXT/MORE_KEYS_FOR_AM_PM",
432                "!TEXT/MORE_KEYS_FOR_AM_PM");
433        assertTextArray("SETTINGS AS MORE KEY", "!TEXT/SETTINGS_AS_MORE_KEY",
434                "!TEXT/SETTINGS_AS_MORE_KEY");
435        assertTextArray("INDIRECT NAVIGATE ACTIONS AS MORE KEY",
436                "!TEXT/INDIRECT_NAVIGATE_ACTIONS_AS_MORE_KEY",
437                "!TEXT/INDIRECT_NAVIGATE_ACTIONS_AS_MORE_KEY");
438     }
439}
440