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 17 package com.android.inputmethod.keyboard.internal; 18 19 import android.content.Context; 20 import android.content.res.Resources; 21 import android.test.AndroidTestCase; 22 import android.test.suitebuilder.annotation.SmallTest; 23 24 import com.android.inputmethod.latin.R; 25 26 import java.util.Arrays; 27 import java.util.Locale; 28 29 @SmallTest 30 public class MoreKeySpecSplitTests extends AndroidTestCase { 31 private static final Locale TEST_LOCALE = Locale.ENGLISH; 32 private final KeyboardTextsSet mTextsSet = new KeyboardTextsSet(); 33 34 @Override 35 protected void setUp() throws Exception { 36 super.setUp(); 37 38 final Context targetContext = getContext(); 39 final Resources targetRes = targetContext.getResources(); 40 final String targetPackageName = targetRes.getResourcePackageName( 41 R.string.english_ime_name); 42 mTextsSet.setLocale(TEST_LOCALE, targetRes, targetPackageName); 43 } 44 45 static <T> void assertArrayEquals(final String message, final T[] expected, final T[] actual) { 46 if (expected == actual) { 47 return; 48 } 49 if (expected == null || actual == null) { 50 assertEquals(message, Arrays.toString(expected), Arrays.toString(actual)); 51 return; 52 } 53 if (expected.length != actual.length) { 54 assertEquals(message + " [length]", Arrays.toString(expected), Arrays.toString(actual)); 55 return; 56 } 57 for (int i = 0; i < expected.length; i++) { 58 final T e = expected[i]; 59 final T a = actual[i]; 60 if (e == a) { 61 continue; 62 } 63 assertEquals(message + " [" + i + "]", e, a); 64 } 65 } 66 67 private void assertTextArray(final String message, final String value, 68 final String ... expectedArray) { 69 final String resolvedActual = mTextsSet.resolveTextReference(value); 70 final String[] actual = MoreKeySpec.splitKeySpecs(resolvedActual); 71 final String[] expected = (expectedArray.length == 0) ? null : expectedArray; 72 assertArrayEquals(message, expected, actual); 73 } 74 75 private void assertError(final String message, final String value, final String ... expected) { 76 try { 77 assertTextArray(message, value, expected); 78 fail(message); 79 } catch (Exception pcpe) { 80 // success. 81 } 82 } 83 84 // \U001d11e: MUSICAL SYMBOL G CLEF 85 private static final String PAIR1 = "\ud834\udd1e"; 86 // \U001d122: MUSICAL SYMBOL F CLEF 87 private static final String PAIR2 = "\ud834\udd22"; 88 // \U002f8a6: CJK COMPATIBILITY IDEOGRAPH-2F8A6; variant character of \u6148. 89 private static final String PAIR3 = "\ud87e\udca6"; 90 private static final String SURROGATE1 = PAIR1 + PAIR2; 91 private static final String SURROGATE2 = PAIR1 + PAIR2 + PAIR3; 92 93 public void testSplitZero() { 94 assertTextArray("Empty string", ""); 95 assertTextArray("Empty entry", ","); 96 assertTextArray("Empty entry at beginning", ",a", "a"); 97 assertTextArray("Empty entry at end", "a,", "a"); 98 assertTextArray("Empty entry at middle", "a,,b", "a", "b"); 99 assertTextArray("Empty entries with escape", ",a,b\\,c,,d,", "a", "b\\,c", "d"); 100 } 101 102 public void testSplitSingle() { 103 assertTextArray("Single char", "a", "a"); 104 assertTextArray("Surrogate pair", PAIR1, PAIR1); 105 assertTextArray("Single escape", "\\", "\\"); 106 assertTextArray("Space", " ", " "); 107 assertTextArray("Single label", "abc", "abc"); 108 assertTextArray("Single surrogate pairs label", SURROGATE2, SURROGATE2); 109 assertTextArray("Spaces", " ", " "); 110 assertTextArray("Spaces in label", "a b c", "a b c"); 111 assertTextArray("Spaces at beginning of label", " abc", " abc"); 112 assertTextArray("Spaces at end of label", "abc ", "abc "); 113 assertTextArray("Label surrounded by spaces", " abc ", " abc "); 114 assertTextArray("Surrogate pair surrounded by space", 115 " " + PAIR1 + " ", 116 " " + PAIR1 + " "); 117 assertTextArray("Surrogate pair within characters", 118 "ab" + PAIR2 + "cd", 119 "ab" + PAIR2 + "cd"); 120 assertTextArray("Surrogate pairs within characters", 121 "ab" + SURROGATE1 + "cd", 122 "ab" + SURROGATE1 + "cd"); 123 124 assertTextArray("Incomplete resource reference 1", "text", "text"); 125 assertTextArray("Incomplete resource reference 2", "!text", "!text"); 126 assertTextArray("Incomplete RESOURCE REFERENCE 2", "!TEXT", "!TEXT"); 127 assertTextArray("Incomplete resource reference 3", "text/", "text/"); 128 assertTextArray("Incomplete resource reference 4", "!" + SURROGATE2, "!" + SURROGATE2); 129 } 130 131 public void testSplitSingleEscaped() { 132 assertTextArray("Escaped char", "\\a", "\\a"); 133 assertTextArray("Escaped surrogate pair", "\\" + PAIR1, "\\" + PAIR1); 134 assertTextArray("Escaped comma", "\\,", "\\,"); 135 assertTextArray("Escaped comma escape", "a\\,\\", "a\\,\\"); 136 assertTextArray("Escaped escape", "\\\\", "\\\\"); 137 assertTextArray("Escaped label", "a\\bc", "a\\bc"); 138 assertTextArray("Escaped surrogate", "a\\" + PAIR1 + "c", "a\\" + PAIR1 + "c"); 139 assertTextArray("Escaped label at beginning", "\\abc", "\\abc"); 140 assertTextArray("Escaped surrogate at beginning", "\\" + SURROGATE2, "\\" + SURROGATE2); 141 assertTextArray("Escaped label at end", "abc\\", "abc\\"); 142 assertTextArray("Escaped surrogate at end", SURROGATE2 + "\\", SURROGATE2 + "\\"); 143 assertTextArray("Escaped label with comma", "a\\,c", "a\\,c"); 144 assertTextArray("Escaped surrogate with comma", 145 PAIR1 + "\\," + PAIR2, PAIR1 + "\\," + PAIR2); 146 assertTextArray("Escaped label with comma at beginning", "\\,bc", "\\,bc"); 147 assertTextArray("Escaped surrogate with comma at beginning", 148 "\\," + SURROGATE1, "\\," + SURROGATE1); 149 assertTextArray("Escaped label with comma at end", "ab\\,", "ab\\,"); 150 assertTextArray("Escaped surrogate with comma at end", 151 SURROGATE2 + "\\,", SURROGATE2 + "\\,"); 152 assertTextArray("Escaped label with successive", "\\,\\\\bc", "\\,\\\\bc"); 153 assertTextArray("Escaped surrogate with successive", 154 "\\,\\\\" + SURROGATE1, "\\,\\\\" + SURROGATE1); 155 assertTextArray("Escaped label with escape", "a\\\\c", "a\\\\c"); 156 assertTextArray("Escaped surrogate with escape", 157 PAIR1 + "\\\\" + PAIR2, PAIR1 + "\\\\" + PAIR2); 158 159 assertTextArray("Escaped !text", "\\!text", "\\!text"); 160 assertTextArray("Escaped !text/", "\\!text/", "\\!text/"); 161 assertTextArray("Escaped !TEXT/", "\\!TEXT/", "\\!TEXT/"); 162 assertTextArray("Escaped !text/name", "\\!text/empty_string", "\\!text/empty_string"); 163 assertTextArray("Escaped !TEXT/NAME", "\\!TEXT/EMPTY_STRING", "\\!TEXT/EMPTY_STRING"); 164 } 165 166 public void testSplitMulti() { 167 assertTextArray("Multiple chars", "a,b,c", "a", "b", "c"); 168 assertTextArray("Multiple chars", "a,b,\\c", "a", "b", "\\c"); 169 assertTextArray("Multiple chars and escape at beginning and end", 170 "\\a,b,\\c\\", "\\a", "b", "\\c\\"); 171 assertTextArray("Multiple surrogates", PAIR1 + "," + PAIR2 + "," + PAIR3, 172 PAIR1, PAIR2, PAIR3); 173 assertTextArray("Multiple chars surrounded by spaces", " a , b , c ", " a ", " b ", " c "); 174 assertTextArray("Multiple labels", "abc,def,ghi", "abc", "def", "ghi"); 175 assertTextArray("Multiple surrogated", SURROGATE1 + "," + SURROGATE2, 176 SURROGATE1, SURROGATE2); 177 assertTextArray("Multiple labels surrounded by spaces", " abc , def , ghi ", 178 " abc ", " def ", " ghi "); 179 } 180 181 public void testSplitMultiEscaped() { 182 assertTextArray("Multiple chars with comma", "a,\\,,c", "a", "\\,", "c"); 183 assertTextArray("Multiple chars with comma surrounded by spaces", " a , \\, , c ", 184 " a ", " \\, ", " c "); 185 assertTextArray("Multiple labels with escape", 186 "\\abc,d\\ef,gh\\i", "\\abc", "d\\ef", "gh\\i"); 187 assertTextArray("Multiple labels with escape surrounded by spaces", 188 " \\abc , d\\ef , gh\\i ", " \\abc ", " d\\ef ", " gh\\i "); 189 assertTextArray("Multiple labels with comma and escape", 190 "ab\\\\,d\\\\\\,,g\\,i", "ab\\\\", "d\\\\\\,", "g\\,i"); 191 assertTextArray("Multiple labels with comma and escape surrounded by spaces", 192 " ab\\\\ , d\\\\\\, , g\\,i ", " ab\\\\ ", " d\\\\\\, ", " g\\,i "); 193 194 assertTextArray("Multiple escaped !text", "\\!,\\!text/empty_string", 195 "\\!", "\\!text/empty_string"); 196 assertTextArray("Multiple escaped !TEXT", "\\!,\\!TEXT/EMPTY_STRING", 197 "\\!", "\\!TEXT/EMPTY_STRING"); 198 } 199 200 public void testSplitTextReferenceError() { 201 assertError("Incomplete text name", "!text/", "!text/"); 202 assertError("Non existing text", "!text/non_existing"); 203 } 204 205 public void testSplitEmptyTextReference() { 206 // Note that morekeys_q of English locale is empty. 207 assertTextArray("Empty string", "!text/morekeys_q"); 208 } 209 210 public void testLabelReferece() { 211 assertTextArray("Label time am", "!text/keylabel_time_am", "AM"); 212 213 assertTextArray("More keys for am pm", "!text/morekeys_am_pm", 214 "!fixedColumnOrder!2", "!hasLabels!", "AM", "PM"); 215 216 assertTextArray("Settings as more key", "!text/keyspec_settings", 217 "!icon/settings_key|!code/key_settings"); 218 } 219 220 public void testUselessUpperCaseSpecifier() { 221 assertTextArray("EMPTY STRING", 222 "!TEXT/EMPTY_STRING", "!TEXT/EMPTY_STRING"); 223 224 assertTextArray("SINGLE CHAR", 225 "!TEXT/SINGLE_CHAR", "!TEXT/SINGLE_CHAR"); 226 assertTextArray("Escape and SINGLE CHAR", 227 "\\\\!TEXT/SINGLE_CHAR", "\\\\!TEXT/SINGLE_CHAR"); 228 229 assertTextArray("MULTIPLE CHARS", 230 "!TEXT/MULTIPLE_CHARS", "!TEXT/MULTIPLE_CHARS"); 231 232 assertTextArray("Literals and RESOURCES", 233 "1,!TEXT/MULTIPLE_CHARS,z", "1", "!TEXT/MULTIPLE_CHARS", "z"); 234 assertTextArray("Multiple single RESOURCE chars and LABELS 2", 235 "!TEXT/SINGLE_CHAR,!TEXT/SINGLE_LABEL,!TEXT/ESCAPED_COMMA_ESCAPE", 236 "!TEXT/SINGLE_CHAR", "!TEXT/SINGLE_LABEL", "!TEXT/ESCAPED_COMMA_ESCAPE"); 237 238 assertTextArray("INDIRECT", 239 "!TEXT/INDIRECT_STRING", "!TEXT/INDIRECT_STRING"); 240 assertTextArray("INDIRECT with literal", 241 "1,!TEXT/INDIRECT_STRING_WITH_LITERAL,2", 242 "1", "!TEXT/INDIRECT_STRING_WITH_LITERAL", "2"); 243 assertTextArray("INDIRECT2", 244 "!TEXT/INDIRECT2_STRING", "!TEXT/INDIRECT2_STRING"); 245 246 assertTextArray("UPPER INDIRECT", 247 "!TEXT/upper_INDIRECT_STRING", "!TEXT/upper_INDIRECT_STRING"); 248 assertTextArray("Upper INDIRECT with literal", 249 "1,!TEXT/upper_INDIRECT_STRING_WITH_LITERAL,2", 250 "1", "!TEXT/upper_INDIRECT_STRING_WITH_LITERAL", "2"); 251 assertTextArray("Upper INDIRECT2", 252 "!TEXT/upper_INDIRECT2_STRING", "!TEXT/upper_INDIRECT2_STRING"); 253 254 assertTextArray("INFINITE INDIRECTION", 255 "1,!TEXT/INFINITE_INDIRECTION,2", "1", "!TEXT/INFINITE_INDIRECTION", "2"); 256 257 assertTextArray("Upper INFINITE INDIRECTION", 258 "1,!TEXT/UPPER_INFINITE_INDIRECTION,2", 259 "1", "!TEXT/UPPER_INFINITE_INDIRECTION", "2"); 260 261 assertTextArray("LABEL TIME AM", "!TEXT/LABEL_TIME_AM", "!TEXT/LABEL_TIME_AM"); 262 assertTextArray("MORE KEYS FOR AM OM", "!TEXT/MORE_KEYS_FOR_AM_PM", 263 "!TEXT/MORE_KEYS_FOR_AM_PM"); 264 assertTextArray("SETTINGS AS MORE KEY", "!TEXT/SETTINGS_AS_MORE_KEY", 265 "!TEXT/SETTINGS_AS_MORE_KEY"); 266 assertTextArray("INDIRECT NAVIGATE ACTIONS AS MORE KEY", 267 "!TEXT/INDIRECT_NAVIGATE_ACTIONS_AS_MORE_KEY", 268 "!TEXT/INDIRECT_NAVIGATE_ACTIONS_AS_MORE_KEY"); 269 } 270 } 271