From ff8405cdfbd575657a6f615a1ac4d86eb1b07f74 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Thu, 6 Mar 2014 19:23:12 +0900 Subject: [PATCH] Add ActualKeyboardBuilder for testing keyboard layouts Bug: 13017434 Change-Id: I38b1f5c261ea1f3ff312c780d7d9b5fe3fba8aaf --- .../inputmethod/latin/utils/StringUtils.java | 40 ++++ .../expected/ActualKeyboardBuilder.java | 189 ++++++++++++++++++ 2 files changed, 229 insertions(+) create mode 100644 tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java diff --git a/java/src/com/android/inputmethod/latin/utils/StringUtils.java b/java/src/com/android/inputmethod/latin/utils/StringUtils.java index e7932b5a6..b9d526b5f 100644 --- a/java/src/com/android/inputmethod/latin/utils/StringUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/StringUtils.java @@ -507,4 +507,44 @@ public final class StringUtils { return codePointCount(casedText) == 1 ? casedText.codePointAt(0) : CODE_UNSPECIFIED; } + + @UsedForTesting + public static class Stringizer { + public String stringize(final E element) { + return element != null ? element.toString() : "null"; + } + + @UsedForTesting + public final String join(final E[] array) { + return joinStringArray(toStringArray(array), null /* delimiter */); + } + + @UsedForTesting + public final String join(final E[] array, final String delimiter) { + return joinStringArray(toStringArray(array), delimiter); + } + + protected String[] toStringArray(final E[] array) { + final String[] stringArray = new String[array.length]; + for (int index = 0; index < array.length; index++) { + stringArray[index] = stringize(array[index]); + } + return stringArray; + } + + protected String joinStringArray(final String[] stringArray, final String delimiter) { + if (stringArray == null) { + return "null"; + } + if (delimiter == null) { + return Arrays.toString(stringArray); + } + final StringBuilder sb = new StringBuilder(); + for (int index = 0; index < stringArray.length; index++) { + sb.append(index == 0 ? "[" : delimiter); + sb.append(stringArray[index]); + } + return sb + "]"; + } + } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java new file mode 100644 index 000000000..b918d47f8 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.expected; + +import com.android.inputmethod.keyboard.Key; +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.keyboard.internal.MoreKeySpec; +import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.utils.CollectionUtils; +import com.android.inputmethod.latin.utils.StringUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; + +/** + * This class builds an actual keyboard for unit test. + */ +public final class ActualKeyboardBuilder extends AbstractKeyboardBuilder { + // Comparator to sort {@link Key}s from top-left to bottom-right order. + private static final Comparator ROW_COLUMN_COMPARATOR = new Comparator() { + @Override + public int compare(final Key lhs, final Key rhs) { + if (lhs.getY() < rhs.getY()) return -1; + if (lhs.getY() > rhs.getY()) return 1; + if (lhs.getX() < rhs.getX()) return -1; + if (lhs.getX() > rhs.getX()) return 1; + return 0; + } + }; + + /** + * Create the keyboard that consists of the array of rows of the actual keyboard's keys. + * @param keys the array of keys of the actual keyboard. + * @return the actual keyboard grouped with rows. + */ + public static Key[][] buildKeyboard(final Key[] keys) { + // Sort keys from top-left to bottom-right order to prepare to create rows. + final ArrayList sortedKeys = CollectionUtils.newArrayList(Arrays.asList(keys)); + Collections.sort(sortedKeys, ROW_COLUMN_COMPARATOR); + + // Grouping keys into rows. + final ArrayList> rows = CollectionUtils.newArrayList(); + ArrayList elements = CollectionUtils.newArrayList(); + int lastY = sortedKeys.get(0).getY(); + for (final Key key : sortedKeys) { + if (lastY != key.getY()) { + // A new row is starting. + lastY = key.getY(); + rows.add(elements); + elements = CollectionUtils.newArrayList(); + } + elements.add(key); + } + rows.add(elements); // Add the last row. + + // Calculate each dimension of rows and create a builder. + final int[] dimensions = new int[rows.size()]; + for (int rowIndex = 0; rowIndex < dimensions.length; rowIndex++) { + dimensions[rowIndex] = rows.get(rowIndex).size(); + } + final ActualKeyboardBuilder builder = new ActualKeyboardBuilder(dimensions); + + for (int rowIndex = 0; rowIndex < rows.size(); rowIndex++) { + final int row = rowIndex + 1; + final ArrayList rowKeys = rows.get(rowIndex); + builder.setRowAt(row, rowKeys.toArray(new Key[rowKeys.size()])); + } + return builder.build(); + } + + private ActualKeyboardBuilder(final int ... dimensions) { + super(dimensions); + } + + @Override + Key defaultElement() { return null; } + + @Override + Key[] newArray(final int size) { return new Key[size]; } + + @Override + Key[][] newArrayOfArray(final int size) { return new Key[size][]; } + + // Helper class to create concise representation from the key specification. + static class MoreKeySpecStringizer extends StringUtils.Stringizer { + static final MoreKeySpecStringizer STRINGIZER = new MoreKeySpecStringizer(); + + @Override + public String stringize(final MoreKeySpec spec) { + return toString(spec.mLabel, spec.mIconId, spec.mOutputText, spec.mCode); + } + + static String toString(final String label, final int iconId, final String outputText, + final int code) { + final String visual = (iconId != KeyboardIconsSet.ICON_UNDEFINED) + ? KeyboardIconsSet.getIconName(iconId) : label; + final String output; + if (code == Constants.CODE_OUTPUT_TEXT) { + output = outputText; + } else if (code < Constants.CODE_SPACE) { + output = Constants.printableCode(code); + } else { + output = StringUtils.newSingleCodePointString(code); + } + if (visual.equals(output)) { + return visual; + } + return visual + "|" + output; + } + } + + // Helper class to create concise representation from the key. + static class KeyStringizer extends StringUtils.Stringizer { + static final KeyStringizer STRINGIZER = new KeyStringizer(); + + @Override + public String stringize(final Key key) { + if (key == null) { + return "NULL"; + } + if (key.isSpacer()) { + return "SPACER"; + } + final StringBuilder sb = new StringBuilder(); + sb.append(MoreKeySpecStringizer.toString( + key.getLabel(), key.getIconId(), key.getOutputText(), key.getCode())); + final MoreKeySpec[] moreKeys = key.getMoreKeys(); + if (moreKeys == null) { + return sb.toString(); + } + sb.append("^"); + sb.append(MoreKeySpecStringizer.STRINGIZER.join(moreKeys)); + return sb.toString(); + } + } + + /** + * Convert the key to human readable string. + * @param key the key to be converted to string. + * @return the human readable representation of key. + */ + public static String toString(final Key key) { + return KeyStringizer.STRINGIZER.stringize(key); + } + + /** + * Convert the keyboard row to human readable string. + * @param keys the keyboard row to be converted to string. + * @return the human readable representation of keys. + */ + public static String toString(final Key[] keys) { + return KeyStringizer.STRINGIZER.join(keys); + } + + // Helper class to create concise representation from the array of the key. + static class KeyArrayStringizer extends StringUtils.Stringizer { + static final KeyArrayStringizer STRINGIZER = new KeyArrayStringizer(); + + @Override + public String stringize(final Key[] keyArray) { + return KeyStringizer.STRINGIZER.join(keyArray); + } + } + + /** + * Convert the keyboard to human readable string. + * @param rows the keyboard to be converted to string. + * @return the human readable representation of rows. + */ + public static String toString(final Key[][] rows) { + return KeyArrayStringizer.STRINGIZER.join(rows, "\n" /* delimiter */); + } +}