Merge "Add ActualKeyboardBuilder for testing keyboard layouts"
commit
ad04ed5460
|
@ -507,4 +507,44 @@ public final class StringUtils {
|
||||||
return codePointCount(casedText) == 1
|
return codePointCount(casedText) == 1
|
||||||
? casedText.codePointAt(0) : CODE_UNSPECIFIED;
|
? casedText.codePointAt(0) : CODE_UNSPECIFIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UsedForTesting
|
||||||
|
public static class Stringizer<E> {
|
||||||
|
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 + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<Key> {
|
||||||
|
// Comparator to sort {@link Key}s from top-left to bottom-right order.
|
||||||
|
private static final Comparator<Key> ROW_COLUMN_COMPARATOR = new Comparator<Key>() {
|
||||||
|
@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<Key> sortedKeys = CollectionUtils.newArrayList(Arrays.asList(keys));
|
||||||
|
Collections.sort(sortedKeys, ROW_COLUMN_COMPARATOR);
|
||||||
|
|
||||||
|
// Grouping keys into rows.
|
||||||
|
final ArrayList<ArrayList<Key>> rows = CollectionUtils.newArrayList();
|
||||||
|
ArrayList<Key> 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<Key> 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<MoreKeySpec> {
|
||||||
|
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<Key> {
|
||||||
|
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 <code>key</code>.
|
||||||
|
*/
|
||||||
|
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 <code>keys</code>.
|
||||||
|
*/
|
||||||
|
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<Key[]> {
|
||||||
|
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 <code>rows</code>.
|
||||||
|
*/
|
||||||
|
public static String toString(final Key[][] rows) {
|
||||||
|
return KeyArrayStringizer.STRINGIZER.join(rows, "\n" /* delimiter */);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue