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 static com.android.inputmethod.keyboard.internal.KeyboardIconsSet.ICON_UNDEFINED; 20 import static com.android.inputmethod.latin.Constants.CODE_UNSPECIFIED; 21 22 import android.test.suitebuilder.annotation.SmallTest; 23 24 import com.android.inputmethod.latin.Constants; 25 26 import java.util.Arrays; 27 import java.util.Locale; 28 29 @SmallTest 30 public final class MoreKeySpecTests extends KeySpecParserTestsBase { 31 @Override 32 protected void assertParser(final String message, final String moreKeySpec, 33 final String expectedLabel, final String expectedOutputText, final int expectedIconId, 34 final int expectedCode) { 35 final String labelResolved = mTextsSet.resolveTextReference(moreKeySpec); 36 final MoreKeySpec spec = new MoreKeySpec( 37 labelResolved, false /* needsToUpperCase */, Locale.US); 38 assertEquals(message + " [label]", expectedLabel, spec.mLabel); 39 assertEquals(message + " [ouptputText]", expectedOutputText, spec.mOutputText); 40 assertEquals(message + " [icon]", 41 KeyboardIconsSet.getIconName(expectedIconId), 42 KeyboardIconsSet.getIconName(spec.mIconId)); 43 assertEquals(message + " [code]", 44 Constants.printableCode(expectedCode), 45 Constants.printableCode(spec.mCode)); 46 } 47 48 // TODO: Move this method to {@link KeySpecParserBase}. 49 public void testEmptySpec() { 50 assertParserError("Null spec", null, 51 null, null, ICON_UNDEFINED, CODE_UNSPECIFIED); 52 assertParserError("Empty spec", "", 53 null, null, ICON_UNDEFINED, CODE_UNSPECIFIED); 54 } 55 56 private static void assertArrayEquals(final String message, final Object[] expected, 57 final Object[] actual) { 58 if (expected == actual) { 59 return; 60 } 61 if (expected == null || actual == null) { 62 assertEquals(message, Arrays.toString(expected), Arrays.toString(actual)); 63 return; 64 } 65 if (expected.length != actual.length) { 66 assertEquals(message + " [length]", Arrays.toString(expected), Arrays.toString(actual)); 67 return; 68 } 69 for (int i = 0; i < expected.length; i++) { 70 assertEquals(message + " [" + i + "]", 71 Arrays.toString(expected), Arrays.toString(actual)); 72 } 73 } 74 75 private static void assertInsertAdditionalMoreKeys(final String message, 76 final String[] moreKeys, final String[] additionalMoreKeys, final String[] expected) { 77 final String[] actual = MoreKeySpec.insertAdditionalMoreKeys(moreKeys, additionalMoreKeys); 78 assertArrayEquals(message, expected, actual); 79 } 80 81 public void testEmptyEntry() { 82 assertInsertAdditionalMoreKeys("null more keys and null additons", 83 null, 84 null, 85 null); 86 assertInsertAdditionalMoreKeys("null more keys and empty additons", 87 null, 88 new String[0], 89 null); 90 assertInsertAdditionalMoreKeys("empty more keys and null additons", 91 new String[0], 92 null, 93 null); 94 assertInsertAdditionalMoreKeys("empty more keys and empty additons", 95 new String[0], 96 new String[0], 97 null); 98 99 assertInsertAdditionalMoreKeys("filter out empty more keys", 100 new String[] { null, "a", "", "b", null }, 101 null, 102 new String[] { "a", "b" }); 103 assertInsertAdditionalMoreKeys("filter out empty additons", 104 new String[] { "a", "%", "b", "%", "c", "%", "d" }, 105 new String[] { null, "A", "", "B", null }, 106 new String[] { "a", "A", "b", "B", "c", "d" }); 107 } 108 109 public void testInsertAdditionalMoreKeys() { 110 // Escaped marker. 111 assertInsertAdditionalMoreKeys("escaped marker", 112 new String[] { "\\%", "%-)" }, 113 new String[] { "1", "2" }, 114 new String[] { "1", "2", "\\%", "%-)" }); 115 116 // 0 more key. 117 assertInsertAdditionalMoreKeys("null & null", null, null, null); 118 assertInsertAdditionalMoreKeys("null & 1 additon", 119 null, 120 new String[] { "1" }, 121 new String[] { "1" }); 122 assertInsertAdditionalMoreKeys("null & 2 additons", 123 null, 124 new String[] { "1", "2" }, 125 new String[] { "1", "2" }); 126 127 // 0 additional more key. 128 assertInsertAdditionalMoreKeys("1 more key & null", 129 new String[] { "A" }, 130 null, 131 new String[] { "A" }); 132 assertInsertAdditionalMoreKeys("2 more keys & null", 133 new String[] { "A", "B" }, 134 null, 135 new String[] { "A", "B" }); 136 137 // No marker. 138 assertInsertAdditionalMoreKeys("1 more key & 1 addtional & no marker", 139 new String[] { "A" }, 140 new String[] { "1" }, 141 new String[] { "1", "A" }); 142 assertInsertAdditionalMoreKeys("1 more key & 2 addtionals & no marker", 143 new String[] { "A" }, 144 new String[] { "1", "2" }, 145 new String[] { "1", "2", "A" }); 146 assertInsertAdditionalMoreKeys("2 more keys & 1 addtional & no marker", 147 new String[] { "A", "B" }, 148 new String[] { "1" }, 149 new String[] { "1", "A", "B" }); 150 assertInsertAdditionalMoreKeys("2 more keys & 2 addtionals & no marker", 151 new String[] { "A", "B" }, 152 new String[] { "1", "2" }, 153 new String[] { "1", "2", "A", "B" }); 154 155 // 1 marker. 156 assertInsertAdditionalMoreKeys("1 more key & 1 additon & marker at head", 157 new String[] { "%", "A" }, 158 new String[] { "1" }, 159 new String[] { "1", "A" }); 160 assertInsertAdditionalMoreKeys("1 more key & 1 additon & marker at tail", 161 new String[] { "A", "%" }, 162 new String[] { "1" }, 163 new String[] { "A", "1" }); 164 assertInsertAdditionalMoreKeys("2 more keys & 1 additon & marker at middle", 165 new String[] { "A", "%", "B" }, 166 new String[] { "1" }, 167 new String[] { "A", "1", "B" }); 168 169 // 1 marker & excess additional more keys. 170 assertInsertAdditionalMoreKeys("1 more key & 2 additons & marker at head", 171 new String[] { "%", "A", "B" }, 172 new String[] { "1", "2" }, 173 new String[] { "1", "A", "B", "2" }); 174 assertInsertAdditionalMoreKeys("1 more key & 2 additons & marker at tail", 175 new String[] { "A", "B", "%" }, 176 new String[] { "1", "2" }, 177 new String[] { "A", "B", "1", "2" }); 178 assertInsertAdditionalMoreKeys("2 more keys & 2 additons & marker at middle", 179 new String[] { "A", "%", "B" }, 180 new String[] { "1", "2" }, 181 new String[] { "A", "1", "B", "2" }); 182 183 // 2 markers. 184 assertInsertAdditionalMoreKeys("0 more key & 2 addtional & 2 markers", 185 new String[] { "%", "%" }, 186 new String[] { "1", "2" }, 187 new String[] { "1", "2" }); 188 assertInsertAdditionalMoreKeys("1 more key & 2 addtional & 2 markers at head", 189 new String[] { "%", "%", "A" }, 190 new String[] { "1", "2" }, 191 new String[] { "1", "2", "A" }); 192 assertInsertAdditionalMoreKeys("1 more key & 2 addtional & 2 markers at tail", 193 new String[] { "A", "%", "%" }, 194 new String[] { "1", "2" }, 195 new String[] { "A", "1", "2" }); 196 assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at middle", 197 new String[] { "A", "%", "%", "B" }, 198 new String[] { "1", "2" }, 199 new String[] { "A", "1", "2", "B" }); 200 assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at head & middle", 201 new String[] { "%", "A", "%", "B" }, 202 new String[] { "1", "2" }, 203 new String[] { "1", "A", "2", "B" }); 204 assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at head & tail", 205 new String[] { "%", "A", "B", "%" }, 206 new String[] { "1", "2" }, 207 new String[] { "1", "A", "B", "2" }); 208 assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at middle & tail", 209 new String[] { "A", "%", "B", "%" }, 210 new String[] { "1", "2" }, 211 new String[] { "A", "1", "B", "2" }); 212 213 // 2 markers & excess additional more keys. 214 assertInsertAdditionalMoreKeys("0 more key & 2 additons & 2 markers", 215 new String[] { "%", "%" }, 216 new String[] { "1", "2", "3" }, 217 new String[] { "1", "2", "3" }); 218 assertInsertAdditionalMoreKeys("1 more key & 2 additons & 2 markers at head", 219 new String[] { "%", "%", "A" }, 220 new String[] { "1", "2", "3" }, 221 new String[] { "1", "2", "A", "3" }); 222 assertInsertAdditionalMoreKeys("1 more key & 2 additons & 2 markers at tail", 223 new String[] { "A", "%", "%" }, 224 new String[] { "1", "2", "3" }, 225 new String[] { "A", "1", "2", "3" }); 226 assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at middle", 227 new String[] { "A", "%", "%", "B" }, 228 new String[] { "1", "2", "3" }, 229 new String[] { "A", "1", "2", "B", "3" }); 230 assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at head & middle", 231 new String[] { "%", "A", "%", "B" }, 232 new String[] { "1", "2", "3" }, 233 new String[] { "1", "A", "2", "B", "3" }); 234 assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at head & tail", 235 new String[] { "%", "A", "B", "%" }, 236 new String[] { "1", "2", "3" }, 237 new String[] { "1", "A", "B", "2", "3" }); 238 assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at middle & tail", 239 new String[] { "A", "%", "B", "%" }, 240 new String[] { "1", "2", "3" }, 241 new String[] { "A", "1", "B", "2", "3" }); 242 243 // 0 addtional more key and excess markers. 244 assertInsertAdditionalMoreKeys("0 more key & null & excess marker", 245 new String[] { "%" }, 246 null, 247 null); 248 assertInsertAdditionalMoreKeys("1 more key & null & excess marker at head", 249 new String[] { "%", "A" }, 250 null, 251 new String[] { "A" }); 252 assertInsertAdditionalMoreKeys("1 more key & null & excess marker at tail", 253 new String[] { "A", "%" }, 254 null, 255 new String[] { "A" }); 256 assertInsertAdditionalMoreKeys("2 more keys & null & excess marker at middle", 257 new String[] { "A", "%", "B" }, 258 null, 259 new String[] { "A", "B" }); 260 assertInsertAdditionalMoreKeys("2 more keys & null & excess markers", 261 new String[] { "%", "A", "%", "B", "%" }, 262 null, 263 new String[] { "A", "B" }); 264 265 // Excess markers. 266 assertInsertAdditionalMoreKeys("0 more key & 1 additon & excess marker", 267 new String[] { "%", "%" }, 268 new String[] { "1" }, 269 new String[] { "1" }); 270 assertInsertAdditionalMoreKeys("1 more key & 1 additon & excess marker at head", 271 new String[] { "%", "%", "A" }, 272 new String[] { "1" }, 273 new String[] { "1", "A" }); 274 assertInsertAdditionalMoreKeys("1 more key & 1 additon & excess marker at tail", 275 new String[] { "A", "%", "%" }, 276 new String[] { "1" }, 277 new String[] { "A", "1" }); 278 assertInsertAdditionalMoreKeys("2 more keys & 1 additon & excess marker at middle", 279 new String[] { "A", "%", "%", "B" }, 280 new String[] { "1" }, 281 new String[] { "A", "1", "B" }); 282 assertInsertAdditionalMoreKeys("2 more keys & 1 additon & excess markers", 283 new String[] { "%", "A", "%", "B", "%" }, 284 new String[] { "1" }, 285 new String[] { "1", "A", "B" }); 286 assertInsertAdditionalMoreKeys("2 more keys & 2 additons & excess markers", 287 new String[] { "%", "A", "%", "B", "%" }, 288 new String[] { "1", "2" }, 289 new String[] { "1", "A", "2", "B" }); 290 assertInsertAdditionalMoreKeys("2 more keys & 3 additons & excess markers", 291 new String[] { "%", "A", "%", "%", "B", "%" }, 292 new String[] { "1", "2", "3" }, 293 new String[] { "1", "A", "2", "3", "B" }); 294 } 295 296 private static final String HAS_LABEL = "!hasLabel!"; 297 private static final String NEEDS_DIVIDER = "!needsDividers!"; 298 private static final String AUTO_COLUMN_ORDER = "!autoColumnOrder!"; 299 private static final String FIXED_COLUMN_ORDER = "!fixedColumnOrder!"; 300 301 private static void assertGetBooleanValue(final String message, final String key, 302 final String[] moreKeys, final String[] expected, final boolean expectedValue) { 303 final String[] actual = Arrays.copyOf(moreKeys, moreKeys.length); 304 final boolean actualValue = MoreKeySpec.getBooleanValue(actual, key); 305 assertEquals(message + " [value]", expectedValue, actualValue); 306 assertArrayEquals(message, expected, actual); 307 } 308 309 public void testGetBooleanValue() { 310 assertGetBooleanValue("Has label", HAS_LABEL, 311 new String[] { HAS_LABEL, "a", "b", "c" }, 312 new String[] { null, "a", "b", "c" }, true); 313 // Upper case specification will not work. 314 assertGetBooleanValue("HAS LABEL", HAS_LABEL, 315 new String[] { HAS_LABEL.toUpperCase(Locale.ROOT), "a", "b", "c" }, 316 new String[] { "!HASLABEL!", "a", "b", "c" }, false); 317 318 assertGetBooleanValue("No has label", HAS_LABEL, 319 new String[] { "a", "b", "c" }, 320 new String[] { "a", "b", "c" }, false); 321 assertGetBooleanValue("No has label with fixed clumn order", HAS_LABEL, 322 new String[] { FIXED_COLUMN_ORDER + "3", "a", "b", "c" }, 323 new String[] { FIXED_COLUMN_ORDER + "3", "a", "b", "c" }, false); 324 325 // Upper case specification will not work. 326 assertGetBooleanValue("Multiple has label", HAS_LABEL, 327 new String[] { 328 "a", HAS_LABEL.toUpperCase(Locale.ROOT), "b", "c", HAS_LABEL, "d" }, 329 new String[] { 330 "a", "!HASLABEL!", "b", "c", null, "d" }, true); 331 // Upper case specification will not work. 332 assertGetBooleanValue("Multiple has label with needs dividers", HAS_LABEL, 333 new String[] { 334 "a", HAS_LABEL, "b", NEEDS_DIVIDER, HAS_LABEL.toUpperCase(Locale.ROOT), "d" }, 335 new String[] { 336 "a", null, "b", NEEDS_DIVIDER, "!HASLABEL!", "d" }, true); 337 } 338 339 private static void assertGetIntValue(final String message, final String key, 340 final int defaultValue, final String[] moreKeys, final String[] expected, 341 final int expectedValue) { 342 final String[] actual = Arrays.copyOf(moreKeys, moreKeys.length); 343 final int actualValue = MoreKeySpec.getIntValue(actual, key, defaultValue); 344 assertEquals(message + " [value]", expectedValue, actualValue); 345 assertArrayEquals(message, expected, actual); 346 } 347 348 public void testGetIntValue() { 349 assertGetIntValue("Fixed column order 3", FIXED_COLUMN_ORDER, -1, 350 new String[] { FIXED_COLUMN_ORDER + "3", "a", "b", "c" }, 351 new String[] { null, "a", "b", "c" }, 3); 352 // Upper case specification will not work. 353 assertGetIntValue("FIXED COLUMN ORDER 3", FIXED_COLUMN_ORDER, -1, 354 new String[] { FIXED_COLUMN_ORDER.toUpperCase(Locale.ROOT) + "3", "a", "b", "c" }, 355 new String[] { "!FIXEDCOLUMNORDER!3", "a", "b", "c" }, -1); 356 357 assertGetIntValue("No fixed column order", FIXED_COLUMN_ORDER, -1, 358 new String[] { "a", "b", "c" }, 359 new String[] { "a", "b", "c" }, -1); 360 assertGetIntValue("No fixed column order with auto column order", FIXED_COLUMN_ORDER, -1, 361 new String[] { AUTO_COLUMN_ORDER + "5", "a", "b", "c" }, 362 new String[] { AUTO_COLUMN_ORDER + "5", "a", "b", "c" }, -1); 363 364 assertGetIntValue("Multiple fixed column order 3,5", FIXED_COLUMN_ORDER, -1, 365 new String[] { FIXED_COLUMN_ORDER + "3", "a", FIXED_COLUMN_ORDER + "5", "b" }, 366 new String[] { null, "a", null, "b" }, 3); 367 // Upper case specification will not work. 368 assertGetIntValue("Multiple fixed column order 5,3 with has label", FIXED_COLUMN_ORDER, -1, 369 new String[] { 370 FIXED_COLUMN_ORDER.toUpperCase(Locale.ROOT) + "5", HAS_LABEL, "a", 371 FIXED_COLUMN_ORDER + "3", "b" }, 372 new String[] { "!FIXEDCOLUMNORDER!5", HAS_LABEL, "a", null, "b" }, 3); 373 } 374 } 375