Refactor currency and quotes keys tests

Bug: 13017434
Change-Id: I38dff3c8b9b28eff4397c7cdbad623fb43cbc312
This commit is contained in:
Tadashi G. Takaoka 2014-03-08 00:29:20 +09:00
parent 89dbd056d1
commit f247b171ce
9 changed files with 235 additions and 172 deletions

View file

@ -28,13 +28,12 @@ import java.util.Locale;
* The generic upper case alphabet keyboard layout. * The generic upper case alphabet keyboard layout.
*/ */
public final class AlphabetShifted extends LayoutBase { public final class AlphabetShifted extends LayoutBase {
public static ExpectedKey[][] getAlphabet(final ExpectedKey[][] lowerCaseKeyboard, public static ExpectedKey[][] getDefaultLayout(final ExpectedKey[][] lowerCaseKeyboard,
final Locale locale) { final Locale locale) {
final ExpectedKey[][] upperCaseKeyboard = ExpectedKeyboardBuilder.toUpperCase( final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(lowerCaseKeyboard);
lowerCaseKeyboard, locale); builder.toUpperCase(locale);
return new ExpectedKeyboardBuilder(upperCaseKeyboard) builder.replaceKeysOfAll(SHIFT_KEY, SHIFTED_SHIFT_KEY);
.replaceKeyOfAll(SHIFT_KEY, SHIFTED_SHIFT_KEY) return builder.build();
.build();
} }
// Icon id. // Icon id.

View file

@ -24,7 +24,7 @@ import com.android.inputmethod.keyboard.layout.expected.LayoutBase;
* The QWERTY alphabet keyboard. * The QWERTY alphabet keyboard.
*/ */
public final class Qwerty extends LayoutBase { public final class Qwerty extends LayoutBase {
public static ExpectedKey[][] getAlphabet(final boolean isPhone) { public static ExpectedKey[][] getLayout(final boolean isPhone) {
return toCommonAlphabet(ALPHABET_COMMON, isPhone); return toCommonAlphabet(ALPHABET_COMMON, isPhone);
} }

View file

@ -25,15 +25,88 @@ import com.android.inputmethod.latin.Constants;
* The symbols keyboard layout. * The symbols keyboard layout.
*/ */
public final class Symbols extends LayoutBase { public final class Symbols extends LayoutBase {
public static ExpectedKey[][] getSymbols(final boolean isPhone) { public static ExpectedKey[][] getLayout(final boolean isPhone) {
return isPhone ? toPhoneSymbol(SYMBOLS_COMMON) : toTabletSymbols(SYMBOLS_COMMON); return isPhone ? toPhoneSymbol(SYMBOLS_COMMON) : toTabletSymbols(SYMBOLS_COMMON);
} }
public static ExpectedKey[][] getDefaultLayout(final boolean isPhone) {
final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(SYMBOLS_COMMON);
builder.replaceKeyOfLabel(CURRENCY, Symbols.CURRENCY_DOLLAR);
builder.replaceKeyOfLabel(DOUBLE_QUOTE,
key("\"", join(Symbols.DOUBLE_QUOTES_9LR, Symbols.DOUBLE_ANGLE_QUOTES_LR)));
builder.replaceKeyOfLabel(SINGLE_QUOTE,
key("'", join(Symbols.SINGLE_QUOTES_9LR, Symbols.SINGLE_ANGLE_QUOTES_LR)));
final ExpectedKey[][] symbolsCommon = builder.build();
return isPhone ? toPhoneSymbol(symbolsCommon) : toTabletSymbols(symbolsCommon);
}
// Functional keys. // Functional keys.
public static final ExpectedKey ALPHABET_KEY = key("ABC", Constants.CODE_SWITCH_ALPHA_SYMBOL); public static final ExpectedKey ALPHABET_KEY = key("ABC", Constants.CODE_SWITCH_ALPHA_SYMBOL);
public static final ExpectedKey SYMBOLS_SHIFT_KEY = key("= \\ <", Constants.CODE_SHIFT); public static final ExpectedKey SYMBOLS_SHIFT_KEY = key("= \\ <", Constants.CODE_SHIFT);
public static final ExpectedKey TABLET_SYMBOLS_SHIFT_KEY = key("~ [ <", Constants.CODE_SHIFT); public static final ExpectedKey TABLET_SYMBOLS_SHIFT_KEY = key("~ [ <", Constants.CODE_SHIFT);
// Variations of the "currency" key on the 2nd row.
public static final String CURRENCY = "currency";
// U+00A2: "¢" CENT SIGN
// U+00A3: "£" POUND SIGN
// U+00A5: "¥" YEN SIGN
// U+20AC: "" EURO SIGN
// U+20B1: "" PESO SIGN
public static final ExpectedKey DOLLAR_SIGN = key("$");
public static final ExpectedKey CENT_SIGN = key("\u00A2");
public static final ExpectedKey POUND_SIGN = key("\u00A3");
public static final ExpectedKey YEN_SIGN = key("\u00A5");
public static final ExpectedKey EURO_SIGN = key("\u20AC");
public static final ExpectedKey PESO_SIGN = key("\u20B1");
public static final ExpectedKey CURRENCY_DOLLAR = key("$",
CENT_SIGN, POUND_SIGN, EURO_SIGN, YEN_SIGN, PESO_SIGN);
public static final ExpectedKey CURRENCY_EURO = key("\u20AC",
CENT_SIGN, POUND_SIGN, DOLLAR_SIGN, YEN_SIGN, PESO_SIGN);
// Variations of the "double quote" key's "more keys" on the 3rd row.
public static final String DOUBLE_QUOTE = "double_quote";
// U+201C: "" LEFT DOUBLE QUOTATION MARK
// U+201D: "" RIGHT DOUBLE QUOTATION MARK
// U+201E: "" DOUBLE LOW-9 QUOTATION MARK
static final ExpectedKey DQUOTE_LEFT = key("\u201C");
static final ExpectedKey DQUOTE_RIGHT = key("\u201D");
static final ExpectedKey DQUOTE_LOW9 = key("\u201E");
public static ExpectedKey[] DOUBLE_QUOTES_9LR = { DQUOTE_LOW9, DQUOTE_LEFT, DQUOTE_RIGHT };
public static ExpectedKey[] DOUBLE_QUOTES_R9L = { DQUOTE_RIGHT, DQUOTE_LOW9, DQUOTE_LEFT };
public static ExpectedKey[] DOUBLE_QUOTES_L9R = { DQUOTE_LEFT, DQUOTE_LOW9, DQUOTE_RIGHT };
public static ExpectedKey[] DOUBLE_QUOTES_LR9 = { DQUOTE_LEFT, DQUOTE_RIGHT, DQUOTE_LOW9 };
// U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
// U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
private static final ExpectedKey DAQUOTE_LEFT = key("\u00AB");
private static final ExpectedKey DAQUOTE_RIGHT = key("\u00BB");
private static final ExpectedKey DAQUOTE_LEFT_RTL = key("\u00AB", "\u00BB");
private static final ExpectedKey DAQUOTE_RIGHT_RTL = key("\u00BB", "\u00AB");
public static ExpectedKey[] DOUBLE_ANGLE_QUOTES_LR = { DAQUOTE_LEFT, DAQUOTE_RIGHT };
public static ExpectedKey[] DOUBLE_ANGLE_QUOTES_RL = { DAQUOTE_RIGHT, DAQUOTE_LEFT };
public static ExpectedKey[] DOUBLE_ANGLE_QUOTES_RTL = { DAQUOTE_LEFT_RTL, DAQUOTE_RIGHT_RTL };
// Variations of the "single quote" key's "more keys" on the 3rd row.
public static final String SINGLE_QUOTE = "single_quote";
// U+2018: "" LEFT SINGLE QUOTATION MARK
// U+2019: "" RIGHT SINGLE QUOTATION MARK
// U+201A: "" SINGLE LOW-9 QUOTATION MARK
static final ExpectedKey SQUOTE_LEFT = key("\u2018");
static final ExpectedKey SQUOTE_RIGHT = key("\u2019");
static final ExpectedKey SQUOTE_LOW9 = key("\u201A");
public static ExpectedKey[] SINGLE_QUOTES_9LR = { SQUOTE_LOW9, SQUOTE_LEFT, SQUOTE_RIGHT };
public static ExpectedKey[] SINGLE_QUOTES_R9L = { SQUOTE_RIGHT, SQUOTE_LOW9, SQUOTE_LEFT };
public static ExpectedKey[] SINGLE_QUOTES_L9R = { SQUOTE_LEFT, SQUOTE_LOW9, SQUOTE_RIGHT };
public static ExpectedKey[] SINGLE_QUOTES_LR9 = { SQUOTE_LEFT, SQUOTE_RIGHT, SQUOTE_LOW9 };
// U+2039: "" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
// U+203A: "" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
private static final ExpectedKey SAQUOTE_LEFT = key("\u2039");
private static final ExpectedKey SAQUOTE_RIGHT = key("\u203A");
private static final ExpectedKey SAQUOTE_LEFT_RTL = key("\u2039", "\u203A");
private static final ExpectedKey SAQUOTE_RIGHT_RTL = key("\u203A", "\u2039");
public static ExpectedKey[] SINGLE_ANGLE_QUOTES_LR = { SAQUOTE_LEFT, SAQUOTE_RIGHT };
public static ExpectedKey[] SINGLE_ANGLE_QUOTES_RL = { SAQUOTE_RIGHT, SAQUOTE_LEFT };
public static ExpectedKey[] SINGLE_ANGLE_QUOTES_RTL = { SAQUOTE_LEFT_RTL, SAQUOTE_RIGHT_RTL };
// Common symbols keyboard layout. // Common symbols keyboard layout.
public static final ExpectedKey[][] SYMBOLS_COMMON = new ExpectedKeyboardBuilder(10, 9, 7, 5) public static final ExpectedKey[][] SYMBOLS_COMMON = new ExpectedKeyboardBuilder(10, 9, 7, 5)
.setLabelsOfRow(1, "1", "2", "3", "4", "5", "6", "7", "8", "9", "0") .setLabelsOfRow(1, "1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
@ -59,13 +132,7 @@ public final class Symbols extends LayoutBase {
// U+207F: "" SUPERSCRIPT LATIN SMALL LETTER N // U+207F: "" SUPERSCRIPT LATIN SMALL LETTER N
// U+2205: "" EMPTY SET // U+2205: "" EMPTY SET
.setMoreKeysOf("0", "\u207F", "\u2205") .setMoreKeysOf("0", "\u207F", "\u2205")
.setLabelsOfRow(2, "@", "#", "$", "%", "&", "-", "+", "(", ")") .setLabelsOfRow(2, "@", "#", CURRENCY, "%", "&", "-", "+", "(", ")")
// U+00A2: "¢" CENT SIGN
// U+00A3: "£" POUND SIGN
// U+20AC: "" EURO SIGN
// U+00A5: "¥" YEN SIGN
// U+20B1: "" PESO SIGN
.setMoreKeysOf("$", "\u00A2", "\u00A3", "\u20AC", "\u00A5", "\u20B1")
// U+2030: "" PER MILLE SIGN // U+2030: "" PER MILLE SIGN
.setMoreKeysOf("%", "\u2030") .setMoreKeysOf("%", "\u2030")
// U+2013: "" EN DASH // U+2013: "" EN DASH
@ -76,23 +143,11 @@ public final class Symbols extends LayoutBase {
.setMoreKeysOf("+", "\u00B1") .setMoreKeysOf("+", "\u00B1")
.setMoreKeysOf("(", "<", "{", "[") .setMoreKeysOf("(", "<", "{", "[")
.setMoreKeysOf(")", ">", "}", "]") .setMoreKeysOf(")", ">", "}", "]")
.setLabelsOfRow(3, "*", "\"", "'", ":", ";", "!", "?") .setLabelsOfRow(3, "*", DOUBLE_QUOTE, SINGLE_QUOTE, ":", ";", "!", "?")
// U+2020: "" DAGGER // U+2020: "" DAGGER
// U+2021: "" DOUBLE DAGGER // U+2021: "" DOUBLE DAGGER
// U+2605: "" BLACK STAR // U+2605: "" BLACK STAR
.setMoreKeysOf("*", "\u2020", "\u2021", "\u2605") .setMoreKeysOf("*", "\u2020", "\u2021", "\u2605")
// U+201E: "" DOUBLE LOW-9 QUOTATION MARK
// U+201C: "" LEFT DOUBLE QUOTATION MARK
// U+201D: "" RIGHT DOUBLE QUOTATION MARK
// U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
// U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
.setMoreKeysOf("\"", "\u201E", "\u201C", "\u201D", "\u00AB", "\u00BB")
// U+201A: "" SINGLE LOW-9 QUOTATION MARK
// U+2018: "" LEFT SINGLE QUOTATION MARK
// U+2019: "" RIGHT SINGLE QUOTATION MARK
// U+2039: "" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
// U+203A: "" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
.setMoreKeysOf("'", "\u201A", "\u2018", "\u2019", "\u2039", "\u203A")
// U+00A1: "¡" INVERTED EXCLAMATION MARK // U+00A1: "¡" INVERTED EXCLAMATION MARK
.setMoreKeysOf("!", "\u00A1") .setMoreKeysOf("!", "\u00A1")
// U+00BF: "¿" INVERTED QUESTION MARK // U+00BF: "¿" INVERTED QUESTION MARK
@ -123,65 +178,4 @@ public final class Symbols extends LayoutBase {
.addKeysOnTheRightOfRow(4, EMOJI_KEY) .addKeysOnTheRightOfRow(4, EMOJI_KEY)
.build(); .build();
} }
// Helper method to add currency symbols for Euro.
public static ExpectedKeyboardBuilder euro(final ExpectedKeyboardBuilder builder) {
return builder
// U+20AC: "" EURO SIGN
// U+00A2: "¢" CENT SIGN
// U+00A3: "£" POUND SIGN
// U+00A5: "¥" YEN SIGN
// U+20B1: "" PESO SIGN
.replaceKeyOfLabel("$", key("\u20AC",
moreKey("\u00A2"), moreKey("\u00A3"), moreKey("$"),
moreKey("\u00A5"), moreKey("\u20B1")));
}
// Helper method to add single quotes "more keys".
// "9LLR" means "9-low/Left quotation marks, Left/Right-pointing angle quotation marks".
public static ExpectedKeyboardBuilder singleQuotes9LLR(final ExpectedKeyboardBuilder builder) {
return builder
// U+2019: "" RIGHT SINGLE QUOTATION MARK
// U+201A: "" SINGLE LOW-9 QUOTATION MARK
// U+2018: "" LEFT SINGLE QUOTATION MARK
// U+2039: "" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
// U+203A: "" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
.setMoreKeysOf("'", "\u2019", "\u201A", "\u2018", "\u2039", "\u203A");
}
// Helper method to add single quotes "more keys".
// "9LLR" means "9-low/Left quotation marks, Right/Left-pointing angle quotation marks".
public static ExpectedKeyboardBuilder singleQuotes9LRL(final ExpectedKeyboardBuilder builder) {
return builder
// U+2019: "" RIGHT SINGLE QUOTATION MARK
// U+201A: "" SINGLE LOW-9 QUOTATION MARK
// U+2018: "" LEFT SINGLE QUOTATION MARK
// U+203A: "" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
// U+2039: "" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
.setMoreKeysOf("'", "\u2019", "\u201A", "\u2018", "\u203A", "\u2039");
}
// Helper method to add double quotes "more keys".
// "9LLR" means "9-low/Left quotation marks, Left/Right-pointing angle quotation marks".
public static ExpectedKeyboardBuilder doubleQuotes9LLR(final ExpectedKeyboardBuilder builder) {
return builder
// U+201D: "" RIGHT DOUBLE QUOTATION MARK
// U+201E: "" DOUBLE LOW-9 QUOTATION MARK
// U+201C: "" LEFT DOUBLE QUOTATION MARK
// U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
// U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
.setMoreKeysOf("\"", "\u201D", "\u201E", "\u201C", "\u00AB", "\u00BB");
}
// Helper method to add double quotes "more keys".
// "9LLR" means "9-low/Left quotation marks, Right/Left-pointing angle quotation marks".
public static ExpectedKeyboardBuilder doubleQuotes9LRL(final ExpectedKeyboardBuilder builder) {
return builder
// U+201D: "" RIGHT DOUBLE QUOTATION MARK
// U+201E: "" DOUBLE LOW-9 QUOTATION MARK
// U+201C: "" LEFT DOUBLE QUOTATION MARK
// U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
// U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
.setMoreKeysOf("\"", "\u201D", "\u201E", "\u201C", "\u00BB", "\u00AB");
}
} }

View file

@ -25,17 +25,35 @@ import com.android.inputmethod.latin.Constants;
* The symbols shifted keyboard layout. * The symbols shifted keyboard layout.
*/ */
public final class SymbolsShifted extends LayoutBase { public final class SymbolsShifted extends LayoutBase {
public static ExpectedKey[][] getSymbolsShifted(final boolean isPhone) { public static ExpectedKey[][] getLayout(final boolean isPhone) {
return isPhone ? toPhoneSymbolsShifted(SYMBOLS_SHIFTED_COMMON) return isPhone ? toPhoneSymbolsShifted(SYMBOLS_SHIFTED_COMMON)
: toTabletSymbolsShifted(SYMBOLS_SHIFTED_COMMON); : toTabletSymbolsShifted(SYMBOLS_SHIFTED_COMMON);
} }
public static ExpectedKey[][] getDefaultLayout(final boolean isPhone) {
final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(SYMBOLS_SHIFTED_COMMON);
builder.replaceKeyOfLabel(OTHER_CURRENCIES, SymbolsShifted.CURRENCIES_OTHER_THAN_DOLLAR);
final ExpectedKey[][] symbolsShiftedCommon = builder.build();
return isPhone ? toPhoneSymbolsShifted(symbolsShiftedCommon)
: toTabletSymbolsShifted(symbolsShiftedCommon);
}
// Functional key. // Functional key.
public static final ExpectedKey BACK_TO_SYMBOLS_KEY = key("?123", Constants.CODE_SHIFT); public static final ExpectedKey BACK_TO_SYMBOLS_KEY = key("?123", Constants.CODE_SHIFT);
// Variations of the "other currencies" keys on the 2rd row.
public static final String OTHER_CURRENCIES = "other_currencies";
public static final ExpectedKey[] CURRENCIES_OTHER_THAN_DOLLAR = {
Symbols.POUND_SIGN, Symbols.CENT_SIGN, Symbols.EURO_SIGN, Symbols.YEN_SIGN
};
public static final ExpectedKey[] CURRENCIES_OTHER_THAN_EURO = {
Symbols.POUND_SIGN, Symbols.YEN_SIGN, key(Symbols.DOLLAR_SIGN, Symbols.CENT_SIGN),
Symbols.CENT_SIGN
};
// Common symbols shifted keyboard layout. // Common symbols shifted keyboard layout.
public static final ExpectedKey[][] SYMBOLS_SHIFTED_COMMON = public static final ExpectedKey[][] SYMBOLS_SHIFTED_COMMON =
new ExpectedKeyboardBuilder(10, 9, 7, 5) new ExpectedKeyboardBuilder(10, 1 /* other_currencies */ + 5, 7, 5)
// U+0060: "`" GRAVE ACCENT // U+0060: "`" GRAVE ACCENT
// U+2022: "" BULLET // U+2022: "" BULLET
// U+221A: "" SQUARE ROOT // U+221A: "" SQUARE ROOT
@ -60,14 +78,8 @@ public final class SymbolsShifted extends LayoutBase {
// U+00B6: "" PILCROW SIGN // U+00B6: "" PILCROW SIGN
// U+00A7: "§" SECTION SIGN // U+00A7: "§" SECTION SIGN
.setMoreKeysOf("\u00B6", "\u00A7") .setMoreKeysOf("\u00B6", "\u00A7")
// U+00A3: "£" POUND SIGN
// U+00A2: "¢" CENT SIGN
// U+20AC: "" EURO SIGN
// U+00A5: "¥" YEN SIGN
// U+00B0: "°" DEGREE SIGN // U+00B0: "°" DEGREE SIGN
.setLabelsOfRow(2, .setLabelsOfRow(2, OTHER_CURRENCIES, "^", "\u00B0", "=", "{", "}")
"\u00A3", "\u00A2", "\u20AC", "\u00A5", "^",
"\u00B0", "=", "{", "}")
// U+2191: "" UPWARDS ARROW // U+2191: "" UPWARDS ARROW
// U+2193: "" DOWNWARDS ARROW // U+2193: "" DOWNWARDS ARROW
// U+2190: "" LEFTWARDS ARROW // U+2190: "" LEFTWARDS ARROW
@ -125,18 +137,4 @@ public final class SymbolsShifted extends LayoutBase {
.addKeysOnTheRightOfRow(4, EMOJI_KEY) .addKeysOnTheRightOfRow(4, EMOJI_KEY)
.build(); .build();
} }
// Helper method to add currency symbols for Euro.
public static ExpectedKeyboardBuilder euro(final ExpectedKeyboardBuilder builder) {
return builder
// U+00A5: "¥" YEN SIGN
// U+00A2: "¢" CENT SIGN
.replaceKeyOfLabel("\u00A5", key("\u00A2"))
// U+20AC: "" EURO SIGN
// U+00A2: "¢" CENT SIGN
.replaceKeyOfLabel("\u20AC", key("$", moreKey("\u00A2")))
// U+00A2: "¢" CENT SIGN
// U+00A5: "¥" YEN SIGN
.replaceKeyOfLabel("\u00A2", key("\u00A5"));
}
} }

View file

@ -72,6 +72,14 @@ abstract class AbstractKeyboardBuilder<E> {
return mRows; return mRows;
} }
/**
* Return the number of rows.
* @return the number of rows being constructed.
*/
int getRowCount() {
return mRows.length;
}
/** /**
* Get the current contents of the specified row. * Get the current contents of the specified row.
* @param row the row number to get the contents. * @param row the row number to get the contents.

View file

@ -52,32 +52,56 @@ public final class ExpectedKeyboardBuilder extends AbstractKeyboardBuilder<Expec
} }
// A replacement job to be performed. // A replacement job to be performed.
interface ReplaceJob { private interface ReplaceJob {
// Returns a {@link ExpectedKey} object to replace. // Returns a {@link ExpectedKey} objects to replace.
ExpectedKey replace(final ExpectedKey oldKey); ExpectedKey[] replacingKeys(final ExpectedKey oldKey);
// Return true if replacing should be stopped at first occurrence. // Return true if replacing should be stopped at first occurrence.
boolean stopAtFirstOccurrence(); boolean stopAtFirstOccurrence();
} }
private static ExpectedKey[] replaceKeyAt(final ExpectedKey[] keys, final int columnIndex,
final ExpectedKey[] replacingKeys) {
// Optimization for replacing a key with another key.
if (replacingKeys.length == 1) {
keys[columnIndex] = replacingKeys[0];
return keys;
}
final int newLength = keys.length - 1 + replacingKeys.length;
// Remove the key at columnIndex.
final ExpectedKey[] newKeys = Arrays.copyOf(keys, newLength);
System.arraycopy(keys, columnIndex + 1, newKeys, columnIndex + replacingKeys.length,
keys.length - 1 - columnIndex);
// Insert replacing keys at columnIndex.
System.arraycopy(replacingKeys, 0, newKeys, columnIndex, replacingKeys.length);
return newKeys;
}
// Replace key(s) that has the specified visual. // Replace key(s) that has the specified visual.
private void replaceKeyOf(final ExpectedKeyVisual visual, final ReplaceJob job) { private void replaceKeyOf(final ExpectedKeyVisual visual, final ReplaceJob job) {
int replacedCount = 0; int replacedCount = 0;
final ExpectedKey[][] rows = build(); final int rowCount = getRowCount();
for (int rowIndex = 0; rowIndex < rows.length; rowIndex++) { for (int row = 1; row <= rowCount; row++) {
final ExpectedKey[] keys = rows[rowIndex]; ExpectedKey[] keys = getRowAt(row);
for (int columnIndex = 0; columnIndex < keys.length; columnIndex++) { for (int columnIndex = 0; columnIndex < keys.length; /* nothing */) {
if (keys[columnIndex].getVisual().equalsTo(visual)) { final ExpectedKey currentKey = keys[columnIndex];
keys[columnIndex] = job.replace(keys[columnIndex]); if (!currentKey.getVisual().equalsTo(visual)) {
replacedCount++; columnIndex++;
if (job.stopAtFirstOccurrence()) { continue;
return; }
} final ExpectedKey[] replacingKeys = job.replacingKeys(currentKey);
keys = replaceKeyAt(keys, columnIndex, replacingKeys);
columnIndex += replacingKeys.length;
setRowAt(row, keys);
replacedCount++;
if (job.stopAtFirstOccurrence()) {
return;
} }
} }
} }
if (replacedCount == 0) { if (replacedCount == 0) {
throw new RuntimeException( throw new RuntimeException(
"Can't find key that has visual: " + visual + " in\n" + toString(rows)); "Can't find key that has visual: " + visual + " in\n" + this);
} }
} }
@ -137,8 +161,10 @@ public final class ExpectedKeyboardBuilder extends AbstractKeyboardBuilder<Expec
private void setMoreKeysOf(final ExpectedKeyVisual visual, final ExpectedKey[] moreKeys) { private void setMoreKeysOf(final ExpectedKeyVisual visual, final ExpectedKey[] moreKeys) {
replaceKeyOf(visual, new ReplaceJob() { replaceKeyOf(visual, new ReplaceJob() {
@Override @Override
public ExpectedKey replace(final ExpectedKey oldKey) { public ExpectedKey[] replacingKeys(final ExpectedKey oldKey) {
return ExpectedKey.newInstance(oldKey.getVisual(), oldKey.getOutput(), moreKeys); return new ExpectedKey[] {
ExpectedKey.newInstance(oldKey.getVisual(), oldKey.getOutput(), moreKeys)
};
} }
@Override @Override
public boolean stopAtFirstOccurrence() { public boolean stopAtFirstOccurrence() {
@ -194,17 +220,18 @@ public final class ExpectedKeyboardBuilder extends AbstractKeyboardBuilder<Expec
} }
/** /**
* Replace the most top-left key that has the specified label with the new key. * Replace the most top-left key that has the specified label with the new keys.
* @param label the label of the key to set <code>newKey</code>. * @param label the label of the key to set <code>newKeys</code>.
* @param newKey the key to be set. * @param newKeys the keys to be set.
* @return this builder. * @return this builder.
*/ */
public ExpectedKeyboardBuilder replaceKeyOfLabel(final String label, final ExpectedKey newKey) { public ExpectedKeyboardBuilder replaceKeyOfLabel(final String label,
final ExpectedKey ... newKeys) {
final ExpectedKeyVisual visual = ExpectedKeyVisual.newInstance(label); final ExpectedKeyVisual visual = ExpectedKeyVisual.newInstance(label);
replaceKeyOf(visual, new ReplaceJob() { replaceKeyOf(visual, new ReplaceJob() {
@Override @Override
public ExpectedKey replace(final ExpectedKey oldKey) { public ExpectedKey[] replacingKeys(final ExpectedKey oldKey) {
return newKey; return newKeys;
} }
@Override @Override
public boolean stopAtFirstOccurrence() { public boolean stopAtFirstOccurrence() {
@ -215,17 +242,17 @@ public final class ExpectedKeyboardBuilder extends AbstractKeyboardBuilder<Expec
} }
/** /**
* Replace the all specified keys with the new key. * Replace the all specified keys with the new keys.
* @param key the key to be replaced by <code>newKey</code>. * @param key the key to be replaced by <code>newKeys</code>.
* @param newKey the key to be set. * @param newKeys the keys to be set.
* @return this builder. * @return this builder.
*/ */
public ExpectedKeyboardBuilder replaceKeyOfAll(final ExpectedKey key, public ExpectedKeyboardBuilder replaceKeysOfAll(final ExpectedKey key,
final ExpectedKey newKey) { final ExpectedKey ... newKeys) {
replaceKeyOf(key.getVisual(), new ReplaceJob() { replaceKeyOf(key.getVisual(), new ReplaceJob() {
@Override @Override
public ExpectedKey replace(final ExpectedKey oldKey) { public ExpectedKey[] replacingKeys(final ExpectedKey oldKey) {
return newKey; return newKeys;
} }
@Override @Override
public boolean stopAtFirstOccurrence() { public boolean stopAtFirstOccurrence() {
@ -236,22 +263,26 @@ public final class ExpectedKeyboardBuilder extends AbstractKeyboardBuilder<Expec
} }
/** /**
* Returns new keyboard instance that has upper case keys of the specified keyboard. * Convert all keys of this keyboard builder to upper case keys.
* @param rows the lower case keyboard.
* @param locale the locale used to convert cases. * @param locale the locale used to convert cases.
* @return the upper case keyboard. * @return this builder
*/ */
public static ExpectedKey[][] toUpperCase(final ExpectedKey[][] rows, final Locale locale) { public ExpectedKeyboardBuilder toUpperCase(final Locale locale) {
final ExpectedKey[][] upperCaseRows = new ExpectedKey[rows.length][]; final int rowCount = getRowCount();
for (int rowIndex = 0; rowIndex < rows.length; rowIndex++) { for (int row = 1; row <= rowCount; row++) {
final ExpectedKey[] lowerCaseKeys = rows[rowIndex]; final ExpectedKey[] lowerCaseKeys = getRowAt(row);
final ExpectedKey[] upperCaseKeys = new ExpectedKey[lowerCaseKeys.length]; final ExpectedKey[] upperCaseKeys = new ExpectedKey[lowerCaseKeys.length];
for (int columnIndex = 0; columnIndex < lowerCaseKeys.length; columnIndex++) { for (int columnIndex = 0; columnIndex < lowerCaseKeys.length; columnIndex++) {
upperCaseKeys[columnIndex] = lowerCaseKeys[columnIndex].toUpperCase(locale); upperCaseKeys[columnIndex] = lowerCaseKeys[columnIndex].toUpperCase(locale);
} }
upperCaseRows[rowIndex] = upperCaseKeys; setRowAt(row, upperCaseKeys);
} }
return upperCaseRows; return this;
}
@Override
public String toString() {
return toString(build());
} }
/** /**

View file

@ -18,6 +18,10 @@ package com.android.inputmethod.keyboard.layout.expected;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.utils.CollectionUtils;
import java.util.ArrayList;
import java.util.Arrays;
/** /**
* Base class to create an expected keyboard for unit test. * Base class to create an expected keyboard for unit test.
@ -71,6 +75,24 @@ public class LayoutBase {
return ExpectedKey.newInstance(label, code); return ExpectedKey.newInstance(label, code);
} }
// Helper method to create {@link ExpectedKey} array by joining {@link ExpectedKey},
// {@link ExpectedKey} array, and {@link String}.
public static ExpectedKey[] join(final Object ... keys) {
final ArrayList<ExpectedKey> list = CollectionUtils.newArrayList();
for (final Object key : keys) {
if (key instanceof ExpectedKey) {
list.add((ExpectedKey)key);
} else if (key instanceof ExpectedKey[]) {
list.addAll(Arrays.asList((ExpectedKey[])key));
} else if (key instanceof String) {
list.add(key((String)key));
} else {
throw new RuntimeException("Unknown expected key type: " + key);
}
}
return list.toArray(new ExpectedKey[list.size()]);
}
// Icon ids. // Icon ids.
private static final int ICON_SHIFT = KeyboardIconsSet.getIconId("shift_key"); private static final int ICON_SHIFT = KeyboardIconsSet.getIconId("shift_key");
private static final int ICON_DELETE = KeyboardIconsSet.getIconId("delete_key"); private static final int ICON_DELETE = KeyboardIconsSet.getIconId("delete_key");

View file

@ -68,6 +68,11 @@ abstract class LayoutTestsBase extends KeyboardLayoutSetTestsBase {
return LayoutBase.key(label, outputText, moreKeys); return LayoutBase.key(label, outputText, moreKeys);
} }
// Helper method to create {@link ExpectedKey} object that has new "more keys".
static ExpectedKey key(final ExpectedKey key, final ExpectedKey ... moreKeys) {
return LayoutBase.key(key, moreKeys);
}
// Helper method to create {@link ExpectedKey} object for "more key" that has the label. // Helper method to create {@link ExpectedKey} object for "more key" that has the label.
static ExpectedKey moreKey(final String label) { static ExpectedKey moreKey(final String label) {
return LayoutBase.moreKey(label); return LayoutBase.moreKey(label);
@ -79,6 +84,12 @@ abstract class LayoutTestsBase extends KeyboardLayoutSetTestsBase {
return LayoutBase.moreKey(label, outputText); return LayoutBase.moreKey(label, outputText);
} }
// Helper method to create {@link ExpectedKey} array by joining {@link ExpectedKey},
// {@link ExpectedKey} array, and {@link String}.
static ExpectedKey[] join(final Object ... keys) {
return LayoutBase.join(keys);
}
// Locale for testing subtype. // Locale for testing subtype.
abstract Locale getTestLocale(); abstract Locale getTestLocale();
@ -86,73 +97,73 @@ abstract class LayoutTestsBase extends KeyboardLayoutSetTestsBase {
abstract String getTestKeyboardLayout(); abstract String getTestKeyboardLayout();
// Alphabet keyboard for testing subtype. // Alphabet keyboard for testing subtype.
abstract ExpectedKey[][] getAlphabet(final boolean isPhone); abstract ExpectedKey[][] getAlphabetLayout(final boolean isPhone);
// Alphabet automatic shifted keyboard for testing subtype. // Alphabet automatic shifted keyboard for testing subtype.
ExpectedKey[][] getAlphabetAutomaticShifted(final boolean isPhone) { ExpectedKey[][] getAlphabetAutomaticShiftedLayout(final boolean isPhone) {
return AlphabetShifted.getAlphabet(getAlphabet(isPhone), getTestLocale()); return AlphabetShifted.getDefaultLayout(getAlphabetLayout(isPhone), getTestLocale());
} }
// Alphabet manual shifted keyboard for testing subtype. // Alphabet manual shifted keyboard for testing subtype.
ExpectedKey[][] getAlphabetManualShifted(final boolean isPhone) { ExpectedKey[][] getAlphabetManualShiftedLayout(final boolean isPhone) {
return AlphabetShifted.getAlphabet(getAlphabet(isPhone), getTestLocale()); return AlphabetShifted.getDefaultLayout(getAlphabetLayout(isPhone), getTestLocale());
} }
// Alphabet shift locked keyboard for testing subtype. // Alphabet shift locked keyboard for testing subtype.
ExpectedKey[][] getAlphabetShiftLocked(final boolean isPhone) { ExpectedKey[][] getAlphabetShiftLockedLayout(final boolean isPhone) {
return AlphabetShifted.getAlphabet(getAlphabet(isPhone), getTestLocale()); return AlphabetShifted.getDefaultLayout(getAlphabetLayout(isPhone), getTestLocale());
} }
// Alphabet shift lock shifted keyboard for testing subtype. // Alphabet shift lock shifted keyboard for testing subtype.
ExpectedKey[][] getAlphabetShiftLockShifted(final boolean isPhone) { ExpectedKey[][] getAlphabetShiftLockShiftedLayout(final boolean isPhone) {
return AlphabetShifted.getAlphabet(getAlphabet(isPhone), getTestLocale()); return AlphabetShifted.getDefaultLayout(getAlphabetLayout(isPhone), getTestLocale());
} }
// Symbols keyboard for testing subtype. // Symbols keyboard for testing subtype.
ExpectedKey[][] getSymbols(final boolean isPhone) { ExpectedKey[][] getSymbolsLayout(final boolean isPhone) {
return Symbols.getSymbols(isPhone); return Symbols.getDefaultLayout(isPhone);
} }
// Symbols shifted keyboard for testing subtype. // Symbols shifted keyboard for testing subtype.
ExpectedKey[][] getSymbolsShifted(final boolean isPhone) { ExpectedKey[][] getSymbolsShiftedLayout(final boolean isPhone) {
return SymbolsShifted.getSymbolsShifted(isPhone); return SymbolsShifted.getDefaultLayout(isPhone);
} }
// TODO: Add phone, phone symbols, number, number password layout tests. // TODO: Add phone, phone symbols, number, number password layout tests.
public final void testAlphabet() { public final void testAlphabet() {
final int elementId = KeyboardId.ELEMENT_ALPHABET; final int elementId = KeyboardId.ELEMENT_ALPHABET;
doKeyboardTests(elementId, getAlphabet(isPhone())); doKeyboardTests(elementId, getAlphabetLayout(isPhone()));
} }
public final void testAlphabetAutomaticShifted() { public final void testAlphabetAutomaticShifted() {
final int elementId = KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED; final int elementId = KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED;
doKeyboardTests(elementId, getAlphabetAutomaticShifted(isPhone())); doKeyboardTests(elementId, getAlphabetAutomaticShiftedLayout(isPhone()));
} }
public final void testAlphabetManualShifted() { public final void testAlphabetManualShifted() {
final int elementId = KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED; final int elementId = KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED;
doKeyboardTests(elementId, getAlphabetManualShifted(isPhone())); doKeyboardTests(elementId, getAlphabetManualShiftedLayout(isPhone()));
} }
public final void testAlphabetShiftLocked() { public final void testAlphabetShiftLocked() {
final int elementId = KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED; final int elementId = KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED;
doKeyboardTests(elementId, getAlphabetShiftLocked(isPhone())); doKeyboardTests(elementId, getAlphabetShiftLockedLayout(isPhone()));
} }
public final void testAlphabetShiftLockShifted() { public final void testAlphabetShiftLockShifted() {
final int elementId = KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED; final int elementId = KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED;
doKeyboardTests(elementId, getAlphabetShiftLockShifted(isPhone())); doKeyboardTests(elementId, getAlphabetShiftLockShiftedLayout(isPhone()));
} }
public final void testSymbols() { public final void testSymbols() {
final int elementId = KeyboardId.ELEMENT_SYMBOLS; final int elementId = KeyboardId.ELEMENT_SYMBOLS;
doKeyboardTests(elementId, getSymbols(isPhone())); doKeyboardTests(elementId, getSymbolsLayout(isPhone()));
} }
public final void testSymbolsShifted() { public final void testSymbolsShifted() {
final int elementId = KeyboardId.ELEMENT_SYMBOLS_SHIFTED; final int elementId = KeyboardId.ELEMENT_SYMBOLS_SHIFTED;
doKeyboardTests(elementId, getSymbolsShifted(isPhone())); doKeyboardTests(elementId, getSymbolsShiftedLayout(isPhone()));
} }
// Comparing expected keyboard and actual keyboard. // Comparing expected keyboard and actual keyboard.

View file

@ -40,8 +40,8 @@ public final class TestsEnglishUS extends LayoutTestsBase {
} }
@Override @Override
ExpectedKey[][] getAlphabet(final boolean isPhone) { ExpectedKey[][] getAlphabetLayout(final boolean isPhone) {
final ExpectedKey[][] keyboard = Qwerty.getAlphabet(isPhone); final ExpectedKey[][] keyboard = Qwerty.getLayout(isPhone);
final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(keyboard); final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(keyboard);
setAccentedLetters(builder); setAccentedLetters(builder);
return builder.build(); return builder.build();