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