aboutsummaryrefslogtreecommitdiffstats
path: root/tests/src
diff options
context:
space:
mode:
Diffstat (limited to 'tests/src')
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/expected/AbstractKeyboardBuilder.java134
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKey.java186
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyOutput.java138
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyVisual.java135
-rw-r--r--tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyboardBuilder.java272
-rw-r--r--tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java7
-rw-r--r--tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java3
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java7
-rw-r--r--tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java6
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/EditDistanceTests.java (renamed from tests/src/com/android/inputmethod/latin/EditDistanceTests.java)20
10 files changed, 888 insertions, 20 deletions
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/AbstractKeyboardBuilder.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/AbstractKeyboardBuilder.java
new file mode 100644
index 000000000..45449b762
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/AbstractKeyboardBuilder.java
@@ -0,0 +1,134 @@
+/*
+ * 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 java.util.Arrays;
+
+/**
+ * This class builds a keyboard that is a two dimensional array of elements <code>E</code>.
+ *
+ * A keyboard consists of array of rows, and a row consists of array of elements. Each row may have
+ * different number of elements. A element of a keyboard can be specified by a row number and a
+ * column number, both numbers starts from 1.
+ *
+ * @param <E> the type of a keyboard element. A keyboard element must be an immutable object.
+ */
+abstract class AbstractKeyboardBuilder<E> {
+ // A building array of rows.
+ private final E[][] mRows;
+
+ // Returns an instance of default element.
+ abstract E defaultElement();
+ // Returns an <code>E</code> array instance of the <code>size</code>.
+ abstract E[] newArray(final int size);
+ // Returns an <code>E[]</code> array instance of the <code>size</code>.
+ abstract E[][] newArrayOfArray(final int size);
+
+ /**
+ * Construct a builder filled with the default element.
+ * @param dimensions the integer array of each row's size.
+ */
+ AbstractKeyboardBuilder(final int ... dimensions) {
+ mRows = newArrayOfArray(dimensions.length);
+ for (int rowIndex = 0; rowIndex < dimensions.length; rowIndex++) {
+ mRows[rowIndex] = newArray(dimensions[rowIndex]);
+ Arrays.fill(mRows[rowIndex], defaultElement());
+ }
+ }
+
+ /**
+ * Construct a builder from template keyboard. This builder has the same dimensions and
+ * elements of <code>rows</rows>.
+ * @param rows the template keyboard rows. The elements of the <code>rows</code> will be
+ * shared with this builder. Therefore a element must be an immutable object.
+ */
+ AbstractKeyboardBuilder(final E[][] rows) {
+ mRows = newArrayOfArray(rows.length);
+ for (int rowIndex = 0; rowIndex < rows.length; rowIndex++) {
+ final E[] row = rows[rowIndex];
+ mRows[rowIndex] = Arrays.copyOf(row, row.length);
+ }
+ }
+
+ /**
+ * Return current constructing keyboard.
+ * @return the array of the array of the element being constructed.
+ */
+ E[][] build() {
+ return mRows;
+ }
+
+ /**
+ * Get the current contents of the specified row.
+ * @param row the row number to get the contents.
+ * @return the array of elements at row number <code>row</code>.
+ * @throws {@link RuntimeException} if <code>row</code> is illegal.
+ */
+ E[] getRowAt(final int row) {
+ final int rowIndex = row - 1;
+ if (rowIndex < 0 || rowIndex >= mRows.length) {
+ throw new RuntimeException("Illegal row number: " + row);
+ }
+ return mRows[rowIndex];
+ }
+
+ /**
+ * Set an array of elements to the specified row.
+ * @param row the row number to set <code>elements</code>.
+ * @param elements the array of elements to set at row number <code>row</code>.
+ * @throws {@link RuntimeException} if <code>row</code> is illegal.
+ */
+ void setRowAt(final int row, final E[] elements) {
+ final int rowIndex = row - 1;
+ if (rowIndex < 0 || rowIndex >= mRows.length) {
+ throw new RuntimeException("Illegal row number: " + row);
+ }
+ mRows[rowIndex] = elements;
+ }
+
+ /**
+ * Set or insert an element at specified position.
+ * @param row the row number to set or insert the <code>element</code>.
+ * @param column the column number to set or insert the <code>element</code>.
+ * @param element the element to set or insert at <code>row,column</code>.
+ * @param insert if true, the <code>element</code> is inserted at <code>row,column</code>.
+ * Otherwise the <code>element</code> replace the element at <code>row,column</code>.
+ * @throws {@link RuntimeException} if <code>row</code> or <code>column</code> is illegal.
+ */
+ void setElementAt(final int row, final int column, final E element, final boolean insert) {
+ final E[] elements = getRowAt(row);
+ final int columnIndex = column - 1;
+ if (insert) {
+ if (columnIndex < 0 || columnIndex >= elements.length + 1) {
+ throw new RuntimeException("Illegal column number: " + column);
+ }
+ final E[] newElements = Arrays.copyOf(elements, elements.length + 1);
+ // Shift the remaining elements.
+ System.arraycopy(newElements, columnIndex, newElements, columnIndex + 1,
+ elements.length - columnIndex);
+ // Insert the element at <code>row,column</code>.
+ newElements[columnIndex] = element;
+ // Replace the current row with one.
+ setRowAt(row, newElements);
+ return;
+ }
+ if (columnIndex < 0 || columnIndex >= elements.length) {
+ throw new RuntimeException("Illegal column number: " + column);
+ }
+ elements[columnIndex] = element;
+ }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKey.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKey.java
new file mode 100644
index 000000000..e22d75cd7
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKey.java
@@ -0,0 +1,186 @@
+/*
+ * 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.MoreKeySpec;
+
+import java.util.Arrays;
+import java.util.Locale;
+
+/**
+ * This class represents an expected key.
+ */
+public class ExpectedKey {
+ static ExpectedKey EMPTY_KEY = newInstance("");
+
+ // A key that has a string label and may have "more keys".
+ static ExpectedKey newInstance(final String label, final ExpectedKey ... moreKeys) {
+ return newInstance(label, label, moreKeys);
+ }
+
+ // A key that has a string label and a different output text and may have "more keys".
+ static ExpectedKey newInstance(final String label, final String outputText,
+ final ExpectedKey ... moreKeys) {
+ return newInstance(ExpectedKeyVisual.newInstance(label),
+ ExpectedKeyOutput.newInstance(outputText), moreKeys);
+ }
+
+ // A key that has a string label and a code point output and may have "more keys".
+ static ExpectedKey newInstance(final String label, final int code,
+ final ExpectedKey ... moreKeys) {
+ return newInstance(ExpectedKeyVisual.newInstance(label),
+ ExpectedKeyOutput.newInstance(code), moreKeys);
+ }
+
+ // A key that has an icon and a code point output and may have "more keys".
+ static ExpectedKey newInstance(final int iconId, final int code,
+ final ExpectedKey ... moreKeys) {
+ return newInstance(ExpectedKeyVisual.newInstance(iconId),
+ ExpectedKeyOutput.newInstance(code), moreKeys);
+ }
+
+ static ExpectedKey newInstance(final ExpectedKeyVisual visual, final ExpectedKeyOutput output,
+ final ExpectedKey ... moreKeys) {
+ if (moreKeys.length == 0) {
+ return new ExpectedKey(visual, output);
+ }
+ return new ExpectedKeyWithMoreKeys(visual, output, moreKeys);
+ }
+
+ private static final ExpectedKey[] EMPTY_KEYS = new ExpectedKey[0];
+
+ // The expected visual outlook of this key.
+ private final ExpectedKeyVisual mVisual;
+ // The expected output of this key.
+ private final ExpectedKeyOutput mOutput;
+
+ public final ExpectedKeyVisual getVisual() {
+ return mVisual;
+ }
+
+ public final ExpectedKeyOutput getOutput() {
+ return mOutput;
+ }
+
+ public ExpectedKey[] getMoreKeys() {
+ // This key has no "more keys".
+ return EMPTY_KEYS;
+ }
+
+ protected ExpectedKey(final ExpectedKeyVisual visual, final ExpectedKeyOutput output) {
+ mVisual = visual;
+ mOutput = output;
+ }
+
+ public ExpectedKey toUpperCase(Locale locale) {
+ return newInstance(mVisual.toUpperCase(locale), mOutput.toUpperCase(locale));
+ }
+
+ public boolean equalsTo(final Key key) {
+ // This key has no "more keys".
+ return mVisual.equalsTo(key) && mOutput.equalsTo(key) && key.getMoreKeys() == null;
+ }
+
+ public boolean equalsTo(final MoreKeySpec moreKeySpec) {
+ return mVisual.equalsTo(moreKeySpec) && mOutput.equalsTo(moreKeySpec);
+ }
+
+ @Override
+ public boolean equals(final Object object) {
+ if (object instanceof ExpectedKey) {
+ final ExpectedKey key = (ExpectedKey)object;
+ return mVisual.equalsTo(key.mVisual) && mOutput.equalsTo(key.mOutput)
+ && Arrays.equals(getMoreKeys(), key.getMoreKeys());
+ }
+ return false;
+ }
+
+ private static int hashCode(final Object ... objects) {
+ return Arrays.hashCode(objects);
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode(mVisual, mOutput, getMoreKeys());
+ }
+
+ @Override
+ public String toString() {
+ if (mVisual.equalsTo(mOutput)) {
+ return mVisual.toString();
+ }
+ return mVisual + "|" + mOutput;
+ }
+
+ /**
+ * This class represents an expected key that has "more keys".
+ */
+ private static final class ExpectedKeyWithMoreKeys extends ExpectedKey {
+ private final ExpectedKey[] mMoreKeys;
+
+ ExpectedKeyWithMoreKeys(final ExpectedKeyVisual visual,
+ final ExpectedKeyOutput output, final ExpectedKey ... moreKeys) {
+ super(visual, output);
+ mMoreKeys = moreKeys;
+ }
+
+ @Override
+ public ExpectedKey toUpperCase(final Locale locale) {
+ final ExpectedKey[] upperCaseMoreKeys = new ExpectedKey[mMoreKeys.length];
+ for (int i = 0; i < mMoreKeys.length; i++) {
+ upperCaseMoreKeys[i] = mMoreKeys[i].toUpperCase(locale);
+ }
+ return newInstance(getVisual().toUpperCase(locale), getOutput().toUpperCase(locale),
+ upperCaseMoreKeys);
+ }
+
+ @Override
+ public ExpectedKey[] getMoreKeys() {
+ return mMoreKeys;
+ }
+
+ @Override
+ public boolean equalsTo(final Key key) {
+ if (getVisual().equalsTo(key) && getOutput().equalsTo(key)) {
+ final MoreKeySpec[] moreKeys = key.getMoreKeys();
+ // This key should have at least one "more key".
+ if (moreKeys == null || moreKeys.length != mMoreKeys.length) {
+ return false;
+ }
+ for (int index = 0; index < moreKeys.length; index++) {
+ if (!mMoreKeys[index].equalsTo(moreKeys[index])) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean equalsTo(final MoreKeySpec moreKeySpec) {
+ // MoreKeySpec has no "more keys".
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + "^" + Arrays.toString(mMoreKeys);
+ }
+ }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyOutput.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyOutput.java
new file mode 100644
index 000000000..1be51e60b
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyOutput.java
@@ -0,0 +1,138 @@
+/*
+ * 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.MoreKeySpec;
+import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.utils.StringUtils;
+
+import java.util.Locale;
+
+/**
+ * This class represents an expected output of a key.
+ *
+ * There are two types of expected output, an integer code point and a string output text.
+ */
+abstract class ExpectedKeyOutput {
+ static ExpectedKeyOutput newInstance(final int code) {
+ return new Code(code);
+ }
+
+ static ExpectedKeyOutput newInstance(final String outputText) {
+ // If the <code>outputText</code> is one code point string, use {@link CodePoint} object.
+ if (StringUtils.codePointCount(outputText) == 1) {
+ return new Code(outputText.codePointAt(0));
+ }
+ return new Text(outputText);
+ }
+
+ abstract ExpectedKeyOutput toUpperCase(final Locale locale);
+ abstract boolean equalsTo(final String text);
+ abstract boolean equalsTo(final Key key);
+ abstract boolean equalsTo(final MoreKeySpec moreKeySpec);
+ abstract boolean equalsTo(final ExpectedKeyOutput output);
+
+ /**
+ * This class represents an integer code point.
+ */
+ private static class Code extends ExpectedKeyOutput {
+ // UNICODE code point or a special negative value defined in {@link Constants}.
+ private final int mCode;
+
+ Code(final int code) { mCode = code; }
+
+ @Override
+ ExpectedKeyOutput toUpperCase(final Locale locale) {
+ if (Constants.isLetterCode(mCode)) {
+ final String codeString = StringUtils.newSingleCodePointString(mCode);
+ // A letter may have an upper case counterpart that consists of multiple code
+ // points, for instance the upper case of "ß" is "SS".
+ return newInstance(codeString.toUpperCase(locale));
+ }
+ // A special negative value has no upper case.
+ return this;
+ }
+
+ @Override
+ boolean equalsTo(final String text) {
+ return StringUtils.codePointCount(text) == 1 && text.codePointAt(0) == mCode;
+ }
+
+ @Override
+ boolean equalsTo(final Key key) {
+ return mCode == key.getCode();
+ }
+
+ @Override
+ boolean equalsTo(final MoreKeySpec moreKeySpec) {
+ return mCode == moreKeySpec.mCode;
+ }
+
+ @Override
+ boolean equalsTo(final ExpectedKeyOutput output) {
+ return (output instanceof Code) && mCode == ((Code)output).mCode;
+ }
+
+ @Override
+ public String toString() {
+ return Constants.isLetterCode(mCode) ? StringUtils.newSingleCodePointString(mCode)
+ : Constants.printableCode(mCode);
+ }
+ }
+
+ /**
+ * This class represents a string output text.
+ */
+ private static class Text extends ExpectedKeyOutput {
+ private final String mText;
+
+ Text(final String text) { mText = text; }
+
+ @Override
+ ExpectedKeyOutput toUpperCase(final Locale locale) {
+ return newInstance(mText.toUpperCase(locale));
+ }
+
+ @Override
+ boolean equalsTo(final String text) {
+ return text.equals(text);
+ }
+
+ @Override
+ boolean equalsTo(final Key key) {
+ return key.getCode() == Constants.CODE_OUTPUT_TEXT
+ && mText.equals(key.getOutputText());
+ }
+
+ @Override
+ boolean equalsTo(final MoreKeySpec moreKeySpec) {
+ return moreKeySpec.mCode == Constants.CODE_OUTPUT_TEXT
+ && mText.equals(moreKeySpec.mOutputText);
+ }
+
+ @Override
+ boolean equalsTo(final ExpectedKeyOutput output) {
+ return (output instanceof Text) && mText == ((Text)output).mText;
+ }
+
+ @Override
+ public String toString() {
+ return mText;
+ }
+ }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyVisual.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyVisual.java
new file mode 100644
index 000000000..0a0da32b6
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyVisual.java
@@ -0,0 +1,135 @@
+/*
+ * 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 java.util.Locale;
+
+/**
+ * This class represents an expected visual outlook of a key.
+ *
+ * There are two types of expected visual, an integer icon id and a string label.
+ */
+abstract class ExpectedKeyVisual {
+ static ExpectedKeyVisual newInstance(final String label) {
+ return new Label(label);
+ }
+
+ static ExpectedKeyVisual newInstance(final int iconId) {
+ return new Icon(iconId);
+ }
+
+ abstract ExpectedKeyVisual toUpperCase(final Locale locale);
+ abstract boolean equalsTo(final String text);
+ abstract boolean equalsTo(final Key key);
+ abstract boolean equalsTo(final MoreKeySpec moreKeySpec);
+ abstract boolean equalsTo(final ExpectedKeyOutput output);
+ abstract boolean equalsTo(final ExpectedKeyVisual visual);
+
+ /**
+ * This class represents an integer icon id.
+ */
+ private static class Icon extends ExpectedKeyVisual {
+ private final int mIconId;
+
+ Icon(final int iconId) {
+ mIconId = iconId;
+ }
+
+ @Override
+ ExpectedKeyVisual toUpperCase(final Locale locale) {
+ return this;
+ }
+
+ @Override
+ boolean equalsTo(final String text) {
+ return false;
+ }
+
+ @Override
+ boolean equalsTo(final Key key) {
+ return mIconId == key.getIconId();
+ }
+
+ @Override
+ boolean equalsTo(final MoreKeySpec moreKeySpec) {
+ return mIconId == moreKeySpec.mIconId;
+ }
+
+ @Override
+ boolean equalsTo(final ExpectedKeyOutput output) {
+ return false;
+ }
+
+ @Override
+ boolean equalsTo(final ExpectedKeyVisual visual) {
+ return (visual instanceof Icon) && mIconId == ((Icon)visual).mIconId;
+ }
+
+ @Override
+ public String toString() {
+ return KeyboardIconsSet.getIconName(mIconId);
+ }
+ }
+
+ /**
+ * This class represents a string label.
+ */
+ private static class Label extends ExpectedKeyVisual {
+ private final String mLabel;
+
+ Label(final String label) { mLabel = label; }
+
+ @Override
+ ExpectedKeyVisual toUpperCase(final Locale locale) {
+ return new Label(mLabel.toUpperCase(locale));
+ }
+
+ @Override
+ boolean equalsTo(final String text) {
+ return mLabel.equals(text);
+ }
+
+ @Override
+ boolean equalsTo(final Key key) {
+ return mLabel.equals(key.getLabel());
+ }
+
+ @Override
+ boolean equalsTo(final MoreKeySpec moreKeySpec) {
+ return mLabel.equals(moreKeySpec.mLabel);
+ }
+
+ @Override
+ boolean equalsTo(final ExpectedKeyOutput output) {
+ return output.equalsTo(mLabel);
+ }
+
+ @Override
+ boolean equalsTo(final ExpectedKeyVisual visual) {
+ return (visual instanceof Label) && mLabel.equals(((Label)visual).mLabel);
+ }
+
+ @Override
+ public String toString() {
+ return mLabel;
+ }
+ }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyboardBuilder.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyboardBuilder.java
new file mode 100644
index 000000000..61288f048
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyboardBuilder.java
@@ -0,0 +1,272 @@
+/*
+ * 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 java.util.Arrays;
+import java.util.Locale;
+
+/**
+ * This class builds an expected keyboard for unit test.
+ */
+public final class ExpectedKeyboardBuilder extends AbstractKeyboardBuilder<ExpectedKey> {
+ public ExpectedKeyboardBuilder(final int ... dimensions) {
+ super(dimensions);
+ }
+
+ public ExpectedKeyboardBuilder(final ExpectedKey[][] rows) {
+ super(rows);
+ }
+
+ @Override
+ protected ExpectedKey defaultElement() {
+ return ExpectedKey.EMPTY_KEY;
+ }
+
+ @Override
+ ExpectedKey[] newArray(final int size) {
+ return new ExpectedKey[size];
+ }
+
+ @Override
+ ExpectedKey[][] newArrayOfArray(final int size) {
+ return new ExpectedKey[size][];
+ }
+
+ @Override
+ public ExpectedKey[][] build() {
+ return super.build();
+ }
+
+ // A replacement job to be performed.
+ interface ReplaceJob {
+ // Returns a {@link ExpectedKey} object to replace.
+ ExpectedKey replace(final ExpectedKey oldKey);
+ // Return true if replacing should be stopped at first occurrence.
+ boolean stopAtFirstOccurrence();
+ }
+
+ // Replace key(s) that has the specified visual.
+ private void replaceKeyOf(final ExpectedKeyVisual visual, final ReplaceJob job) {
+ int replacedCount = 0;
+ final ExpectedKey[][] rows = build();
+ for (int rowIndex = 0; rowIndex < rows.length; rowIndex++) {
+ final ExpectedKey[] keys = rows[rowIndex];
+ for (int columnIndex = 0; columnIndex < keys.length; columnIndex++) {
+ if (keys[columnIndex].getVisual().equalsTo(visual)) {
+ keys[columnIndex] = job.replace(keys[columnIndex]);
+ replacedCount++;
+ if (job.stopAtFirstOccurrence()) {
+ return;
+ }
+ }
+ }
+ }
+ if (replacedCount == 0) {
+ throw new RuntimeException(
+ "Can't find key that has visual: " + visual + " in\n" + toString(rows));
+ }
+ }
+
+ /**
+ * Set the row with specified keys that have specified labels.
+ * @param row the row number to set keys.
+ * @param labels the label texts of the keys.
+ * @return this builder.
+ */
+ public ExpectedKeyboardBuilder setLabelsOfRow(final int row, final String ... labels) {
+ final ExpectedKey[] keys = new ExpectedKey[labels.length];
+ for (int columnIndex = 0; columnIndex < labels.length; columnIndex++) {
+ keys[columnIndex] = ExpectedKey.newInstance(labels[columnIndex]);
+ }
+ setRowAt(row, keys);
+ return this;
+ }
+
+ /**
+ * Set the "more keys" of the key that has the specified label.
+ * @param label the label of the key to set the "more keys".
+ * @param moreKeys the array of labels of the "more keys" to be set.
+ * @return this builder.
+ */
+ public ExpectedKeyboardBuilder setMoreKeysOf(final String label, final String ... moreKeys) {
+ final ExpectedKey[] expectedMoreKeys = new ExpectedKey[moreKeys.length];
+ for (int index = 0; index < moreKeys.length; index++) {
+ expectedMoreKeys[index] = ExpectedKey.newInstance(moreKeys[index]);
+ }
+ setMoreKeysOf(label, expectedMoreKeys);
+ return this;
+ }
+
+ /**
+ * Set the "more keys" of the key that has the specified label.
+ * @param label the label of the key to set the "more keys".
+ * @param moreKeys the array of "more key" to be set.
+ * @return this builder.
+ */
+ public ExpectedKeyboardBuilder setMoreKeysOf(final String label,
+ final ExpectedKey ... moreKeys) {
+ setMoreKeysOf(ExpectedKeyVisual.newInstance(label), moreKeys);
+ return this;
+ }
+
+ /**
+ * Set the "more keys" of the key that has the specified icon.
+ * @param iconId the icon id of the key to set the "more keys".
+ * @param moreKeys the array of "more key" to be set.
+ * @return this builder.
+ */
+ public ExpectedKeyboardBuilder setMoreKeysOf(final int iconId, final ExpectedKey ... moreKeys) {
+ setMoreKeysOf(ExpectedKeyVisual.newInstance(iconId), moreKeys);
+ return this;
+ }
+
+ private void setMoreKeysOf(final ExpectedKeyVisual visual, final ExpectedKey[] moreKeys) {
+ replaceKeyOf(visual, new ReplaceJob() {
+ @Override
+ public ExpectedKey replace(final ExpectedKey oldKey) {
+ return ExpectedKey.newInstance(oldKey.getVisual(), oldKey.getOutput(), moreKeys);
+ }
+ @Override
+ public boolean stopAtFirstOccurrence() {
+ return true;
+ }
+ });
+ }
+
+ /**
+ * Insert the keys at specified position.
+ * @param row the row number to insert the <code>keys</code>.
+ * @param column the column number to insert the <code>keys</code>.
+ * @param keys the array of keys to insert at <code>row,column</code>.
+ * @return this builder.
+ * @throws {@link RuntimeException} if <code>row</code> or <code>column</code> is illegal.
+ */
+ public ExpectedKeyboardBuilder insertKeysAtRow(final int row, final int column,
+ final ExpectedKey ... keys) {
+ for (int index = 0; index < keys.length; index++) {
+ setElementAt(row, column + index, keys[index], true /* insert */);
+ }
+ return this;
+ }
+
+ /**
+ * Add the keys on the left most of the row.
+ * @param row the row number to add the <code>keys</code>.
+ * @param keys the array of keys to add on the left most of the row.
+ * @return this builder.
+ * @throws {@link RuntimeException} if <code>row</code> is illegal.
+ */
+ public ExpectedKeyboardBuilder addKeysOnTheLeftOfRow(final int row,
+ final ExpectedKey ... keys) {
+ // Keys should be inserted from the last to preserve the order.
+ for (int index = keys.length - 1; index >= 0; index--) {
+ setElementAt(row, 1, keys[index], true /* insert */);
+ }
+ return this;
+ }
+
+ /**
+ * Add the keys on the right most of the row.
+ * @param row the row number to add the <code>keys</code>.
+ * @param keys the array of keys to add on the right most of the row.
+ * @return this builder.
+ * @throws {@link RuntimeException} if <code>row</code> is illegal.
+ */
+ public ExpectedKeyboardBuilder addKeysOnTheRightOfRow(final int row,
+ final ExpectedKey ... keys) {
+ final int rightEnd = getRowAt(row).length + 1;
+ insertKeysAtRow(row, rightEnd, keys);
+ return this;
+ }
+
+ /**
+ * Replace the most top-left key that has the specified label with the new key.
+ * @param label the label of the key to set <code>newKey</code>.
+ * @param newKey the key to be set.
+ * @return this builder.
+ */
+ public ExpectedKeyboardBuilder replaceKeyOfLabel(final String label, final ExpectedKey newKey) {
+ final ExpectedKeyVisual visual = ExpectedKeyVisual.newInstance(label);
+ replaceKeyOf(visual, new ReplaceJob() {
+ @Override
+ public ExpectedKey replace(final ExpectedKey oldKey) {
+ return newKey;
+ }
+ @Override
+ public boolean stopAtFirstOccurrence() {
+ return true;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Replace the all specified keys with the new key.
+ * @param key the key to be replaced by <code>newKey</code>.
+ * @param newKey the key to be set.
+ * @return this builder.
+ */
+ public ExpectedKeyboardBuilder replaceKeyOfAll(final ExpectedKey key,
+ final ExpectedKey newKey) {
+ replaceKeyOf(key.getVisual(), new ReplaceJob() {
+ @Override
+ public ExpectedKey replace(final ExpectedKey oldKey) {
+ return newKey;
+ }
+ @Override
+ public boolean stopAtFirstOccurrence() {
+ return false;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Returns new keyboard instance that has upper case keys of the specified keyboard.
+ * @param rows the lower case keyboard.
+ * @param locale the locale used to convert cases.
+ * @return the upper case keyboard.
+ */
+ public static ExpectedKey[][] toUpperCase(final ExpectedKey[][] rows, final Locale locale) {
+ final ExpectedKey[][] upperCaseRows = new ExpectedKey[rows.length][];
+ for (int rowIndex = 0; rowIndex < rows.length; rowIndex++) {
+ final ExpectedKey[] lowerCaseKeys = rows[rowIndex];
+ final ExpectedKey[] upperCaseKeys = new ExpectedKey[lowerCaseKeys.length];
+ for (int columnIndex = 0; columnIndex < lowerCaseKeys.length; columnIndex++) {
+ upperCaseKeys[columnIndex] = lowerCaseKeys[columnIndex].toUpperCase(locale);
+ }
+ upperCaseRows[rowIndex] = upperCaseKeys;
+ }
+ return upperCaseRows;
+ }
+
+ /**
+ * 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 ExpectedKey[][] rows) {
+ final StringBuilder sb = new StringBuilder();
+ for (int rowIndex = 0; rowIndex < rows.length; rowIndex++) {
+ if (rowIndex > 0) {
+ sb.append("\n");
+ }
+ sb.append(Arrays.toString(rows[rowIndex]));
+ }
+ return sb.toString();
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
index fa5123665..69420d6ac 100644
--- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
+++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
@@ -27,6 +27,7 @@ import com.android.inputmethod.latin.makedict.FormatSpec;
import com.android.inputmethod.latin.makedict.FusionDictionary;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
+import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
import com.android.inputmethod.latin.utils.FileUtils;
import com.android.inputmethod.latin.utils.LocaleUtils;
@@ -111,7 +112,7 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
DictionaryHeader.ATTRIBUTE_VALUE_TRUE);
attributeMap.put(DictionaryHeader.HAS_HISTORICAL_INFO_KEY,
DictionaryHeader.ATTRIBUTE_VALUE_TRUE);
- if (BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(), FormatSpec.VERSION4,
+ if (BinaryDictionaryUtils.createEmptyDictFile(file.getAbsolutePath(), FormatSpec.VERSION4,
LocaleUtils.constructLocaleFromString(TEST_LOCALE), attributeMap)) {
return file;
} else {
@@ -121,11 +122,11 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
}
private static int setCurrentTimeForTestMode(final int currentTime) {
- return BinaryDictionary.setCurrentTimeForTest(currentTime);
+ return BinaryDictionaryUtils.setCurrentTimeForTest(currentTime);
}
private static int stopTestModeInNativeCode() {
- return BinaryDictionary.setCurrentTimeForTest(-1);
+ return BinaryDictionaryUtils.setCurrentTimeForTest(-1);
}
public void testReadDictInJavaSide() {
diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
index c1adf6557..4f9245ce0 100644
--- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
@@ -25,6 +25,7 @@ import com.android.inputmethod.latin.makedict.CodePointUtils;
import com.android.inputmethod.latin.makedict.FormatSpec;
import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import com.android.inputmethod.latin.makedict.WordProperty;
+import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
import com.android.inputmethod.latin.utils.FileUtils;
import com.android.inputmethod.latin.utils.LanguageModelParam;
@@ -59,7 +60,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
file.delete();
file.mkdir();
Map<String, String> attributeMap = new HashMap<String, String>();
- if (BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(), FormatSpec.VERSION4,
+ if (BinaryDictionaryUtils.createEmptyDictFile(file.getAbsolutePath(), FormatSpec.VERSION4,
Locale.ENGLISH, attributeMap)) {
return file;
} else {
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
index 0ee0fb577..80978df97 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
@@ -30,6 +30,7 @@ import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
+import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
import com.android.inputmethod.latin.utils.ByteArrayDictBuffer;
import com.android.inputmethod.latin.utils.CollectionUtils;
@@ -77,7 +78,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
public BinaryDictDecoderEncoderTests(final long seed, final int maxUnigrams) {
super();
- BinaryDictionary.setCurrentTimeForTest(0);
+ BinaryDictionaryUtils.setCurrentTimeForTest(0);
Log.e(TAG, "Testing dictionary: seed is " + seed);
final Random random = new Random(seed);
sWords.clear();
@@ -112,13 +113,13 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
- BinaryDictionary.setCurrentTimeForTest(0);
+ BinaryDictionaryUtils.setCurrentTimeForTest(0);
}
@Override
protected void tearDown() throws Exception {
// Quit test mode.
- BinaryDictionary.setCurrentTimeForTest(-1);
+ BinaryDictionaryUtils.setCurrentTimeForTest(-1);
super.tearDown();
}
diff --git a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java
index 6ace2de4f..04840d667 100644
--- a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java
@@ -20,8 +20,8 @@ import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
-import com.android.inputmethod.latin.BinaryDictionary;
import com.android.inputmethod.latin.ExpandableBinaryDictionary;
+import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.FileUtils;
@@ -79,11 +79,11 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
}
private static int setCurrentTimeForTestMode(final int currentTime) {
- return BinaryDictionary.setCurrentTimeForTest(currentTime);
+ return BinaryDictionaryUtils.setCurrentTimeForTest(currentTime);
}
private static int stopTestModeInNativeCode() {
- return BinaryDictionary.setCurrentTimeForTest(-1);
+ return BinaryDictionaryUtils.setCurrentTimeForTest(-1);
}
/**
diff --git a/tests/src/com/android/inputmethod/latin/EditDistanceTests.java b/tests/src/com/android/inputmethod/latin/utils/EditDistanceTests.java
index ffec20ab2..58312264b 100644
--- a/tests/src/com/android/inputmethod/latin/EditDistanceTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/EditDistanceTests.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.inputmethod.latin;
+package com.android.inputmethod.latin.utils;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
@@ -29,7 +29,7 @@ public class EditDistanceTests extends AndroidTestCase {
* sitting
*/
public void testExample1() {
- final int dist = BinaryDictionary.editDistance("kitten", "sitting");
+ final int dist = BinaryDictionaryUtils.editDistance("kitten", "sitting");
assertEquals("edit distance between 'kitten' and 'sitting' is 3",
3, dist);
}
@@ -42,26 +42,26 @@ public class EditDistanceTests extends AndroidTestCase {
* S--unday
*/
public void testExample2() {
- final int dist = BinaryDictionary.editDistance("Saturday", "Sunday");
+ final int dist = BinaryDictionaryUtils.editDistance("Saturday", "Sunday");
assertEquals("edit distance between 'Saturday' and 'Sunday' is 3",
3, dist);
}
public void testBothEmpty() {
- final int dist = BinaryDictionary.editDistance("", "");
+ final int dist = BinaryDictionaryUtils.editDistance("", "");
assertEquals("when both string are empty, no edits are needed",
0, dist);
}
public void testFirstArgIsEmpty() {
- final int dist = BinaryDictionary.editDistance("", "aaaa");
+ final int dist = BinaryDictionaryUtils.editDistance("", "aaaa");
assertEquals("when only one string of the arguments is empty,"
+ " the edit distance is the length of the other.",
4, dist);
}
public void testSecoondArgIsEmpty() {
- final int dist = BinaryDictionary.editDistance("aaaa", "");
+ final int dist = BinaryDictionaryUtils.editDistance("aaaa", "");
assertEquals("when only one string of the arguments is empty,"
+ " the edit distance is the length of the other.",
4, dist);
@@ -70,27 +70,27 @@ public class EditDistanceTests extends AndroidTestCase {
public void testSameStrings() {
final String arg1 = "The quick brown fox jumps over the lazy dog.";
final String arg2 = "The quick brown fox jumps over the lazy dog.";
- final int dist = BinaryDictionary.editDistance(arg1, arg2);
+ final int dist = BinaryDictionaryUtils.editDistance(arg1, arg2);
assertEquals("when same strings are passed, distance equals 0.",
0, dist);
}
public void testSameReference() {
final String arg = "The quick brown fox jumps over the lazy dog.";
- final int dist = BinaryDictionary.editDistance(arg, arg);
+ final int dist = BinaryDictionaryUtils.editDistance(arg, arg);
assertEquals("when same string references are passed, the distance equals 0.",
0, dist);
}
public void testNullArg() {
try {
- BinaryDictionary.editDistance(null, "aaa");
+ BinaryDictionaryUtils.editDistance(null, "aaa");
fail("IllegalArgumentException should be thrown.");
} catch (Exception e) {
assertTrue(e instanceof IllegalArgumentException);
}
try {
- BinaryDictionary.editDistance("aaa", null);
+ BinaryDictionaryUtils.editDistance("aaa", null);
fail("IllegalArgumentException should be thrown.");
} catch (Exception e) {
assertTrue(e instanceof IllegalArgumentException);