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