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.common.Constants.CODE_UNSPECIFIED; 21 22 import android.test.suitebuilder.annotation.SmallTest; 23 24 import com.android.inputmethod.latin.common.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 @SuppressWarnings("static-method") 82 public void testEmptyEntry() { 83 assertInsertAdditionalMoreKeys("null more keys and null additons", 84 null, 85 null, 86 null); 87 assertInsertAdditionalMoreKeys("null more keys and empty additons", 88 null, 89 new String[0], 90 null); 91 assertInsertAdditionalMoreKeys("empty more keys and null additons", 92 new String[0], 93 null, 94 null); 95 assertInsertAdditionalMoreKeys("empty more keys and empty additons", 96 new String[0], 97 new String[0], 98 null); 99 100 assertInsertAdditionalMoreKeys("filter out empty more keys", 101 new String[] { null, "a", "", "b", null }, 102 null, 103 new String[] { "a", "b" }); 104 assertInsertAdditionalMoreKeys("filter out empty additons", 105 new String[] { "a", "%", "b", "%", "c", "%", "d" }, 106 new String[] { null, "A", "", "B", null }, 107 new String[] { "a", "A", "b", "B", "c", "d" }); 108 } 109 110 @SuppressWarnings("static-method") 111 public void testInsertAdditionalMoreKeys() { 112 // Escaped marker. 113 assertInsertAdditionalMoreKeys("escaped marker", 114 new String[] { "\\%", "%-)" }, 115 new String[] { "1", "2" }, 116 new String[] { "1", "2", "\\%", "%-)" }); 117 118 // 0 more key. 119 assertInsertAdditionalMoreKeys("null & null", null, null, null); 120 assertInsertAdditionalMoreKeys("null & 1 additon", 121 null, 122 new String[] { "1" }, 123 new String[] { "1" }); 124 assertInsertAdditionalMoreKeys("null & 2 additons", 125 null, 126 new String[] { "1", "2" }, 127 new String[] { "1", "2" }); 128 129 // 0 additional more key. 130 assertInsertAdditionalMoreKeys("1 more key & null", 131 new String[] { "A" }, 132 null, 133 new String[] { "A" }); 134 assertInsertAdditionalMoreKeys("2 more keys & null", 135 new String[] { "A", "B" }, 136 null, 137 new String[] { "A", "B" }); 138 139 // No marker. 140 assertInsertAdditionalMoreKeys("1 more key & 1 addtional & no marker", 141 new String[] { "A" }, 142 new String[] { "1" }, 143 new String[] { "1", "A" }); 144 assertInsertAdditionalMoreKeys("1 more key & 2 addtionals & no marker", 145 new String[] { "A" }, 146 new String[] { "1", "2" }, 147 new String[] { "1", "2", "A" }); 148 assertInsertAdditionalMoreKeys("2 more keys & 1 addtional & no marker", 149 new String[] { "A", "B" }, 150 new String[] { "1" }, 151 new String[] { "1", "A", "B" }); 152 assertInsertAdditionalMoreKeys("2 more keys & 2 addtionals & no marker", 153 new String[] { "A", "B" }, 154 new String[] { "1", "2" }, 155 new String[] { "1", "2", "A", "B" }); 156 157 // 1 marker. 158 assertInsertAdditionalMoreKeys("1 more key & 1 additon & marker at head", 159 new String[] { "%", "A" }, 160 new String[] { "1" }, 161 new String[] { "1", "A" }); 162 assertInsertAdditionalMoreKeys("1 more key & 1 additon & marker at tail", 163 new String[] { "A", "%" }, 164 new String[] { "1" }, 165 new String[] { "A", "1" }); 166 assertInsertAdditionalMoreKeys("2 more keys & 1 additon & marker at middle", 167 new String[] { "A", "%", "B" }, 168 new String[] { "1" }, 169 new String[] { "A", "1", "B" }); 170 171 // 1 marker & excess additional more keys. 172 assertInsertAdditionalMoreKeys("1 more key & 2 additons & marker at head", 173 new String[] { "%", "A", "B" }, 174 new String[] { "1", "2" }, 175 new String[] { "1", "A", "B", "2" }); 176 assertInsertAdditionalMoreKeys("1 more key & 2 additons & marker at tail", 177 new String[] { "A", "B", "%" }, 178 new String[] { "1", "2" }, 179 new String[] { "A", "B", "1", "2" }); 180 assertInsertAdditionalMoreKeys("2 more keys & 2 additons & marker at middle", 181 new String[] { "A", "%", "B" }, 182 new String[] { "1", "2" }, 183 new String[] { "A", "1", "B", "2" }); 184 185 // 2 markers. 186 assertInsertAdditionalMoreKeys("0 more key & 2 addtional & 2 markers", 187 new String[] { "%", "%" }, 188 new String[] { "1", "2" }, 189 new String[] { "1", "2" }); 190 assertInsertAdditionalMoreKeys("1 more key & 2 addtional & 2 markers at head", 191 new String[] { "%", "%", "A" }, 192 new String[] { "1", "2" }, 193 new String[] { "1", "2", "A" }); 194 assertInsertAdditionalMoreKeys("1 more key & 2 addtional & 2 markers at tail", 195 new String[] { "A", "%", "%" }, 196 new String[] { "1", "2" }, 197 new String[] { "A", "1", "2" }); 198 assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at middle", 199 new String[] { "A", "%", "%", "B" }, 200 new String[] { "1", "2" }, 201 new String[] { "A", "1", "2", "B" }); 202 assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at head & middle", 203 new String[] { "%", "A", "%", "B" }, 204 new String[] { "1", "2" }, 205 new String[] { "1", "A", "2", "B" }); 206 assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at head & tail", 207 new String[] { "%", "A", "B", "%" }, 208 new String[] { "1", "2" }, 209 new String[] { "1", "A", "B", "2" }); 210 assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at middle & tail", 211 new String[] { "A", "%", "B", "%" }, 212 new String[] { "1", "2" }, 213 new String[] { "A", "1", "B", "2" }); 214 215 // 2 markers & excess additional more keys. 216 assertInsertAdditionalMoreKeys("0 more key & 2 additons & 2 markers", 217 new String[] { "%", "%" }, 218 new String[] { "1", "2", "3" }, 219 new String[] { "1", "2", "3" }); 220 assertInsertAdditionalMoreKeys("1 more key & 2 additons & 2 markers at head", 221 new String[] { "%", "%", "A" }, 222 new String[] { "1", "2", "3" }, 223 new String[] { "1", "2", "A", "3" }); 224 assertInsertAdditionalMoreKeys("1 more key & 2 additons & 2 markers at tail", 225 new String[] { "A", "%", "%" }, 226 new String[] { "1", "2", "3" }, 227 new String[] { "A", "1", "2", "3" }); 228 assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at middle", 229 new String[] { "A", "%", "%", "B" }, 230 new String[] { "1", "2", "3" }, 231 new String[] { "A", "1", "2", "B", "3" }); 232 assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at head & middle", 233 new String[] { "%", "A", "%", "B" }, 234 new String[] { "1", "2", "3" }, 235 new String[] { "1", "A", "2", "B", "3" }); 236 assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at head & tail", 237 new String[] { "%", "A", "B", "%" }, 238 new String[] { "1", "2", "3" }, 239 new String[] { "1", "A", "B", "2", "3" }); 240 assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at middle & tail", 241 new String[] { "A", "%", "B", "%" }, 242 new String[] { "1", "2", "3" }, 243 new String[] { "A", "1", "B", "2", "3" }); 244 245 // 0 addtional more key and excess markers. 246 assertInsertAdditionalMoreKeys("0 more key & null & excess marker", 247 new String[] { "%" }, 248 null, 249 null); 250 assertInsertAdditionalMoreKeys("1 more key & null & excess marker at head", 251 new String[] { "%", "A" }, 252 null, 253 new String[] { "A" }); 254 assertInsertAdditionalMoreKeys("1 more key & null & excess marker at tail", 255 new String[] { "A", "%" }, 256 null, 257 new String[] { "A" }); 258 assertInsertAdditionalMoreKeys("2 more keys & null & excess marker at middle", 259 new String[] { "A", "%", "B" }, 260 null, 261 new String[] { "A", "B" }); 262 assertInsertAdditionalMoreKeys("2 more keys & null & excess markers", 263 new String[] { "%", "A", "%", "B", "%" }, 264 null, 265 new String[] { "A", "B" }); 266 267 // Excess markers. 268 assertInsertAdditionalMoreKeys("0 more key & 1 additon & excess marker", 269 new String[] { "%", "%" }, 270 new String[] { "1" }, 271 new String[] { "1" }); 272 assertInsertAdditionalMoreKeys("1 more key & 1 additon & excess marker at head", 273 new String[] { "%", "%", "A" }, 274 new String[] { "1" }, 275 new String[] { "1", "A" }); 276 assertInsertAdditionalMoreKeys("1 more key & 1 additon & excess marker at tail", 277 new String[] { "A", "%", "%" }, 278 new String[] { "1" }, 279 new String[] { "A", "1" }); 280 assertInsertAdditionalMoreKeys("2 more keys & 1 additon & excess marker at middle", 281 new String[] { "A", "%", "%", "B" }, 282 new String[] { "1" }, 283 new String[] { "A", "1", "B" }); 284 assertInsertAdditionalMoreKeys("2 more keys & 1 additon & excess markers", 285 new String[] { "%", "A", "%", "B", "%" }, 286 new String[] { "1" }, 287 new String[] { "1", "A", "B" }); 288 assertInsertAdditionalMoreKeys("2 more keys & 2 additons & excess markers", 289 new String[] { "%", "A", "%", "B", "%" }, 290 new String[] { "1", "2" }, 291 new String[] { "1", "A", "2", "B" }); 292 assertInsertAdditionalMoreKeys("2 more keys & 3 additons & excess markers", 293 new String[] { "%", "A", "%", "%", "B", "%" }, 294 new String[] { "1", "2", "3" }, 295 new String[] { "1", "A", "2", "3", "B" }); 296 } 297 298 private static final String HAS_LABEL = "!hasLabel!"; 299 private static final String NEEDS_DIVIDER = "!needsDividers!"; 300 private static final String AUTO_COLUMN_ORDER = "!autoColumnOrder!"; 301 private static final String FIXED_COLUMN_ORDER = "!fixedColumnOrder!"; 302 303 private static void assertGetBooleanValue(final String message, final String key, 304 final String[] moreKeys, final String[] expected, final boolean expectedValue) { 305 final String[] actual = Arrays.copyOf(moreKeys, moreKeys.length); 306 final boolean actualValue = MoreKeySpec.getBooleanValue(actual, key); 307 assertEquals(message + " [value]", expectedValue, actualValue); 308 assertArrayEquals(message, expected, actual); 309 } 310 311 @SuppressWarnings("static-method") 312 public void testGetBooleanValue() { 313 assertGetBooleanValue("Has label", HAS_LABEL, 314 new String[] { HAS_LABEL, "a", "b", "c" }, 315 new String[] { null, "a", "b", "c" }, true); 316 // Upper case specification will not work. 317 assertGetBooleanValue("HAS LABEL", HAS_LABEL, 318 new String[] { HAS_LABEL.toUpperCase(Locale.ROOT), "a", "b", "c" }, 319 new String[] { "!HASLABEL!", "a", "b", "c" }, false); 320 321 assertGetBooleanValue("No has label", HAS_LABEL, 322 new String[] { "a", "b", "c" }, 323 new String[] { "a", "b", "c" }, false); 324 assertGetBooleanValue("No has label with fixed clumn order", HAS_LABEL, 325 new String[] { FIXED_COLUMN_ORDER + "3", "a", "b", "c" }, 326 new String[] { FIXED_COLUMN_ORDER + "3", "a", "b", "c" }, false); 327 328 // Upper case specification will not work. 329 assertGetBooleanValue("Multiple has label", HAS_LABEL, 330 new String[] { 331 "a", HAS_LABEL.toUpperCase(Locale.ROOT), "b", "c", HAS_LABEL, "d" }, 332 new String[] { 333 "a", "!HASLABEL!", "b", "c", null, "d" }, true); 334 // Upper case specification will not work. 335 assertGetBooleanValue("Multiple has label with needs dividers", HAS_LABEL, 336 new String[] { 337 "a", HAS_LABEL, "b", NEEDS_DIVIDER, HAS_LABEL.toUpperCase(Locale.ROOT), "d" }, 338 new String[] { 339 "a", null, "b", NEEDS_DIVIDER, "!HASLABEL!", "d" }, true); 340 } 341 342 private static void assertGetIntValue(final String message, final String key, 343 final int defaultValue, final String[] moreKeys, final String[] expected, 344 final int expectedValue) { 345 final String[] actual = Arrays.copyOf(moreKeys, moreKeys.length); 346 final int actualValue = MoreKeySpec.getIntValue(actual, key, defaultValue); 347 assertEquals(message + " [value]", expectedValue, actualValue); 348 assertArrayEquals(message, expected, actual); 349 } 350 351 @SuppressWarnings("static-method") 352 public void testGetIntValue() { 353 assertGetIntValue("Fixed column order 3", FIXED_COLUMN_ORDER, -1, 354 new String[] { FIXED_COLUMN_ORDER + "3", "a", "b", "c" }, 355 new String[] { null, "a", "b", "c" }, 3); 356 // Upper case specification will not work. 357 assertGetIntValue("FIXED COLUMN ORDER 3", FIXED_COLUMN_ORDER, -1, 358 new String[] { FIXED_COLUMN_ORDER.toUpperCase(Locale.ROOT) + "3", "a", "b", "c" }, 359 new String[] { "!FIXEDCOLUMNORDER!3", "a", "b", "c" }, -1); 360 361 assertGetIntValue("No fixed column order", FIXED_COLUMN_ORDER, -1, 362 new String[] { "a", "b", "c" }, 363 new String[] { "a", "b", "c" }, -1); 364 assertGetIntValue("No fixed column order with auto column order", FIXED_COLUMN_ORDER, -1, 365 new String[] { AUTO_COLUMN_ORDER + "5", "a", "b", "c" }, 366 new String[] { AUTO_COLUMN_ORDER + "5", "a", "b", "c" }, -1); 367 368 assertGetIntValue("Multiple fixed column order 3,5", FIXED_COLUMN_ORDER, -1, 369 new String[] { FIXED_COLUMN_ORDER + "3", "a", FIXED_COLUMN_ORDER + "5", "b" }, 370 new String[] { null, "a", null, "b" }, 3); 371 // Upper case specification will not work. 372 assertGetIntValue("Multiple fixed column order 5,3 with has label", FIXED_COLUMN_ORDER, -1, 373 new String[] { 374 FIXED_COLUMN_ORDER.toUpperCase(Locale.ROOT) + "5", HAS_LABEL, "a", 375 FIXED_COLUMN_ORDER + "3", "b" }, 376 new String[] { "!FIXEDCOLUMNORDER!5", HAS_LABEL, "a", null, "b" }, 3); 377 } 378 } 379