aboutsummaryrefslogtreecommitdiffstats
path: root/tests/src
diff options
context:
space:
mode:
Diffstat (limited to 'tests/src')
-rw-r--r--tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java644
-rw-r--r--tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTestsBase.java353
-rw-r--r--tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java (renamed from tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserSplitTests.java)16
-rw-r--r--tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecTests.java374
-rw-r--r--tests/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueueTests.java16
-rw-r--r--tests/src/com/android/inputmethod/latin/AppWorkaroundsTests.java74
-rw-r--r--tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java431
-rw-r--r--tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java675
-rw-r--r--tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java13
-rw-r--r--tests/src/com/android/inputmethod/latin/EditDistanceTests.java10
-rw-r--r--tests/src/com/android/inputmethod/latin/ExpandableDictionaryTests.java58
-rw-r--r--tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java11
-rw-r--r--tests/src/com/android/inputmethod/latin/InputLogicTests.java110
-rw-r--r--tests/src/com/android/inputmethod/latin/InputLogicTestsLanguageWithoutSpaces.java3
-rw-r--r--tests/src/com/android/inputmethod/latin/InputLogicTestsNonEnglish.java5
-rw-r--r--tests/src/com/android/inputmethod/latin/InputPointersTests.java209
-rw-r--r--tests/src/com/android/inputmethod/latin/InputTestsBase.java112
-rw-r--r--tests/src/com/android/inputmethod/latin/LatinImeStressTests.java2
-rw-r--r--tests/src/com/android/inputmethod/latin/PunctuationTests.java39
-rw-r--r--tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java89
-rw-r--r--tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java3
-rw-r--r--tests/src/com/android/inputmethod/latin/WordComposerTests.java66
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java392
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java389
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java78
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/SparseTableTests.java195
-rw-r--r--tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java (renamed from tests/src/com/android/inputmethod/latin/makedict/Ver3DictDecoderTests.java)10
-rw-r--r--tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java203
-rw-r--r--tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java477
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java109
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/DictionaryInfoUtilsTests.java47
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/ForgettingCurveTests.java58
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/RecapitalizeStatusTests.java34
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/ResizableIntArrayTests.java158
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/ResourceUtilsTests.java33
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/StringAndJsonUtilsTests.java (renamed from tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java)126
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java99
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtilsTests.java239
38 files changed, 3536 insertions, 2424 deletions
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java
index afb2b0343..8e26e7fc7 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * 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.
@@ -17,643 +17,39 @@
package com.android.inputmethod.keyboard.internal;
import static com.android.inputmethod.keyboard.internal.KeyboardIconsSet.ICON_UNDEFINED;
-import static com.android.inputmethod.latin.Constants.CODE_OUTPUT_TEXT;
import static com.android.inputmethod.latin.Constants.CODE_UNSPECIFIED;
-import android.content.Context;
-import android.content.res.Resources;
-import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.utils.RunInLocale;
-
-import java.util.Arrays;
-import java.util.Locale;
@SmallTest
-public class KeySpecParserTests extends AndroidTestCase {
- private final static Locale TEST_LOCALE = Locale.ENGLISH;
- final KeyboardCodesSet mCodesSet = new KeyboardCodesSet();
- final KeyboardTextsSet mTextsSet = new KeyboardTextsSet();
-
- private static final String CODE_SETTINGS = "!code/key_settings";
- private static final String ICON_SETTINGS = "!icon/settings_key";
- private static final String CODE_SETTINGS_UPPERCASE = CODE_SETTINGS.toUpperCase(Locale.ROOT);
- private static final String ICON_SETTINGS_UPPERCASE = ICON_SETTINGS.toUpperCase(Locale.ROOT);
- private static final String CODE_NON_EXISTING = "!code/non_existing";
- private static final String ICON_NON_EXISTING = "!icon/non_existing";
-
- private int mCodeSettings;
- private int mCodeActionNext;
- private int mSettingsIconId;
-
+public final class KeySpecParserTests extends KeySpecParserTestsBase {
@Override
- protected void setUp() throws Exception {
- super.setUp();
-
- final String language = TEST_LOCALE.getLanguage();
- mCodesSet.setLanguage(language);
- mTextsSet.setLanguage(language);
- final Context context = getContext();
- new RunInLocale<Void>() {
- @Override
- protected Void job(final Resources res) {
- mTextsSet.loadStringResources(context);
- return null;
- }
- }.runInLocale(context.getResources(), TEST_LOCALE);
-
- mCodeSettings = KeySpecParser.parseCode(
- CODE_SETTINGS, mCodesSet, CODE_UNSPECIFIED);
- mCodeActionNext = KeySpecParser.parseCode(
- "!code/key_action_next", mCodesSet, CODE_UNSPECIFIED);
- mSettingsIconId = KeySpecParser.getIconId(ICON_SETTINGS);
- }
-
- private void assertParser(String message, String moreKeySpec, String expectedLabel,
- String expectedOutputText, int expectedIcon, int expectedCode) {
- final String labelResolved = KeySpecParser.resolveTextReference(moreKeySpec, mTextsSet);
- final MoreKeySpec spec = new MoreKeySpec(labelResolved, false /* needsToUpperCase */,
- Locale.US, mCodesSet);
- assertEquals(message + " [label]", expectedLabel, spec.mLabel);
- assertEquals(message + " [ouptputText]", expectedOutputText, spec.mOutputText);
+ protected void assertParser(final String message, final String keySpec,
+ final String expectedLabel, final String expectedOutputText, final int expectedIcon,
+ final int expectedCode) {
+ final String keySpecResolved = mTextsSet.resolveTextReference(keySpec);
+ final String actualLabel = KeySpecParser.getLabel(keySpecResolved);
+ final String actualOutputText = KeySpecParser.getOutputText(keySpecResolved);
+ final int actualIcon = KeySpecParser.getIconId(keySpecResolved);
+ final int actualCode = KeySpecParser.getCode(keySpecResolved);
+ assertEquals(message + " [label]", expectedLabel, actualLabel);
+ assertEquals(message + " [ouptputText]", expectedOutputText, actualOutputText);
assertEquals(message + " [icon]",
KeyboardIconsSet.getIconName(expectedIcon),
- KeyboardIconsSet.getIconName(spec.mIconId));
+ KeyboardIconsSet.getIconName(actualIcon));
assertEquals(message + " [code]",
Constants.printableCode(expectedCode),
- Constants.printableCode(spec.mCode));
- }
-
- private void assertParserError(String message, String moreKeySpec, String expectedLabel,
- String expectedOutputText, int expectedIcon, int expectedCode) {
- try {
- assertParser(message, moreKeySpec, expectedLabel, expectedOutputText, expectedIcon,
- expectedCode);
- fail(message);
- } catch (Exception pcpe) {
- // success.
- }
- }
-
- // \U001d11e: MUSICAL SYMBOL G CLEF
- private static final String PAIR1 = "\ud834\udd1e";
- private static final int CODE1 = PAIR1.codePointAt(0);
- // \U001d122: MUSICAL SYMBOL F CLEF
- private static final String PAIR2 = "\ud834\udd22";
- private static final int CODE2 = PAIR2.codePointAt(0);
- // \U002f8a6: CJK COMPATIBILITY IDEOGRAPH-2F8A6; variant character of \u6148.
- private static final String PAIR3 = "\ud87e\udca6";
- private static final String SURROGATE1 = PAIR1 + PAIR2;
- private static final String SURROGATE2 = PAIR1 + PAIR2 + PAIR3;
-
- public void testSingleLetter() {
- assertParser("Single letter", "a",
- "a", null, ICON_UNDEFINED, 'a');
- assertParser("Single surrogate", PAIR1,
- PAIR1, null, ICON_UNDEFINED, CODE1);
- assertParser("Single escaped bar", "\\|",
- "|", null, ICON_UNDEFINED, '|');
- assertParser("Single escaped escape", "\\\\",
- "\\", null, ICON_UNDEFINED, '\\');
- assertParser("Single comma", ",",
- ",", null, ICON_UNDEFINED, ',');
- assertParser("Single escaped comma", "\\,",
- ",", null, ICON_UNDEFINED, ',');
- assertParser("Single escaped letter", "\\a",
- "a", null, ICON_UNDEFINED, 'a');
- assertParser("Single escaped surrogate", "\\" + PAIR2,
- PAIR2, null, ICON_UNDEFINED, CODE2);
- assertParser("Single bang", "!",
- "!", null, ICON_UNDEFINED, '!');
- assertParser("Single escaped bang", "\\!",
- "!", null, ICON_UNDEFINED, '!');
- assertParser("Single output text letter", "a|a",
- "a", null, ICON_UNDEFINED, 'a');
- assertParser("Single surrogate pair outputText", "G Clef|" + PAIR1,
- "G Clef", null, ICON_UNDEFINED, CODE1);
- assertParser("Single letter with outputText", "a|abc",
- "a", "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Single letter with surrogate outputText", "a|" + SURROGATE1,
- "a", SURROGATE1, ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Single surrogate with outputText", PAIR3 + "|abc",
- PAIR3, "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Single letter with escaped outputText", "a|a\\|c",
- "a", "a|c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Single letter with escaped surrogate outputText",
- "a|" + PAIR1 + "\\|" + PAIR2,
- "a", PAIR1 + "|" + PAIR2, ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Single letter with comma outputText", "a|a,b",
- "a", "a,b", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Single letter with escaped comma outputText", "a|a\\,b",
- "a", "a,b", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Single letter with outputText starts with bang", "a|!bc",
- "a", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Single letter with surrogate outputText starts with bang", "a|!" + SURROGATE2,
- "a", "!" + SURROGATE2, ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Single letter with outputText contains bang", "a|a!c",
- "a", "a!c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Single letter with escaped bang outputText", "a|\\!bc",
- "a", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Single escaped escape with single outputText", "\\\\|\\\\",
- "\\", null, ICON_UNDEFINED, '\\');
- assertParser("Single escaped bar with single outputText", "\\||\\|",
- "|", null, ICON_UNDEFINED, '|');
- assertParser("Single letter with code", "a|" + CODE_SETTINGS,
- "a", null, ICON_UNDEFINED, mCodeSettings);
- }
-
- public void testLabel() {
- assertParser("Simple label", "abc",
- "abc", "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Simple surrogate label", SURROGATE1,
- SURROGATE1, SURROGATE1, ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with escaped bar", "a\\|c",
- "a|c", "a|c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Surrogate label with escaped bar", PAIR1 + "\\|" + PAIR2,
- PAIR1 + "|" + PAIR2, PAIR1 + "|" + PAIR2,
- ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with escaped escape", "a\\\\c",
- "a\\c", "a\\c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with comma", "a,c",
- "a,c", "a,c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with escaped comma", "a\\,c",
- "a,c", "a,c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label starts with bang", "!bc",
- "!bc", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Surrogate label starts with bang", "!" + SURROGATE1,
- "!" + SURROGATE1, "!" + SURROGATE1, ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label contains bang", "a!c",
- "a!c", "a!c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with escaped bang", "\\!bc",
- "!bc", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with escaped letter", "\\abc",
- "abc", "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with outputText", "abc|def",
- "abc", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with comma and outputText", "a,c|def",
- "a,c", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Escaped comma label with outputText", "a\\,c|def",
- "a,c", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Escaped label with outputText", "a\\|c|def",
- "a|c", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with escaped bar outputText", "abc|d\\|f",
- "abc", "d|f", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Escaped escape label with outputText", "a\\\\|def",
- "a\\", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label starts with bang and outputText", "!bc|def",
- "!bc", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label contains bang label and outputText", "a!c|def",
- "a!c", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Escaped bang label with outputText", "\\!bc|def",
- "!bc", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with comma outputText", "abc|a,b",
- "abc", "a,b", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with escaped comma outputText", "abc|a\\,b",
- "abc", "a,b", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with outputText starts with bang", "abc|!bc",
- "abc", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with outputText contains bang", "abc|a!c",
- "abc", "a!c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with escaped bang outputText", "abc|\\!bc",
- "abc", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with escaped bar outputText", "abc|d\\|f",
- "abc", "d|f", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Escaped bar label with escaped bar outputText", "a\\|c|d\\|f",
- "a|c", "d|f", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with code", "abc|" + CODE_SETTINGS,
- "abc", null, ICON_UNDEFINED, mCodeSettings);
- assertParser("Escaped label with code", "a\\|c|" + CODE_SETTINGS,
- "a|c", null, ICON_UNDEFINED, mCodeSettings);
- }
-
- public void testIconAndCode() {
- assertParser("Icon with outputText", ICON_SETTINGS + "|abc",
- null, "abc", mSettingsIconId, CODE_OUTPUT_TEXT);
- assertParser("Icon with outputText starts with bang", ICON_SETTINGS + "|!bc",
- null, "!bc", mSettingsIconId, CODE_OUTPUT_TEXT);
- assertParser("Icon with outputText contains bang", ICON_SETTINGS + "|a!c",
- null, "a!c", mSettingsIconId, CODE_OUTPUT_TEXT);
- assertParser("Icon with escaped bang outputText", ICON_SETTINGS + "|\\!bc",
- null, "!bc", mSettingsIconId, CODE_OUTPUT_TEXT);
- assertParser("Label starts with bang and code", "!bc|" + CODE_SETTINGS,
- "!bc", null, ICON_UNDEFINED, mCodeSettings);
- assertParser("Label contains bang and code", "a!c|" + CODE_SETTINGS,
- "a!c", null, ICON_UNDEFINED, mCodeSettings);
- assertParser("Escaped bang label with code", "\\!bc|" + CODE_SETTINGS,
- "!bc", null, ICON_UNDEFINED, mCodeSettings);
- assertParser("Icon with code", ICON_SETTINGS + "|" + CODE_SETTINGS,
- null, null, mSettingsIconId, mCodeSettings);
- }
-
- public void testResourceReference() {
- assertParser("Settings as more key", "!text/settings_as_more_key",
- null, null, mSettingsIconId, mCodeSettings);
-
- assertParser("Action next as more key", "!text/label_next_key|!code/key_action_next",
- "Next", null, ICON_UNDEFINED, mCodeActionNext);
-
- assertParser("Popular domain",
- "!text/keylabel_for_popular_domain|!text/keylabel_for_popular_domain ",
- ".com", ".com ", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ Constants.printableCode(actualCode));
}
- public void testFormatError() {
- assertParserError("Empty spec", "", null,
- null, ICON_UNDEFINED, CODE_UNSPECIFIED);
- assertParserError("Empty label with outputText", "|a",
- null, "a", ICON_UNDEFINED, CODE_UNSPECIFIED);
- assertParserError("Empty label with code", "|" + CODE_SETTINGS,
- null, null, ICON_UNDEFINED, mCodeSettings);
- assertParserError("Empty outputText with label", "a|",
- "a", null, ICON_UNDEFINED, CODE_UNSPECIFIED);
- assertParserError("Empty outputText with icon", ICON_SETTINGS + "|",
- null, null, mSettingsIconId, CODE_UNSPECIFIED);
- assertParserError("Empty icon and code", "|",
+ // TODO: Remove this method.
+ // These should throw {@link KeySpecParserError} when Key.keyLabel attribute become mandatory.
+ public void testEmptySpec() {
+ assertParser("Null spec", null,
+ null, null, ICON_UNDEFINED, CODE_UNSPECIFIED);
+ assertParser("Empty spec", "",
null, null, ICON_UNDEFINED, CODE_UNSPECIFIED);
- assertParserError("Icon without code", ICON_SETTINGS,
- null, null, mSettingsIconId, CODE_UNSPECIFIED);
- assertParserError("Non existing icon", ICON_NON_EXISTING + "|abc",
- null, "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParserError("Non existing code", "abc|" + CODE_NON_EXISTING,
- "abc", null, ICON_UNDEFINED, CODE_UNSPECIFIED);
- assertParserError("Third bar at end", "a|b|",
- "a", null, ICON_UNDEFINED, CODE_UNSPECIFIED);
- assertParserError("Multiple bar", "a|b|c",
- "a", null, ICON_UNDEFINED, CODE_UNSPECIFIED);
- assertParserError("Multiple bar with label and code", "a|" + CODE_SETTINGS + "|c",
- "a", null, ICON_UNDEFINED, mCodeSettings);
- assertParserError("Multiple bar with icon and outputText", ICON_SETTINGS + "|b|c",
- null, null, mSettingsIconId, CODE_UNSPECIFIED);
- assertParserError("Multiple bar with icon and code",
- ICON_SETTINGS + "|" + CODE_SETTINGS + "|c",
- null, null, mSettingsIconId, mCodeSettings);
- }
-
- public void testUselessUpperCaseSpecifier() {
- assertParser("Single letter with CODE", "a|" + CODE_SETTINGS_UPPERCASE,
- "a", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label with CODE", "abc|" + CODE_SETTINGS_UPPERCASE,
- "abc", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Escaped label with CODE", "a\\|c|" + CODE_SETTINGS_UPPERCASE,
- "a|c", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("ICON with outputText", ICON_SETTINGS_UPPERCASE + "|abc",
- "!ICON/SETTINGS_KEY", "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("ICON with outputText starts with bang", ICON_SETTINGS_UPPERCASE + "|!bc",
- "!ICON/SETTINGS_KEY", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("ICON with outputText contains bang", ICON_SETTINGS_UPPERCASE + "|a!c",
- "!ICON/SETTINGS_KEY", "a!c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("ICON with escaped bang outputText", ICON_SETTINGS_UPPERCASE + "|\\!bc",
- "!ICON/SETTINGS_KEY", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label starts with bang and CODE", "!bc|" + CODE_SETTINGS_UPPERCASE,
- "!bc", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Label contains bang and CODE", "a!c|" + CODE_SETTINGS_UPPERCASE,
- "a!c", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("Escaped bang label with CODE", "\\!bc|" + CODE_SETTINGS_UPPERCASE,
- "!bc", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("ICON with CODE", ICON_SETTINGS_UPPERCASE + "|" + CODE_SETTINGS_UPPERCASE,
- "!ICON/SETTINGS_KEY", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParser("SETTINGS AS MORE KEY", "!TEXT/SETTINGS_AS_MORE_KEY",
- "!TEXT/SETTINGS_AS_MORE_KEY", "!TEXT/SETTINGS_AS_MORE_KEY", ICON_UNDEFINED,
- CODE_OUTPUT_TEXT);
- assertParser("ACTION NEXT AS MORE KEY", "!TEXT/LABEL_NEXT_KEY|!CODE/KEY_ACTION_NEXT",
- "!TEXT/LABEL_NEXT_KEY", "!CODE/KEY_ACTION_NEXT", ICON_UNDEFINED,
- CODE_OUTPUT_TEXT);
- assertParser("POPULAR DOMAIN",
- "!TEXT/KEYLABEL_FOR_POPULAR_DOMAIN|!TEXT/KEYLABEL_FOR_POPULAR_DOMAIN ",
- "!TEXT/KEYLABEL_FOR_POPULAR_DOMAIN", "!TEXT/KEYLABEL_FOR_POPULAR_DOMAIN ",
- ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParserError("Empty label with CODE", "|" + CODE_SETTINGS_UPPERCASE,
- null, null, ICON_UNDEFINED, mCodeSettings);
- assertParserError("Empty outputText with ICON", ICON_SETTINGS_UPPERCASE + "|",
- null, null, mSettingsIconId, CODE_UNSPECIFIED);
- assertParser("ICON without code", ICON_SETTINGS_UPPERCASE,
- "!ICON/SETTINGS_KEY", "!ICON/SETTINGS_KEY", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
- assertParserError("Multiple bar with label and CODE", "a|" + CODE_SETTINGS_UPPERCASE + "|c",
- "a", null, ICON_UNDEFINED, mCodeSettings);
- assertParserError("Multiple bar with ICON and outputText", ICON_SETTINGS_UPPERCASE + "|b|c",
- null, null, mSettingsIconId, CODE_UNSPECIFIED);
- assertParserError("Multiple bar with ICON and CODE",
- ICON_SETTINGS_UPPERCASE + "|" + CODE_SETTINGS_UPPERCASE + "|c",
- null, null, mSettingsIconId, mCodeSettings);
- }
-
- private static void assertArrayEquals(String message, Object[] expected, Object[] actual) {
- if (expected == actual) {
- return;
- }
- if (expected == null || actual == null) {
- assertEquals(message, Arrays.toString(expected), Arrays.toString(actual));
- return;
- }
- if (expected.length != actual.length) {
- assertEquals(message + " [length]", Arrays.toString(expected), Arrays.toString(actual));
- return;
- }
- for (int i = 0; i < expected.length; i++) {
- assertEquals(message + " [" + i + "]",
- Arrays.toString(expected), Arrays.toString(actual));
- }
- }
-
- private static void assertInsertAdditionalMoreKeys(String message, String[] moreKeys,
- String[] additionalMoreKeys, String[] expected) {
- final String[] actual =
- KeySpecParser.insertAdditionalMoreKeys( moreKeys, additionalMoreKeys);
- assertArrayEquals(message, expected, actual);
- }
-
- public void testEmptyEntry() {
- assertInsertAdditionalMoreKeys("null more keys and null additons",
- null,
- null,
- null);
- assertInsertAdditionalMoreKeys("null more keys and empty additons",
- null,
- new String[0],
- null);
- assertInsertAdditionalMoreKeys("empty more keys and null additons",
- new String[0],
- null,
- null);
- assertInsertAdditionalMoreKeys("empty more keys and empty additons",
- new String[0],
- new String[0],
- null);
-
- assertInsertAdditionalMoreKeys("filter out empty more keys",
- new String[] { null, "a", "", "b", null },
- null,
- new String[] { "a", "b" });
- assertInsertAdditionalMoreKeys("filter out empty additons",
- new String[] { "a", "%", "b", "%", "c", "%", "d" },
- new String[] { null, "A", "", "B", null },
- new String[] { "a", "A", "b", "B", "c", "d" });
- }
-
- public void testInsertAdditionalMoreKeys() {
- // Escaped marker.
- assertInsertAdditionalMoreKeys("escaped marker",
- new String[] { "\\%", "%-)" },
- new String[] { "1", "2" },
- new String[] { "1", "2", "\\%", "%-)" });
-
- // 0 more key.
- assertInsertAdditionalMoreKeys("null & null", null, null, null);
- assertInsertAdditionalMoreKeys("null & 1 additon",
- null,
- new String[] { "1" },
- new String[] { "1" });
- assertInsertAdditionalMoreKeys("null & 2 additons",
- null,
- new String[] { "1", "2" },
- new String[] { "1", "2" });
-
- // 0 additional more key.
- assertInsertAdditionalMoreKeys("1 more key & null",
- new String[] { "A" },
- null,
- new String[] { "A" });
- assertInsertAdditionalMoreKeys("2 more keys & null",
- new String[] { "A", "B" },
- null,
- new String[] { "A", "B" });
-
- // No marker.
- assertInsertAdditionalMoreKeys("1 more key & 1 addtional & no marker",
- new String[] { "A" },
- new String[] { "1" },
- new String[] { "1", "A" });
- assertInsertAdditionalMoreKeys("1 more key & 2 addtionals & no marker",
- new String[] { "A" },
- new String[] { "1", "2" },
- new String[] { "1", "2", "A" });
- assertInsertAdditionalMoreKeys("2 more keys & 1 addtional & no marker",
- new String[] { "A", "B" },
- new String[] { "1" },
- new String[] { "1", "A", "B" });
- assertInsertAdditionalMoreKeys("2 more keys & 2 addtionals & no marker",
- new String[] { "A", "B" },
- new String[] { "1", "2" },
- new String[] { "1", "2", "A", "B" });
-
- // 1 marker.
- assertInsertAdditionalMoreKeys("1 more key & 1 additon & marker at head",
- new String[] { "%", "A" },
- new String[] { "1" },
- new String[] { "1", "A" });
- assertInsertAdditionalMoreKeys("1 more key & 1 additon & marker at tail",
- new String[] { "A", "%" },
- new String[] { "1" },
- new String[] { "A", "1" });
- assertInsertAdditionalMoreKeys("2 more keys & 1 additon & marker at middle",
- new String[] { "A", "%", "B" },
- new String[] { "1" },
- new String[] { "A", "1", "B" });
-
- // 1 marker & excess additional more keys.
- assertInsertAdditionalMoreKeys("1 more key & 2 additons & marker at head",
- new String[] { "%", "A", "B" },
- new String[] { "1", "2" },
- new String[] { "1", "A", "B", "2" });
- assertInsertAdditionalMoreKeys("1 more key & 2 additons & marker at tail",
- new String[] { "A", "B", "%" },
- new String[] { "1", "2" },
- new String[] { "A", "B", "1", "2" });
- assertInsertAdditionalMoreKeys("2 more keys & 2 additons & marker at middle",
- new String[] { "A", "%", "B" },
- new String[] { "1", "2" },
- new String[] { "A", "1", "B", "2" });
-
- // 2 markers.
- assertInsertAdditionalMoreKeys("0 more key & 2 addtional & 2 markers",
- new String[] { "%", "%" },
- new String[] { "1", "2" },
- new String[] { "1", "2" });
- assertInsertAdditionalMoreKeys("1 more key & 2 addtional & 2 markers at head",
- new String[] { "%", "%", "A" },
- new String[] { "1", "2" },
- new String[] { "1", "2", "A" });
- assertInsertAdditionalMoreKeys("1 more key & 2 addtional & 2 markers at tail",
- new String[] { "A", "%", "%" },
- new String[] { "1", "2" },
- new String[] { "A", "1", "2" });
- assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at middle",
- new String[] { "A", "%", "%", "B" },
- new String[] { "1", "2" },
- new String[] { "A", "1", "2", "B" });
- assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at head & middle",
- new String[] { "%", "A", "%", "B" },
- new String[] { "1", "2" },
- new String[] { "1", "A", "2", "B" });
- assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at head & tail",
- new String[] { "%", "A", "B", "%" },
- new String[] { "1", "2" },
- new String[] { "1", "A", "B", "2" });
- assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at middle & tail",
- new String[] { "A", "%", "B", "%" },
- new String[] { "1", "2" },
- new String[] { "A", "1", "B", "2" });
-
- // 2 markers & excess additional more keys.
- assertInsertAdditionalMoreKeys("0 more key & 2 additons & 2 markers",
- new String[] { "%", "%" },
- new String[] { "1", "2", "3" },
- new String[] { "1", "2", "3" });
- assertInsertAdditionalMoreKeys("1 more key & 2 additons & 2 markers at head",
- new String[] { "%", "%", "A" },
- new String[] { "1", "2", "3" },
- new String[] { "1", "2", "A", "3" });
- assertInsertAdditionalMoreKeys("1 more key & 2 additons & 2 markers at tail",
- new String[] { "A", "%", "%" },
- new String[] { "1", "2", "3" },
- new String[] { "A", "1", "2", "3" });
- assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at middle",
- new String[] { "A", "%", "%", "B" },
- new String[] { "1", "2", "3" },
- new String[] { "A", "1", "2", "B", "3" });
- assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at head & middle",
- new String[] { "%", "A", "%", "B" },
- new String[] { "1", "2", "3" },
- new String[] { "1", "A", "2", "B", "3" });
- assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at head & tail",
- new String[] { "%", "A", "B", "%" },
- new String[] { "1", "2", "3" },
- new String[] { "1", "A", "B", "2", "3" });
- assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at middle & tail",
- new String[] { "A", "%", "B", "%" },
- new String[] { "1", "2", "3" },
- new String[] { "A", "1", "B", "2", "3" });
-
- // 0 addtional more key and excess markers.
- assertInsertAdditionalMoreKeys("0 more key & null & excess marker",
- new String[] { "%" },
- null,
- null);
- assertInsertAdditionalMoreKeys("1 more key & null & excess marker at head",
- new String[] { "%", "A" },
- null,
- new String[] { "A" });
- assertInsertAdditionalMoreKeys("1 more key & null & excess marker at tail",
- new String[] { "A", "%" },
- null,
- new String[] { "A" });
- assertInsertAdditionalMoreKeys("2 more keys & null & excess marker at middle",
- new String[] { "A", "%", "B" },
- null,
- new String[] { "A", "B" });
- assertInsertAdditionalMoreKeys("2 more keys & null & excess markers",
- new String[] { "%", "A", "%", "B", "%" },
- null,
- new String[] { "A", "B" });
-
- // Excess markers.
- assertInsertAdditionalMoreKeys("0 more key & 1 additon & excess marker",
- new String[] { "%", "%" },
- new String[] { "1" },
- new String[] { "1" });
- assertInsertAdditionalMoreKeys("1 more key & 1 additon & excess marker at head",
- new String[] { "%", "%", "A" },
- new String[] { "1" },
- new String[] { "1", "A" });
- assertInsertAdditionalMoreKeys("1 more key & 1 additon & excess marker at tail",
- new String[] { "A", "%", "%" },
- new String[] { "1" },
- new String[] { "A", "1" });
- assertInsertAdditionalMoreKeys("2 more keys & 1 additon & excess marker at middle",
- new String[] { "A", "%", "%", "B" },
- new String[] { "1" },
- new String[] { "A", "1", "B" });
- assertInsertAdditionalMoreKeys("2 more keys & 1 additon & excess markers",
- new String[] { "%", "A", "%", "B", "%" },
- new String[] { "1" },
- new String[] { "1", "A", "B" });
- assertInsertAdditionalMoreKeys("2 more keys & 2 additons & excess markers",
- new String[] { "%", "A", "%", "B", "%" },
- new String[] { "1", "2" },
- new String[] { "1", "A", "2", "B" });
- assertInsertAdditionalMoreKeys("2 more keys & 3 additons & excess markers",
- new String[] { "%", "A", "%", "%", "B", "%" },
- new String[] { "1", "2", "3" },
- new String[] { "1", "A", "2", "3", "B" });
- }
-
- private static final String HAS_LABEL = "!hasLabel!";
- private static final String NEEDS_DIVIDER = "!needsDividers!";
- private static final String AUTO_COLUMN_ORDER = "!autoColumnOrder!";
- private static final String FIXED_COLUMN_ORDER = "!fixedColumnOrder!";
-
- private static void assertGetBooleanValue(String message, String key, String[] moreKeys,
- String[] expected, boolean expectedValue) {
- final String[] actual = Arrays.copyOf(moreKeys, moreKeys.length);
- final boolean actualValue = KeySpecParser.getBooleanValue(actual, key);
- assertEquals(message + " [value]", expectedValue, actualValue);
- assertArrayEquals(message, expected, actual);
- }
-
- public void testGetBooleanValue() {
- assertGetBooleanValue("Has label", HAS_LABEL,
- new String[] { HAS_LABEL, "a", "b", "c" },
- new String[] { null, "a", "b", "c" }, true);
- // Upper case specification will not work.
- assertGetBooleanValue("HAS LABEL", HAS_LABEL,
- new String[] { HAS_LABEL.toUpperCase(Locale.ROOT), "a", "b", "c" },
- new String[] { "!HASLABEL!", "a", "b", "c" }, false);
-
- assertGetBooleanValue("No has label", HAS_LABEL,
- new String[] { "a", "b", "c" },
- new String[] { "a", "b", "c" }, false);
- assertGetBooleanValue("No has label with fixed clumn order", HAS_LABEL,
- new String[] { FIXED_COLUMN_ORDER + "3", "a", "b", "c" },
- new String[] { FIXED_COLUMN_ORDER + "3", "a", "b", "c" }, false);
-
- // Upper case specification will not work.
- assertGetBooleanValue("Multiple has label", HAS_LABEL,
- new String[] {
- "a", HAS_LABEL.toUpperCase(Locale.ROOT), "b", "c", HAS_LABEL, "d" },
- new String[] {
- "a", "!HASLABEL!", "b", "c", null, "d" }, true);
- // Upper case specification will not work.
- assertGetBooleanValue("Multiple has label with needs dividers", HAS_LABEL,
- new String[] {
- "a", HAS_LABEL, "b", NEEDS_DIVIDER, HAS_LABEL.toUpperCase(Locale.ROOT), "d" },
- new String[] {
- "a", null, "b", NEEDS_DIVIDER, "!HASLABEL!", "d" }, true);
- }
-
- private static void assertGetIntValue(String message, String key, int defaultValue,
- String[] moreKeys, String[] expected, int expectedValue) {
- final String[] actual = Arrays.copyOf(moreKeys, moreKeys.length);
- final int actualValue = KeySpecParser.getIntValue(actual, key, defaultValue);
- assertEquals(message + " [value]", expectedValue, actualValue);
- assertArrayEquals(message, expected, actual);
- }
-
- public void testGetIntValue() {
- assertGetIntValue("Fixed column order 3", FIXED_COLUMN_ORDER, -1,
- new String[] { FIXED_COLUMN_ORDER + "3", "a", "b", "c" },
- new String[] { null, "a", "b", "c" }, 3);
- // Upper case specification will not work.
- assertGetIntValue("FIXED COLUMN ORDER 3", FIXED_COLUMN_ORDER, -1,
- new String[] { FIXED_COLUMN_ORDER.toUpperCase(Locale.ROOT) + "3", "a", "b", "c" },
- new String[] { "!FIXEDCOLUMNORDER!3", "a", "b", "c" }, -1);
-
- assertGetIntValue("No fixed column order", FIXED_COLUMN_ORDER, -1,
- new String[] { "a", "b", "c" },
- new String[] { "a", "b", "c" }, -1);
- assertGetIntValue("No fixed column order with auto column order", FIXED_COLUMN_ORDER, -1,
- new String[] { AUTO_COLUMN_ORDER + "5", "a", "b", "c" },
- new String[] { AUTO_COLUMN_ORDER + "5", "a", "b", "c" }, -1);
-
- assertGetIntValue("Multiple fixed column order 3,5", FIXED_COLUMN_ORDER, -1,
- new String[] { FIXED_COLUMN_ORDER + "3", "a", FIXED_COLUMN_ORDER + "5", "b" },
- new String[] { null, "a", null, "b" }, 3);
- // Upper case specification will not work.
- assertGetIntValue("Multiple fixed column order 5,3 with has label", FIXED_COLUMN_ORDER, -1,
- new String[] {
- FIXED_COLUMN_ORDER.toUpperCase(Locale.ROOT) + "5", HAS_LABEL, "a",
- FIXED_COLUMN_ORDER + "3", "b" },
- new String[] { "!FIXEDCOLUMNORDER!5", HAS_LABEL, "a", null, "b" }, 3);
}
}
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTestsBase.java b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTestsBase.java
new file mode 100644
index 000000000..c342533c8
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTestsBase.java
@@ -0,0 +1,353 @@
+/*
+ * 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.internal;
+
+import static com.android.inputmethod.keyboard.internal.KeyboardCodesSet.PREFIX_CODE;
+import static com.android.inputmethod.keyboard.internal.KeyboardIconsSet.ICON_UNDEFINED;
+import static com.android.inputmethod.keyboard.internal.KeyboardIconsSet.PREFIX_ICON;
+import static com.android.inputmethod.latin.Constants.CODE_OUTPUT_TEXT;
+import static com.android.inputmethod.latin.Constants.CODE_UNSPECIFIED;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+
+import com.android.inputmethod.latin.utils.RunInLocale;
+
+import java.util.Locale;
+
+abstract class KeySpecParserTestsBase extends AndroidTestCase {
+ private final static Locale TEST_LOCALE = Locale.ENGLISH;
+ protected final KeyboardTextsSet mTextsSet = new KeyboardTextsSet();
+
+ private static final String CODE_SETTINGS_NAME = "key_settings";
+ private static final String CODE_SETTINGS = PREFIX_CODE + CODE_SETTINGS_NAME;
+ private static final String ICON_SETTINGS_NAME = "settings_key";
+ private static final String ICON_SETTINGS = PREFIX_ICON + ICON_SETTINGS_NAME;
+ private static final String CODE_SETTINGS_UPPERCASE = CODE_SETTINGS.toUpperCase(Locale.ROOT);
+ private static final String ICON_SETTINGS_UPPERCASE = ICON_SETTINGS.toUpperCase(Locale.ROOT);
+ private static final String CODE_NON_EXISTING = PREFIX_CODE + "non_existing";
+ private static final String ICON_NON_EXISTING = PREFIX_ICON + "non_existing";
+
+ private int mCodeSettings;
+ private int mCodeActionNext;
+ private int mSettingsIconId;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mTextsSet.setLocale(TEST_LOCALE);
+ final Context context = getContext();
+ new RunInLocale<Void>() {
+ @Override
+ protected Void job(final Resources res) {
+ mTextsSet.loadStringResources(context);
+ return null;
+ }
+ }.runInLocale(context.getResources(), TEST_LOCALE);
+
+ mCodeSettings = KeyboardCodesSet.getCode(CODE_SETTINGS_NAME);
+ mCodeActionNext = KeyboardCodesSet.getCode("key_action_next");
+ mSettingsIconId = KeyboardIconsSet.getIconId(ICON_SETTINGS_NAME);
+ }
+
+ abstract protected void assertParser(final String message, final String keySpec,
+ final String expectedLabel, final String expectedOutputText, final int expectedIcon,
+ final int expectedCode);
+
+ protected void assertParserError(final String message, final String keySpec,
+ final String expectedLabel, final String expectedOutputText, final int expectedIconId,
+ final int expectedCode) {
+ try {
+ assertParser(message, keySpec, expectedLabel, expectedOutputText, expectedIconId,
+ expectedCode);
+ fail(message);
+ } catch (Exception pcpe) {
+ // success.
+ }
+ }
+
+ // \U001d11e: MUSICAL SYMBOL G CLEF
+ private static final String SURROGATE_PAIR1 = "\ud834\udd1e";
+ private static final int SURROGATE_CODE1 = SURROGATE_PAIR1.codePointAt(0);
+ // \U001d122: MUSICAL SYMBOL F CLEF
+ private static final String SURROGATE_PAIR2 = "\ud834\udd22";
+ private static final int SURROGATE_CODE2 = SURROGATE_PAIR2.codePointAt(0);
+ // \U002f8a6: CJK COMPATIBILITY IDEOGRAPH-2F8A6; variant character of \u6148.
+ private static final String SURROGATE_PAIR3 = "\ud87e\udca6";
+ private static final String SURROGATE_PAIRS4 = SURROGATE_PAIR1 + SURROGATE_PAIR2;
+ private static final String SURROGATE_PAIRS5 = SURROGATE_PAIRS4 + SURROGATE_PAIR3;
+
+ public void testSingleLetter() {
+ assertParser("Single letter", "a",
+ "a", null, ICON_UNDEFINED, 'a');
+ assertParser("Single surrogate", SURROGATE_PAIR1,
+ SURROGATE_PAIR1, null, ICON_UNDEFINED, SURROGATE_CODE1);
+ assertParser("Sole vertical bar", "|",
+ "|", null, ICON_UNDEFINED, '|');
+ assertParser("Single escaped vertical bar", "\\|",
+ "|", null, ICON_UNDEFINED, '|');
+ assertParser("Single escaped escape", "\\\\",
+ "\\", null, ICON_UNDEFINED, '\\');
+ assertParser("Single comma", ",",
+ ",", null, ICON_UNDEFINED, ',');
+ assertParser("Single escaped comma", "\\,",
+ ",", null, ICON_UNDEFINED, ',');
+ assertParser("Single escaped letter", "\\a",
+ "a", null, ICON_UNDEFINED, 'a');
+ assertParser("Single escaped surrogate", "\\" + SURROGATE_PAIR2,
+ SURROGATE_PAIR2, null, ICON_UNDEFINED, SURROGATE_CODE2);
+ assertParser("Single bang", "!",
+ "!", null, ICON_UNDEFINED, '!');
+ assertParser("Single escaped bang", "\\!",
+ "!", null, ICON_UNDEFINED, '!');
+ assertParser("Single output text letter", "a|a",
+ "a", null, ICON_UNDEFINED, 'a');
+ assertParser("Single surrogate pair outputText", "G Clef|" + SURROGATE_PAIR1,
+ "G Clef", null, ICON_UNDEFINED, SURROGATE_CODE1);
+ assertParser("Single letter with outputText", "a|abc",
+ "a", "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Single letter with surrogate outputText", "a|" + SURROGATE_PAIRS4,
+ "a", SURROGATE_PAIRS4, ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Single surrogate with outputText", SURROGATE_PAIR3 + "|abc",
+ SURROGATE_PAIR3, "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Single letter with escaped outputText", "a|a\\|c",
+ "a", "a|c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Single letter with escaped surrogate outputText",
+ "a|" + SURROGATE_PAIR1 + "\\|" + SURROGATE_PAIR2,
+ "a", SURROGATE_PAIR1 + "|" + SURROGATE_PAIR2, ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Single letter with comma outputText", "a|a,b",
+ "a", "a,b", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Single letter with escaped comma outputText", "a|a\\,b",
+ "a", "a,b", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Single letter with outputText starts with bang", "a|!bc",
+ "a", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Single letter with surrogate outputText starts with bang",
+ "a|!" + SURROGATE_PAIRS5,
+ "a", "!" + SURROGATE_PAIRS5, ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Single letter with outputText contains bang", "a|a!c",
+ "a", "a!c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Single letter with escaped bang outputText", "a|\\!bc",
+ "a", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Single escaped escape with single outputText", "\\\\|\\\\",
+ "\\", null, ICON_UNDEFINED, '\\');
+ assertParser("Single escaped bar with single outputText", "\\||\\|",
+ "|", null, ICON_UNDEFINED, '|');
+ assertParser("Single letter with code", "a|" + CODE_SETTINGS,
+ "a", null, ICON_UNDEFINED, mCodeSettings);
+ }
+
+ public void testLabel() {
+ assertParser("Simple label", "abc",
+ "abc", "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Simple surrogate label", SURROGATE_PAIRS4,
+ SURROGATE_PAIRS4, SURROGATE_PAIRS4, ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with escaped bar", "a\\|c",
+ "a|c", "a|c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Surrogate label with escaped bar", SURROGATE_PAIR1 + "\\|" + SURROGATE_PAIR2,
+ SURROGATE_PAIR1 + "|" + SURROGATE_PAIR2, SURROGATE_PAIR1 + "|" + SURROGATE_PAIR2,
+ ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with escaped escape", "a\\\\c",
+ "a\\c", "a\\c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with comma", "a,c",
+ "a,c", "a,c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with escaped comma", "a\\,c",
+ "a,c", "a,c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label starts with bang", "!bc",
+ "!bc", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Surrogate label starts with bang", "!" + SURROGATE_PAIRS4,
+ "!" + SURROGATE_PAIRS4, "!" + SURROGATE_PAIRS4, ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label contains bang", "a!c",
+ "a!c", "a!c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with escaped bang", "\\!bc",
+ "!bc", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with escaped letter", "\\abc",
+ "abc", "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with outputText", "abc|def",
+ "abc", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with comma and outputText", "a,c|def",
+ "a,c", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Escaped comma label with outputText", "a\\,c|def",
+ "a,c", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Escaped label with outputText", "a\\|c|def",
+ "a|c", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with escaped bar outputText", "abc|d\\|f",
+ "abc", "d|f", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Escaped escape label with outputText", "a\\\\|def",
+ "a\\", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label starts with bang and outputText", "!bc|def",
+ "!bc", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label contains bang label and outputText", "a!c|def",
+ "a!c", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Escaped bang label with outputText", "\\!bc|def",
+ "!bc", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with comma outputText", "abc|a,b",
+ "abc", "a,b", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with escaped comma outputText", "abc|a\\,b",
+ "abc", "a,b", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with outputText starts with bang", "abc|!bc",
+ "abc", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with outputText contains bang", "abc|a!c",
+ "abc", "a!c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with escaped bang outputText", "abc|\\!bc",
+ "abc", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with escaped bar outputText", "abc|d\\|f",
+ "abc", "d|f", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Escaped bar label with escaped bar outputText", "a\\|c|d\\|f",
+ "a|c", "d|f", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with code", "abc|" + CODE_SETTINGS,
+ "abc", null, ICON_UNDEFINED, mCodeSettings);
+ assertParser("Escaped label with code", "a\\|c|" + CODE_SETTINGS,
+ "a|c", null, ICON_UNDEFINED, mCodeSettings);
+ }
+
+ public void testCodes() {
+ assertParser("Hexadecimal code", "a|0x1000",
+ "a", null, ICON_UNDEFINED, 0x1000);
+ assertParserError("Illegal hexadecimal code", "a|0x100X",
+ "a", null, ICON_UNDEFINED, CODE_UNSPECIFIED);
+ assertParser("Escaped hexadecimal code 1", "a|\\0x1000",
+ "a", "0x1000", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Escaped hexadecimal code 2", "a|0\\x1000",
+ "a", "0x1000", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Escaped hexadecimal code 2", "a|0\\x1000",
+ "a", "0x1000", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParserError("Illegally escaped hexadecimal code", "a|0x1\\000",
+ "a", null, ICON_UNDEFINED, CODE_UNSPECIFIED);
+ // This is a workaround to have a key that has a supplementary code point. We can't put a
+ // string in resource as a XML entity of a supplementary code point or a surrogate pair.
+ // TODO: Should pass this test.
+// assertParser("Hexadecimal supplementary code", String.format("a|0x%06x", SURROGATE_CODE2),
+// SURROGATE_PAIR2, null, ICON_UNDEFINED, SURROGATE_CODE2);
+ assertParser("Zero is treated as output text", "a|0",
+ "a", null, ICON_UNDEFINED, '0');
+ assertParser("Digit is treated as output text", "a|3",
+ "a", null, ICON_UNDEFINED, '3');
+ assertParser("Decimal number is treated as an output text", "a|2014",
+ "a", "2014", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ }
+
+ public void testIcons() {
+ assertParser("Icon with single letter", ICON_SETTINGS + "|a",
+ null, null, mSettingsIconId, 'a');
+ assertParser("Icon with outputText", ICON_SETTINGS + "|abc",
+ null, "abc", mSettingsIconId, CODE_OUTPUT_TEXT);
+ assertParser("Icon with outputText starts with bang", ICON_SETTINGS + "|!bc",
+ null, "!bc", mSettingsIconId, CODE_OUTPUT_TEXT);
+ assertParser("Icon with outputText contains bang", ICON_SETTINGS + "|a!c",
+ null, "a!c", mSettingsIconId, CODE_OUTPUT_TEXT);
+ assertParser("Icon with escaped bang outputText", ICON_SETTINGS + "|\\!bc",
+ null, "!bc", mSettingsIconId, CODE_OUTPUT_TEXT);
+ assertParser("Label starts with bang and code", "!bc|" + CODE_SETTINGS,
+ "!bc", null, ICON_UNDEFINED, mCodeSettings);
+ assertParser("Label contains bang and code", "a!c|" + CODE_SETTINGS,
+ "a!c", null, ICON_UNDEFINED, mCodeSettings);
+ assertParser("Escaped bang label with code", "\\!bc|" + CODE_SETTINGS,
+ "!bc", null, ICON_UNDEFINED, mCodeSettings);
+ assertParser("Icon with code", ICON_SETTINGS + "|" + CODE_SETTINGS,
+ null, null, mSettingsIconId, mCodeSettings);
+ }
+
+ public void testResourceReference() {
+ assertParser("Settings as more key", "!text/settings_as_more_key",
+ null, null, mSettingsIconId, mCodeSettings);
+
+ assertParser("Action next as more key", "!text/label_next_key|!code/key_action_next",
+ "Next", null, ICON_UNDEFINED, mCodeActionNext);
+
+ assertParser("Popular domain",
+ "!text/keylabel_for_popular_domain|!text/keylabel_for_popular_domain ",
+ ".com", ".com ", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ }
+
+ public void testFormatError() {
+ assertParserError("Empty label with outputText", "|a",
+ null, "a", ICON_UNDEFINED, CODE_UNSPECIFIED);
+ assertParserError("Empty label with code", "|" + CODE_SETTINGS,
+ null, null, ICON_UNDEFINED, mCodeSettings);
+ assertParserError("Empty outputText with label", "a|",
+ "a", null, ICON_UNDEFINED, CODE_UNSPECIFIED);
+ assertParserError("Empty outputText with icon", ICON_SETTINGS + "|",
+ null, null, mSettingsIconId, CODE_UNSPECIFIED);
+ assertParserError("Icon without code", ICON_SETTINGS,
+ null, null, mSettingsIconId, CODE_UNSPECIFIED);
+ assertParserError("Non existing icon", ICON_NON_EXISTING + "|abc",
+ null, "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParserError("Non existing code", "abc|" + CODE_NON_EXISTING,
+ "abc", null, ICON_UNDEFINED, CODE_UNSPECIFIED);
+ assertParserError("Third bar at end", "a|b|",
+ "a", null, ICON_UNDEFINED, CODE_UNSPECIFIED);
+ assertParserError("Multiple bar", "a|b|c",
+ "a", null, ICON_UNDEFINED, CODE_UNSPECIFIED);
+ assertParserError("Multiple bar with label and code", "a|" + CODE_SETTINGS + "|c",
+ "a", null, ICON_UNDEFINED, mCodeSettings);
+ assertParserError("Multiple bar with icon and outputText", ICON_SETTINGS + "|b|c",
+ null, null, mSettingsIconId, CODE_UNSPECIFIED);
+ assertParserError("Multiple bar with icon and code",
+ ICON_SETTINGS + "|" + CODE_SETTINGS + "|c",
+ null, null, mSettingsIconId, mCodeSettings);
+ }
+
+ public void testUselessUpperCaseSpecifier() {
+ assertParser("Single letter with CODE", "a|" + CODE_SETTINGS_UPPERCASE,
+ "a", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label with CODE", "abc|" + CODE_SETTINGS_UPPERCASE,
+ "abc", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Escaped label with CODE", "a\\|c|" + CODE_SETTINGS_UPPERCASE,
+ "a|c", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("ICON with outputText", ICON_SETTINGS_UPPERCASE + "|abc",
+ "!ICON/SETTINGS_KEY", "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("ICON with outputText starts with bang", ICON_SETTINGS_UPPERCASE + "|!bc",
+ "!ICON/SETTINGS_KEY", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("ICON with outputText contains bang", ICON_SETTINGS_UPPERCASE + "|a!c",
+ "!ICON/SETTINGS_KEY", "a!c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("ICON with escaped bang outputText", ICON_SETTINGS_UPPERCASE + "|\\!bc",
+ "!ICON/SETTINGS_KEY", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label starts with bang and CODE", "!bc|" + CODE_SETTINGS_UPPERCASE,
+ "!bc", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Label contains bang and CODE", "a!c|" + CODE_SETTINGS_UPPERCASE,
+ "a!c", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("Escaped bang label with CODE", "\\!bc|" + CODE_SETTINGS_UPPERCASE,
+ "!bc", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("ICON with CODE", ICON_SETTINGS_UPPERCASE + "|" + CODE_SETTINGS_UPPERCASE,
+ "!ICON/SETTINGS_KEY", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParser("SETTINGS AS MORE KEY", "!TEXT/SETTINGS_AS_MORE_KEY",
+ "!TEXT/SETTINGS_AS_MORE_KEY", "!TEXT/SETTINGS_AS_MORE_KEY", ICON_UNDEFINED,
+ CODE_OUTPUT_TEXT);
+ assertParser("ACTION NEXT AS MORE KEY", "!TEXT/LABEL_NEXT_KEY|!CODE/KEY_ACTION_NEXT",
+ "!TEXT/LABEL_NEXT_KEY", "!CODE/KEY_ACTION_NEXT", ICON_UNDEFINED,
+ CODE_OUTPUT_TEXT);
+ assertParser("POPULAR DOMAIN",
+ "!TEXT/KEYLABEL_FOR_POPULAR_DOMAIN|!TEXT/KEYLABEL_FOR_POPULAR_DOMAIN ",
+ "!TEXT/KEYLABEL_FOR_POPULAR_DOMAIN", "!TEXT/KEYLABEL_FOR_POPULAR_DOMAIN ",
+ ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParserError("Empty label with CODE", "|" + CODE_SETTINGS_UPPERCASE,
+ null, null, ICON_UNDEFINED, mCodeSettings);
+ assertParserError("Empty outputText with ICON", ICON_SETTINGS_UPPERCASE + "|",
+ null, null, mSettingsIconId, CODE_UNSPECIFIED);
+ assertParser("ICON without code", ICON_SETTINGS_UPPERCASE,
+ "!ICON/SETTINGS_KEY", "!ICON/SETTINGS_KEY", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
+ assertParserError("Multiple bar with label and CODE", "a|" + CODE_SETTINGS_UPPERCASE + "|c",
+ "a", null, ICON_UNDEFINED, mCodeSettings);
+ assertParserError("Multiple bar with ICON and outputText", ICON_SETTINGS_UPPERCASE + "|b|c",
+ null, null, mSettingsIconId, CODE_UNSPECIFIED);
+ assertParserError("Multiple bar with ICON and CODE",
+ ICON_SETTINGS_UPPERCASE + "|" + CODE_SETTINGS_UPPERCASE + "|c",
+ null, null, mSettingsIconId, mCodeSettings);
+ }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserSplitTests.java b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java
index 2eb448c82..42a94f420 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserSplitTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java
@@ -31,7 +31,7 @@ import java.util.Arrays;
import java.util.Locale;
@MediumTest
-public class KeySpecParserSplitTests extends InstrumentationTestCase {
+public class MoreKeySpecSplitTests extends InstrumentationTestCase {
private static final Locale TEST_LOCALE = Locale.ENGLISH;
final KeyboardTextsSet mTextsSet = new KeyboardTextsSet();
@@ -41,7 +41,7 @@ public class KeySpecParserSplitTests extends InstrumentationTestCase {
final Instrumentation instrumentation = getInstrumentation();
final Context targetContext = instrumentation.getTargetContext();
- mTextsSet.setLanguage(TEST_LOCALE.getLanguage());
+ mTextsSet.setLocale(TEST_LOCALE);
new RunInLocale<Void>() {
@Override
protected Void job(final Resources res) {
@@ -92,8 +92,8 @@ public class KeySpecParserSplitTests extends InstrumentationTestCase {
private void assertTextArray(final String message, final String value,
final String ... expectedArray) {
- final String resolvedActual = KeySpecParser.resolveTextReference(value, mTextsSet);
- final String[] actual = KeySpecParser.splitKeySpecs(resolvedActual);
+ final String resolvedActual = mTextsSet.resolveTextReference(value);
+ final String[] actual = MoreKeySpec.splitKeySpecs(resolvedActual);
final String[] expected = (expectedArray.length == 0) ? null : expectedArray;
assertArrayEquals(message, expected, actual);
}
@@ -116,6 +116,14 @@ public class KeySpecParserSplitTests extends InstrumentationTestCase {
private static final String SURROGATE1 = PAIR1 + PAIR2;
private static final String SURROGATE2 = PAIR1 + PAIR2 + PAIR3;
+ public void testResolveNullText() {
+ assertNull("resolve null", mTextsSet.resolveTextReference(null));
+ }
+
+ public void testResolveEmptyText() {
+ assertNull("resolve empty text", mTextsSet.resolveTextReference("!text/empty_string"));
+ }
+
public void testSplitZero() {
assertTextArray("Empty string", "");
assertTextArray("Empty entry", ",");
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecTests.java b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecTests.java
new file mode 100644
index 000000000..6c0d74941
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecTests.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2010 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.internal;
+
+import static com.android.inputmethod.keyboard.internal.KeyboardIconsSet.ICON_UNDEFINED;
+import static com.android.inputmethod.latin.Constants.CODE_UNSPECIFIED;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.inputmethod.latin.Constants;
+
+import java.util.Arrays;
+import java.util.Locale;
+
+@SmallTest
+public final class MoreKeySpecTests extends KeySpecParserTestsBase {
+ @Override
+ protected void assertParser(final String message, final String moreKeySpec,
+ final String expectedLabel, final String expectedOutputText, final int expectedIconId,
+ final int expectedCode) {
+ final String labelResolved = mTextsSet.resolveTextReference(moreKeySpec);
+ final MoreKeySpec spec = new MoreKeySpec(
+ labelResolved, false /* needsToUpperCase */, Locale.US);
+ assertEquals(message + " [label]", expectedLabel, spec.mLabel);
+ assertEquals(message + " [ouptputText]", expectedOutputText, spec.mOutputText);
+ assertEquals(message + " [icon]",
+ KeyboardIconsSet.getIconName(expectedIconId),
+ KeyboardIconsSet.getIconName(spec.mIconId));
+ assertEquals(message + " [code]",
+ Constants.printableCode(expectedCode),
+ Constants.printableCode(spec.mCode));
+ }
+
+ // TODO: Move this method to {@link KeySpecParserBase}.
+ public void testEmptySpec() {
+ assertParserError("Null spec", null,
+ null, null, ICON_UNDEFINED, CODE_UNSPECIFIED);
+ assertParserError("Empty spec", "",
+ null, null, ICON_UNDEFINED, CODE_UNSPECIFIED);
+ }
+
+ private static void assertArrayEquals(final String message, final Object[] expected,
+ final Object[] actual) {
+ if (expected == actual) {
+ return;
+ }
+ if (expected == null || actual == null) {
+ assertEquals(message, Arrays.toString(expected), Arrays.toString(actual));
+ return;
+ }
+ if (expected.length != actual.length) {
+ assertEquals(message + " [length]", Arrays.toString(expected), Arrays.toString(actual));
+ return;
+ }
+ for (int i = 0; i < expected.length; i++) {
+ assertEquals(message + " [" + i + "]",
+ Arrays.toString(expected), Arrays.toString(actual));
+ }
+ }
+
+ private static void assertInsertAdditionalMoreKeys(final String message,
+ final String[] moreKeys, final String[] additionalMoreKeys, final String[] expected) {
+ final String[] actual = MoreKeySpec.insertAdditionalMoreKeys(moreKeys, additionalMoreKeys);
+ assertArrayEquals(message, expected, actual);
+ }
+
+ public void testEmptyEntry() {
+ assertInsertAdditionalMoreKeys("null more keys and null additons",
+ null,
+ null,
+ null);
+ assertInsertAdditionalMoreKeys("null more keys and empty additons",
+ null,
+ new String[0],
+ null);
+ assertInsertAdditionalMoreKeys("empty more keys and null additons",
+ new String[0],
+ null,
+ null);
+ assertInsertAdditionalMoreKeys("empty more keys and empty additons",
+ new String[0],
+ new String[0],
+ null);
+
+ assertInsertAdditionalMoreKeys("filter out empty more keys",
+ new String[] { null, "a", "", "b", null },
+ null,
+ new String[] { "a", "b" });
+ assertInsertAdditionalMoreKeys("filter out empty additons",
+ new String[] { "a", "%", "b", "%", "c", "%", "d" },
+ new String[] { null, "A", "", "B", null },
+ new String[] { "a", "A", "b", "B", "c", "d" });
+ }
+
+ public void testInsertAdditionalMoreKeys() {
+ // Escaped marker.
+ assertInsertAdditionalMoreKeys("escaped marker",
+ new String[] { "\\%", "%-)" },
+ new String[] { "1", "2" },
+ new String[] { "1", "2", "\\%", "%-)" });
+
+ // 0 more key.
+ assertInsertAdditionalMoreKeys("null & null", null, null, null);
+ assertInsertAdditionalMoreKeys("null & 1 additon",
+ null,
+ new String[] { "1" },
+ new String[] { "1" });
+ assertInsertAdditionalMoreKeys("null & 2 additons",
+ null,
+ new String[] { "1", "2" },
+ new String[] { "1", "2" });
+
+ // 0 additional more key.
+ assertInsertAdditionalMoreKeys("1 more key & null",
+ new String[] { "A" },
+ null,
+ new String[] { "A" });
+ assertInsertAdditionalMoreKeys("2 more keys & null",
+ new String[] { "A", "B" },
+ null,
+ new String[] { "A", "B" });
+
+ // No marker.
+ assertInsertAdditionalMoreKeys("1 more key & 1 addtional & no marker",
+ new String[] { "A" },
+ new String[] { "1" },
+ new String[] { "1", "A" });
+ assertInsertAdditionalMoreKeys("1 more key & 2 addtionals & no marker",
+ new String[] { "A" },
+ new String[] { "1", "2" },
+ new String[] { "1", "2", "A" });
+ assertInsertAdditionalMoreKeys("2 more keys & 1 addtional & no marker",
+ new String[] { "A", "B" },
+ new String[] { "1" },
+ new String[] { "1", "A", "B" });
+ assertInsertAdditionalMoreKeys("2 more keys & 2 addtionals & no marker",
+ new String[] { "A", "B" },
+ new String[] { "1", "2" },
+ new String[] { "1", "2", "A", "B" });
+
+ // 1 marker.
+ assertInsertAdditionalMoreKeys("1 more key & 1 additon & marker at head",
+ new String[] { "%", "A" },
+ new String[] { "1" },
+ new String[] { "1", "A" });
+ assertInsertAdditionalMoreKeys("1 more key & 1 additon & marker at tail",
+ new String[] { "A", "%" },
+ new String[] { "1" },
+ new String[] { "A", "1" });
+ assertInsertAdditionalMoreKeys("2 more keys & 1 additon & marker at middle",
+ new String[] { "A", "%", "B" },
+ new String[] { "1" },
+ new String[] { "A", "1", "B" });
+
+ // 1 marker & excess additional more keys.
+ assertInsertAdditionalMoreKeys("1 more key & 2 additons & marker at head",
+ new String[] { "%", "A", "B" },
+ new String[] { "1", "2" },
+ new String[] { "1", "A", "B", "2" });
+ assertInsertAdditionalMoreKeys("1 more key & 2 additons & marker at tail",
+ new String[] { "A", "B", "%" },
+ new String[] { "1", "2" },
+ new String[] { "A", "B", "1", "2" });
+ assertInsertAdditionalMoreKeys("2 more keys & 2 additons & marker at middle",
+ new String[] { "A", "%", "B" },
+ new String[] { "1", "2" },
+ new String[] { "A", "1", "B", "2" });
+
+ // 2 markers.
+ assertInsertAdditionalMoreKeys("0 more key & 2 addtional & 2 markers",
+ new String[] { "%", "%" },
+ new String[] { "1", "2" },
+ new String[] { "1", "2" });
+ assertInsertAdditionalMoreKeys("1 more key & 2 addtional & 2 markers at head",
+ new String[] { "%", "%", "A" },
+ new String[] { "1", "2" },
+ new String[] { "1", "2", "A" });
+ assertInsertAdditionalMoreKeys("1 more key & 2 addtional & 2 markers at tail",
+ new String[] { "A", "%", "%" },
+ new String[] { "1", "2" },
+ new String[] { "A", "1", "2" });
+ assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at middle",
+ new String[] { "A", "%", "%", "B" },
+ new String[] { "1", "2" },
+ new String[] { "A", "1", "2", "B" });
+ assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at head & middle",
+ new String[] { "%", "A", "%", "B" },
+ new String[] { "1", "2" },
+ new String[] { "1", "A", "2", "B" });
+ assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at head & tail",
+ new String[] { "%", "A", "B", "%" },
+ new String[] { "1", "2" },
+ new String[] { "1", "A", "B", "2" });
+ assertInsertAdditionalMoreKeys("2 more keys & 2 addtional & 2 markers at middle & tail",
+ new String[] { "A", "%", "B", "%" },
+ new String[] { "1", "2" },
+ new String[] { "A", "1", "B", "2" });
+
+ // 2 markers & excess additional more keys.
+ assertInsertAdditionalMoreKeys("0 more key & 2 additons & 2 markers",
+ new String[] { "%", "%" },
+ new String[] { "1", "2", "3" },
+ new String[] { "1", "2", "3" });
+ assertInsertAdditionalMoreKeys("1 more key & 2 additons & 2 markers at head",
+ new String[] { "%", "%", "A" },
+ new String[] { "1", "2", "3" },
+ new String[] { "1", "2", "A", "3" });
+ assertInsertAdditionalMoreKeys("1 more key & 2 additons & 2 markers at tail",
+ new String[] { "A", "%", "%" },
+ new String[] { "1", "2", "3" },
+ new String[] { "A", "1", "2", "3" });
+ assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at middle",
+ new String[] { "A", "%", "%", "B" },
+ new String[] { "1", "2", "3" },
+ new String[] { "A", "1", "2", "B", "3" });
+ assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at head & middle",
+ new String[] { "%", "A", "%", "B" },
+ new String[] { "1", "2", "3" },
+ new String[] { "1", "A", "2", "B", "3" });
+ assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at head & tail",
+ new String[] { "%", "A", "B", "%" },
+ new String[] { "1", "2", "3" },
+ new String[] { "1", "A", "B", "2", "3" });
+ assertInsertAdditionalMoreKeys("2 more keys & 2 additons & 2 markers at middle & tail",
+ new String[] { "A", "%", "B", "%" },
+ new String[] { "1", "2", "3" },
+ new String[] { "A", "1", "B", "2", "3" });
+
+ // 0 addtional more key and excess markers.
+ assertInsertAdditionalMoreKeys("0 more key & null & excess marker",
+ new String[] { "%" },
+ null,
+ null);
+ assertInsertAdditionalMoreKeys("1 more key & null & excess marker at head",
+ new String[] { "%", "A" },
+ null,
+ new String[] { "A" });
+ assertInsertAdditionalMoreKeys("1 more key & null & excess marker at tail",
+ new String[] { "A", "%" },
+ null,
+ new String[] { "A" });
+ assertInsertAdditionalMoreKeys("2 more keys & null & excess marker at middle",
+ new String[] { "A", "%", "B" },
+ null,
+ new String[] { "A", "B" });
+ assertInsertAdditionalMoreKeys("2 more keys & null & excess markers",
+ new String[] { "%", "A", "%", "B", "%" },
+ null,
+ new String[] { "A", "B" });
+
+ // Excess markers.
+ assertInsertAdditionalMoreKeys("0 more key & 1 additon & excess marker",
+ new String[] { "%", "%" },
+ new String[] { "1" },
+ new String[] { "1" });
+ assertInsertAdditionalMoreKeys("1 more key & 1 additon & excess marker at head",
+ new String[] { "%", "%", "A" },
+ new String[] { "1" },
+ new String[] { "1", "A" });
+ assertInsertAdditionalMoreKeys("1 more key & 1 additon & excess marker at tail",
+ new String[] { "A", "%", "%" },
+ new String[] { "1" },
+ new String[] { "A", "1" });
+ assertInsertAdditionalMoreKeys("2 more keys & 1 additon & excess marker at middle",
+ new String[] { "A", "%", "%", "B" },
+ new String[] { "1" },
+ new String[] { "A", "1", "B" });
+ assertInsertAdditionalMoreKeys("2 more keys & 1 additon & excess markers",
+ new String[] { "%", "A", "%", "B", "%" },
+ new String[] { "1" },
+ new String[] { "1", "A", "B" });
+ assertInsertAdditionalMoreKeys("2 more keys & 2 additons & excess markers",
+ new String[] { "%", "A", "%", "B", "%" },
+ new String[] { "1", "2" },
+ new String[] { "1", "A", "2", "B" });
+ assertInsertAdditionalMoreKeys("2 more keys & 3 additons & excess markers",
+ new String[] { "%", "A", "%", "%", "B", "%" },
+ new String[] { "1", "2", "3" },
+ new String[] { "1", "A", "2", "3", "B" });
+ }
+
+ private static final String HAS_LABEL = "!hasLabel!";
+ private static final String NEEDS_DIVIDER = "!needsDividers!";
+ private static final String AUTO_COLUMN_ORDER = "!autoColumnOrder!";
+ private static final String FIXED_COLUMN_ORDER = "!fixedColumnOrder!";
+
+ private static void assertGetBooleanValue(final String message, final String key,
+ final String[] moreKeys, final String[] expected, final boolean expectedValue) {
+ final String[] actual = Arrays.copyOf(moreKeys, moreKeys.length);
+ final boolean actualValue = MoreKeySpec.getBooleanValue(actual, key);
+ assertEquals(message + " [value]", expectedValue, actualValue);
+ assertArrayEquals(message, expected, actual);
+ }
+
+ public void testGetBooleanValue() {
+ assertGetBooleanValue("Has label", HAS_LABEL,
+ new String[] { HAS_LABEL, "a", "b", "c" },
+ new String[] { null, "a", "b", "c" }, true);
+ // Upper case specification will not work.
+ assertGetBooleanValue("HAS LABEL", HAS_LABEL,
+ new String[] { HAS_LABEL.toUpperCase(Locale.ROOT), "a", "b", "c" },
+ new String[] { "!HASLABEL!", "a", "b", "c" }, false);
+
+ assertGetBooleanValue("No has label", HAS_LABEL,
+ new String[] { "a", "b", "c" },
+ new String[] { "a", "b", "c" }, false);
+ assertGetBooleanValue("No has label with fixed clumn order", HAS_LABEL,
+ new String[] { FIXED_COLUMN_ORDER + "3", "a", "b", "c" },
+ new String[] { FIXED_COLUMN_ORDER + "3", "a", "b", "c" }, false);
+
+ // Upper case specification will not work.
+ assertGetBooleanValue("Multiple has label", HAS_LABEL,
+ new String[] {
+ "a", HAS_LABEL.toUpperCase(Locale.ROOT), "b", "c", HAS_LABEL, "d" },
+ new String[] {
+ "a", "!HASLABEL!", "b", "c", null, "d" }, true);
+ // Upper case specification will not work.
+ assertGetBooleanValue("Multiple has label with needs dividers", HAS_LABEL,
+ new String[] {
+ "a", HAS_LABEL, "b", NEEDS_DIVIDER, HAS_LABEL.toUpperCase(Locale.ROOT), "d" },
+ new String[] {
+ "a", null, "b", NEEDS_DIVIDER, "!HASLABEL!", "d" }, true);
+ }
+
+ private static void assertGetIntValue(final String message, final String key,
+ final int defaultValue, final String[] moreKeys, final String[] expected,
+ final int expectedValue) {
+ final String[] actual = Arrays.copyOf(moreKeys, moreKeys.length);
+ final int actualValue = MoreKeySpec.getIntValue(actual, key, defaultValue);
+ assertEquals(message + " [value]", expectedValue, actualValue);
+ assertArrayEquals(message, expected, actual);
+ }
+
+ public void testGetIntValue() {
+ assertGetIntValue("Fixed column order 3", FIXED_COLUMN_ORDER, -1,
+ new String[] { FIXED_COLUMN_ORDER + "3", "a", "b", "c" },
+ new String[] { null, "a", "b", "c" }, 3);
+ // Upper case specification will not work.
+ assertGetIntValue("FIXED COLUMN ORDER 3", FIXED_COLUMN_ORDER, -1,
+ new String[] { FIXED_COLUMN_ORDER.toUpperCase(Locale.ROOT) + "3", "a", "b", "c" },
+ new String[] { "!FIXEDCOLUMNORDER!3", "a", "b", "c" }, -1);
+
+ assertGetIntValue("No fixed column order", FIXED_COLUMN_ORDER, -1,
+ new String[] { "a", "b", "c" },
+ new String[] { "a", "b", "c" }, -1);
+ assertGetIntValue("No fixed column order with auto column order", FIXED_COLUMN_ORDER, -1,
+ new String[] { AUTO_COLUMN_ORDER + "5", "a", "b", "c" },
+ new String[] { AUTO_COLUMN_ORDER + "5", "a", "b", "c" }, -1);
+
+ assertGetIntValue("Multiple fixed column order 3,5", FIXED_COLUMN_ORDER, -1,
+ new String[] { FIXED_COLUMN_ORDER + "3", "a", FIXED_COLUMN_ORDER + "5", "b" },
+ new String[] { null, "a", null, "b" }, 3);
+ // Upper case specification will not work.
+ assertGetIntValue("Multiple fixed column order 5,3 with has label", FIXED_COLUMN_ORDER, -1,
+ new String[] {
+ FIXED_COLUMN_ORDER.toUpperCase(Locale.ROOT) + "5", HAS_LABEL, "a",
+ FIXED_COLUMN_ORDER + "3", "b" },
+ new String[] { "!FIXEDCOLUMNORDER!5", HAS_LABEL, "a", null, "b" }, 3);
+ }
+}
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueueTests.java b/tests/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueueTests.java
index 279559cfe..7908b260e 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueueTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueueTests.java
@@ -27,7 +27,7 @@ public class PointerTrackerQueueTests extends AndroidTestCase {
public final int mId;
public boolean mIsModifier;
- public boolean mIsInSlidingKeyInput;
+ public boolean mIsInDraggingFinger;
public long mPhantomUpEventTime = NOT_HAPPENED;
public Element(int id) {
@@ -40,8 +40,8 @@ public class PointerTrackerQueueTests extends AndroidTestCase {
}
@Override
- public boolean isInSlidingKeyInput() {
- return mIsInSlidingKeyInput;
+ public boolean isInDraggingFinger() {
+ return mIsInDraggingFinger;
}
@Override
@@ -297,19 +297,19 @@ public class PointerTrackerQueueTests extends AndroidTestCase {
assertEquals(Element.NOT_HAPPENED, mElement4.mPhantomUpEventTime);
}
- public void testIsAnyInSlidingKeyInput() {
+ public void testIsAnyInDraggingFinger() {
Element.sPhantomUpCount = 0;
- assertFalse(mQueue.isAnyInSlidingKeyInput());
+ assertFalse(mQueue.isAnyInDraggingFinger());
mQueue.add(mElement1);
mQueue.add(mElement2);
mQueue.add(mElement3);
mQueue.add(mElement4);
- assertFalse(mQueue.isAnyInSlidingKeyInput());
+ assertFalse(mQueue.isAnyInDraggingFinger());
- mElement3.mIsInSlidingKeyInput = true;
- assertTrue(mQueue.isAnyInSlidingKeyInput());
+ mElement3.mIsInDraggingFinger = true;
+ assertTrue(mQueue.isAnyInDraggingFinger());
assertEquals(0, Element.sPhantomUpCount);
assertEquals(4, mQueue.size());
diff --git a/tests/src/com/android/inputmethod/latin/AppWorkaroundsTests.java b/tests/src/com/android/inputmethod/latin/AppWorkaroundsTests.java
new file mode 100644
index 000000000..c29257d34
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/AppWorkaroundsTests.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013 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.latin;
+
+import com.android.inputmethod.latin.settings.Settings;
+
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Build.VERSION_CODES;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.view.inputmethod.EditorInfo;
+
+@LargeTest
+public class AppWorkaroundsTests extends InputTestsBase {
+ String packageNameOfAppBeforeJellyBean;
+ String packageNameOfAppAfterJellyBean;
+
+ @Override
+ protected void setUp() throws Exception {
+ // NOTE: this will fail if there is no app installed that targets an SDK
+ // before Jelly Bean. For the moment, it's fine.
+ final PackageManager pm = getContext().getPackageManager();
+ for (ApplicationInfo ai : pm.getInstalledApplications(0 /* flags */)) {
+ if (ai.targetSdkVersion < VERSION_CODES.JELLY_BEAN) {
+ packageNameOfAppBeforeJellyBean = ai.packageName;
+ } else {
+ packageNameOfAppAfterJellyBean = ai.packageName;
+ }
+ }
+ super.setUp();
+ }
+
+ // We want to test if the app package info is correctly retrieved by LatinIME. Since it
+ // asks this information to the package manager from the package name, and that it takes
+ // the package name from the EditorInfo, all we have to do it put the correct package
+ // name in the editor info.
+ // To this end, our base class InputTestsBase offers a hook for us to touch the EditorInfo.
+ // We override this hook to write the package name that we need.
+ @Override
+ protected EditorInfo enrichEditorInfo(final EditorInfo ei) {
+ if ("testBeforeJellyBeanTrue".equals(getName())) {
+ ei.packageName = packageNameOfAppBeforeJellyBean;
+ } else if ("testBeforeJellyBeanFalse".equals(getName())) {
+ ei.packageName = packageNameOfAppAfterJellyBean;
+ }
+ return ei;
+ }
+
+ public void testBeforeJellyBeanTrue() {
+ assertTrue("Couldn't successfully detect this app targets < Jelly Bean (package is "
+ + packageNameOfAppBeforeJellyBean + ")",
+ Settings.getInstance().getCurrent().isBeforeJellyBean());
+ }
+
+ public void testBeforeJellyBeanFalse() {
+ assertFalse("Couldn't successfully detect this app targets >= Jelly Bean (package is "
+ + packageNameOfAppAfterJellyBean + ")",
+ Settings.getInstance().getCurrent().isBeforeJellyBean());
+ }
+} \ No newline at end of file
diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
index cd5384ea4..f4b16a7e1 100644
--- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
+++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java
@@ -21,7 +21,14 @@ import android.test.suitebuilder.annotation.LargeTest;
import android.util.Pair;
import com.android.inputmethod.latin.makedict.CodePointUtils;
+import com.android.inputmethod.latin.makedict.DictDecoder;
+import com.android.inputmethod.latin.makedict.DictionaryHeader;
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.FileUtils;
+import com.android.inputmethod.latin.utils.LocaleUtils;
import java.io.File;
import java.io.IOException;
@@ -30,68 +37,168 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
+import java.util.concurrent.TimeUnit;
@LargeTest
public class BinaryDictionaryDecayingTests extends AndroidTestCase {
private static final String TEST_DICT_FILE_EXTENSION = ".testDict";
private static final String TEST_LOCALE = "test";
-
- // Note that these are corresponding definitions in native code in
- // latinime::DynamicPatriciaTriePolicy.
- private static final String SET_NEEDS_TO_DECAY_FOR_TESTING_KEY =
- "SET_NEEDS_TO_DECAY_FOR_TESTING";
-
private static final int DUMMY_PROBABILITY = 0;
+ private int mCurrentTime = 0;
+
@Override
protected void setUp() throws Exception {
super.setUp();
+ mCurrentTime = 0;
}
@Override
protected void tearDown() throws Exception {
+ stopTestModeInNativeCode();
super.tearDown();
}
+ private void addUnigramWord(final BinaryDictionary binaryDictionary, final String word,
+ final int probability) {
+ binaryDictionary.addUnigramWord(word, probability, "" /* shortcutTarget */,
+ BinaryDictionary.NOT_A_PROBABILITY /* shortcutProbability */,
+ false /* isNotAWord */, false /* isBlacklisted */,
+ mCurrentTime /* timestamp */);
+ }
+
+ private void addBigramWords(final BinaryDictionary binaryDictionary, final String word0,
+ final String word1, final int probability) {
+ binaryDictionary.addBigramWords(word0, word1, probability,
+ mCurrentTime /* timestamp */);
+ }
+
private void forcePassingShortTime(final BinaryDictionary binaryDictionary) {
- // Entries having low probability would be suppressed once in 3 GCs.
- final int count = 3;
- for (int i = 0; i < count; i++) {
- binaryDictionary.getPropertyForTests(SET_NEEDS_TO_DECAY_FOR_TESTING_KEY);
- binaryDictionary.flushWithGC();
- }
+ // 4 days.
+ final int timeToElapse = (int)TimeUnit.SECONDS.convert(4, TimeUnit.DAYS);
+ mCurrentTime += timeToElapse;
+ setCurrentTimeForTestMode(mCurrentTime);
+ binaryDictionary.flushWithGC();
}
private void forcePassingLongTime(final BinaryDictionary binaryDictionary) {
- // Currently, probabilities are decayed when GC is run. All entries that have never been
- // typed in 128 GCs would be removed.
- final int count = 128;
- for (int i = 0; i < count; i++) {
- binaryDictionary.getPropertyForTests(SET_NEEDS_TO_DECAY_FOR_TESTING_KEY);
- binaryDictionary.flushWithGC();
+ // 60 days.
+ final int timeToElapse = (int)TimeUnit.SECONDS.convert(60, TimeUnit.DAYS);
+ mCurrentTime += timeToElapse;
+ setCurrentTimeForTestMode(mCurrentTime);
+ binaryDictionary.flushWithGC();
+ }
+
+ private File createEmptyDictionaryAndGetFile(final String dictId,
+ final int formatVersion) throws IOException {
+ if (formatVersion == FormatSpec.VERSION4) {
+ return createEmptyVer4DictionaryAndGetFile(dictId);
+ } else {
+ throw new IOException("Dictionary format version " + formatVersion
+ + " is not supported.");
}
}
- private File createEmptyDictionaryAndGetFile(final String filename) throws IOException {
- final File file = File.createTempFile(filename, TEST_DICT_FILE_EXTENSION,
+ private File createEmptyVer4DictionaryAndGetFile(final String dictId) throws IOException {
+ final File file = File.createTempFile(dictId, TEST_DICT_FILE_EXTENSION,
getContext().getCacheDir());
+ FileUtils.deleteRecursively(file);
Map<String, String> attributeMap = new HashMap<String, String>();
- attributeMap.put(FormatSpec.FileHeader.SUPPORTS_DYNAMIC_UPDATE_ATTRIBUTE,
- FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
- attributeMap.put(FormatSpec.FileHeader.USES_FORGETTING_CURVE_ATTRIBUTE,
- FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
- if (BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(),
- 3 /* dictVersion */, attributeMap)) {
+ attributeMap.put(DictionaryHeader.DICTIONARY_ID_KEY, dictId);
+ attributeMap.put(DictionaryHeader.DICTIONARY_VERSION_KEY,
+ String.valueOf(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())));
+ attributeMap.put(DictionaryHeader.USES_FORGETTING_CURVE_KEY,
+ DictionaryHeader.ATTRIBUTE_VALUE_TRUE);
+ attributeMap.put(DictionaryHeader.HAS_HISTORICAL_INFO_KEY,
+ DictionaryHeader.ATTRIBUTE_VALUE_TRUE);
+ if (BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(), FormatSpec.VERSION4,
+ LocaleUtils.constructLocaleFromString(TEST_LOCALE), attributeMap)) {
return file;
} else {
- throw new IOException("Empty dictionary cannot be created.");
+ throw new IOException("Empty dictionary " + file.getAbsolutePath()
+ + " cannot be created.");
+ }
+ }
+
+ private static int setCurrentTimeForTestMode(final int currentTime) {
+ return BinaryDictionary.setCurrentTimeForTest(currentTime);
+ }
+
+ private static int stopTestModeInNativeCode() {
+ return BinaryDictionary.setCurrentTimeForTest(-1);
+ }
+
+ public void testReadDictInJavaSide() {
+ testReadDictInJavaSide(FormatSpec.VERSION4);
+ }
+
+ private void testReadDictInJavaSide(final int formatVersion) {
+ setCurrentTimeForTestMode(mCurrentTime);
+ File dictFile = null;
+ try {
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
+ } catch (IOException e) {
+ fail("IOException while writing an initial dictionary : " + e);
+ }
+ BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
+ 0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
+ Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
+ addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "ab", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "aaa", DUMMY_PROBABILITY);
+ addBigramWords(binaryDictionary, "a", "aaa", DUMMY_PROBABILITY);
+ binaryDictionary.flushWithGC();
+ binaryDictionary.close();
+
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(dictFile);
+ try {
+ final FusionDictionary dict =
+ dictDecoder.readDictionaryBinary(false /* deleteDictIfBroken */);
+ PtNode ptNode = FusionDictionary.findWordInTree(dict.mRootNodeArray, "a");
+ assertNotNull(ptNode);
+ assertTrue(ptNode.isTerminal());
+ assertNotNull(ptNode.getBigram("aaa"));
+ ptNode = FusionDictionary.findWordInTree(dict.mRootNodeArray, "ab");
+ assertNotNull(ptNode);
+ assertTrue(ptNode.isTerminal());
+ ptNode = FusionDictionary.findWordInTree(dict.mRootNodeArray, "aaa");
+ assertNotNull(ptNode);
+ assertTrue(ptNode.isTerminal());
+ } catch (IOException e) {
+ fail("IOException while reading dictionary: " + e);
+ } catch (UnsupportedFormatException e) {
+ fail("Unsupported format: " + e);
+ }
+ dictFile.delete();
+ }
+
+ public void testControlCurrentTime() {
+ testControlCurrentTime(FormatSpec.VERSION4);
+ }
+
+ private void testControlCurrentTime(final int formatVersion) {
+ final int TEST_COUNT = 1000;
+ final long seed = System.currentTimeMillis();
+ final Random random = new Random(seed);
+ final int startTime = stopTestModeInNativeCode();
+ for (int i = 0; i < TEST_COUNT; i++) {
+ final int currentTime = random.nextInt(Integer.MAX_VALUE);
+ final int currentTimeInNativeCode = setCurrentTimeForTestMode(currentTime);
+ assertEquals(currentTime, currentTimeInNativeCode);
}
+ final int endTime = stopTestModeInNativeCode();
+ final int MAX_ALLOWED_ELAPSED_TIME = 10;
+ assertTrue(startTime <= endTime && endTime <= startTime + MAX_ALLOWED_ELAPSED_TIME);
}
public void testAddValidAndInvalidWords() {
+ testAddValidAndInvalidWords(FormatSpec.VERSION4);
+ }
+
+ private void testAddValidAndInvalidWords(final int formatVersion) {
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
@@ -99,36 +206,35 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
- binaryDictionary.addUnigramWord("a", Dictionary.NOT_A_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", Dictionary.NOT_A_PROBABILITY);
assertFalse(binaryDictionary.isValidWord("a"));
- binaryDictionary.addUnigramWord("a", Dictionary.NOT_A_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", Dictionary.NOT_A_PROBABILITY);
assertFalse(binaryDictionary.isValidWord("a"));
- binaryDictionary.addUnigramWord("a", Dictionary.NOT_A_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", Dictionary.NOT_A_PROBABILITY);
assertFalse(binaryDictionary.isValidWord("a"));
- binaryDictionary.addUnigramWord("a", Dictionary.NOT_A_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", Dictionary.NOT_A_PROBABILITY);
assertTrue(binaryDictionary.isValidWord("a"));
- binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY);
assertTrue(binaryDictionary.isValidWord("b"));
- final int unigramProbability = binaryDictionary.getFrequency("a");
- binaryDictionary.addBigramWords("a", "b", Dictionary.NOT_A_PROBABILITY);
+ addBigramWords(binaryDictionary, "a", "b", Dictionary.NOT_A_PROBABILITY);
assertFalse(binaryDictionary.isValidBigram("a", "b"));
- binaryDictionary.addBigramWords("a", "b", Dictionary.NOT_A_PROBABILITY);
+ addBigramWords(binaryDictionary, "a", "b", Dictionary.NOT_A_PROBABILITY);
assertFalse(binaryDictionary.isValidBigram("a", "b"));
- binaryDictionary.addBigramWords("a", "b", Dictionary.NOT_A_PROBABILITY);
+ addBigramWords(binaryDictionary, "a", "b", Dictionary.NOT_A_PROBABILITY);
assertFalse(binaryDictionary.isValidBigram("a", "b"));
- binaryDictionary.addBigramWords("a", "b", Dictionary.NOT_A_PROBABILITY);
+ addBigramWords(binaryDictionary, "a", "b", Dictionary.NOT_A_PROBABILITY);
assertTrue(binaryDictionary.isValidBigram("a", "b"));
- binaryDictionary.addUnigramWord("c", DUMMY_PROBABILITY);
- binaryDictionary.addBigramWords("a", "c", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "c", DUMMY_PROBABILITY);
+ addBigramWords(binaryDictionary, "a", "c", DUMMY_PROBABILITY);
assertTrue(binaryDictionary.isValidBigram("a", "c"));
// Add bigrams of not valid unigrams.
- binaryDictionary.addBigramWords("x", "y", Dictionary.NOT_A_PROBABILITY);
+ addBigramWords(binaryDictionary, "x", "y", Dictionary.NOT_A_PROBABILITY);
assertFalse(binaryDictionary.isValidBigram("x", "y"));
- binaryDictionary.addBigramWords("x", "y", DUMMY_PROBABILITY);
+ addBigramWords(binaryDictionary, "x", "y", DUMMY_PROBABILITY);
assertFalse(binaryDictionary.isValidBigram("x", "y"));
binaryDictionary.close();
@@ -136,9 +242,13 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
}
public void testDecayingProbability() {
+ testDecayingProbability(FormatSpec.VERSION4);
+ }
+
+ private void testDecayingProbability(final int formatVersion) {
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
@@ -146,39 +256,44 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
- binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
assertTrue(binaryDictionary.isValidWord("a"));
forcePassingShortTime(binaryDictionary);
assertFalse(binaryDictionary.isValidWord("a"));
- binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
- binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
- binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
- binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
+ assertTrue(binaryDictionary.isValidWord("a"));
forcePassingShortTime(binaryDictionary);
assertTrue(binaryDictionary.isValidWord("a"));
forcePassingLongTime(binaryDictionary);
assertFalse(binaryDictionary.isValidWord("a"));
- binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
- binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY);
- binaryDictionary.addBigramWords("a", "b", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY);
+ addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY);
assertTrue(binaryDictionary.isValidBigram("a", "b"));
forcePassingShortTime(binaryDictionary);
assertFalse(binaryDictionary.isValidBigram("a", "b"));
- binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
- binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY);
- binaryDictionary.addBigramWords("a", "b", DUMMY_PROBABILITY);
- binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
- binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY);
- binaryDictionary.addBigramWords("a", "b", DUMMY_PROBABILITY);
- binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
- binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY);
- binaryDictionary.addBigramWords("a", "b", DUMMY_PROBABILITY);
- binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY);
- binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY);
- binaryDictionary.addBigramWords("a", "b", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY);
+ addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY);
+ addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY);
+ addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY);
+ addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY);
+ addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY);
assertTrue(binaryDictionary.isValidBigram("a", "b"));
forcePassingShortTime(binaryDictionary);
assertTrue(binaryDictionary.isValidBigram("a", "b"));
@@ -190,6 +305,10 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
}
public void testAddManyUnigramsToDecayingDict() {
+ testAddManyUnigramsToDecayingDict(FormatSpec.VERSION4);
+ }
+
+ private void testAddManyUnigramsToDecayingDict(final int formatVersion) {
final int unigramCount = 30000;
final int unigramTypedCount = 100000;
final int codePointSetSize = 50;
@@ -198,13 +317,14 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
+ setCurrentTimeForTestMode(mCurrentTime);
final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random);
final ArrayList<String> words = new ArrayList<String>();
@@ -215,32 +335,98 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
}
final int maxUnigramCount = Integer.parseInt(
- binaryDictionary.getPropertyForTests(BinaryDictionary.MAX_UNIGRAM_COUNT_QUERY));
+ binaryDictionary.getPropertyForTest(BinaryDictionary.MAX_UNIGRAM_COUNT_QUERY));
for (int i = 0; i < unigramTypedCount; i++) {
final String word = words.get(random.nextInt(words.size()));
- binaryDictionary.addUnigramWord(word, DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, word, DUMMY_PROBABILITY);
if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) {
final int unigramCountBeforeGC =
- Integer.parseInt(binaryDictionary.getPropertyForTests(
+ Integer.parseInt(binaryDictionary.getPropertyForTest(
BinaryDictionary.UNIGRAM_COUNT_QUERY));
while (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) {
- binaryDictionary.flushWithGC();
+ forcePassingShortTime(binaryDictionary);
}
final int unigramCountAfterGC =
- Integer.parseInt(binaryDictionary.getPropertyForTests(
+ Integer.parseInt(binaryDictionary.getPropertyForTest(
BinaryDictionary.UNIGRAM_COUNT_QUERY));
assertTrue(unigramCountBeforeGC > unigramCountAfterGC);
}
}
- assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTests(
+ assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTest(
BinaryDictionary.UNIGRAM_COUNT_QUERY)) > 0);
- assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTests(
+ assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTest(
BinaryDictionary.UNIGRAM_COUNT_QUERY)) <= maxUnigramCount);
+ forcePassingLongTime(binaryDictionary);
+ assertEquals(0, Integer.parseInt(binaryDictionary.getPropertyForTest(
+ BinaryDictionary.UNIGRAM_COUNT_QUERY)));
+ }
+
+ public void testOverflowUnigrams() {
+ testOverflowUnigrams(FormatSpec.VERSION4);
+ }
+
+ private void testOverflowUnigrams(final int formatVersion) {
+ final int unigramCount = 20000;
+ final int eachUnigramTypedCount = 5;
+ final int strongUnigramTypedCount = 20;
+ final int weakUnigramTypedCount = 1;
+ final int codePointSetSize = 50;
+ final long seed = System.currentTimeMillis();
+ final Random random = new Random(seed);
+
+ File dictFile = null;
+ try {
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
+ } catch (IOException e) {
+ fail("IOException while writing an initial dictionary : " + e);
+ }
+ BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
+ 0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
+ Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
+ setCurrentTimeForTestMode(mCurrentTime);
+ final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random);
+
+ final String strong = "strong";
+ final String weak = "weak";
+ for (int j = 0; j < strongUnigramTypedCount; j++) {
+ addUnigramWord(binaryDictionary, strong, DUMMY_PROBABILITY);
+ }
+ for (int j = 0; j < weakUnigramTypedCount; j++) {
+ addUnigramWord(binaryDictionary, weak, DUMMY_PROBABILITY);
+ }
+ assertTrue(binaryDictionary.isValidWord(strong));
+ assertTrue(binaryDictionary.isValidWord(weak));
+
+ for (int i = 0; i < unigramCount; i++) {
+ final String word = CodePointUtils.generateWord(random, codePointSet);
+ for (int j = 0; j < eachUnigramTypedCount; j++) {
+ addUnigramWord(binaryDictionary, word, DUMMY_PROBABILITY);
+ }
+ if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) {
+ final int unigramCountBeforeGC =
+ Integer.parseInt(binaryDictionary.getPropertyForTest(
+ BinaryDictionary.UNIGRAM_COUNT_QUERY));
+ assertTrue(binaryDictionary.isValidWord(strong));
+ assertTrue(binaryDictionary.isValidWord(weak));
+ binaryDictionary.flushWithGC();
+ final int unigramCountAfterGC =
+ Integer.parseInt(binaryDictionary.getPropertyForTest(
+ BinaryDictionary.UNIGRAM_COUNT_QUERY));
+ assertTrue(unigramCountBeforeGC > unigramCountAfterGC);
+ assertFalse(binaryDictionary.isValidWord(weak));
+ assertTrue(binaryDictionary.isValidWord(strong));
+ break;
+ }
+ }
}
public void testAddManyBigramsToDecayingDict() {
+ testAddManyBigramsToDecayingDict(FormatSpec.VERSION4);
+ }
+
+ private void testAddManyBigramsToDecayingDict(final int formatVersion) {
final int unigramCount = 5000;
final int bigramCount = 30000;
final int bigramTypedCount = 100000;
@@ -250,13 +436,14 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
+ setCurrentTimeForTestMode(mCurrentTime);
final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random);
final ArrayList<String> words = new ArrayList<String>();
@@ -279,30 +466,112 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase {
}
final int maxBigramCount = Integer.parseInt(
- binaryDictionary.getPropertyForTests(BinaryDictionary.MAX_BIGRAM_COUNT_QUERY));
+ binaryDictionary.getPropertyForTest(BinaryDictionary.MAX_BIGRAM_COUNT_QUERY));
for (int i = 0; i < bigramTypedCount; ++i) {
final Pair<String, String> bigram = bigrams.get(random.nextInt(bigrams.size()));
- binaryDictionary.addUnigramWord(bigram.first, DUMMY_PROBABILITY);
- binaryDictionary.addUnigramWord(bigram.second, DUMMY_PROBABILITY);
- binaryDictionary.addBigramWords(bigram.first, bigram.second, DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, bigram.first, DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, bigram.second, DUMMY_PROBABILITY);
+ addBigramWords(binaryDictionary, bigram.first, bigram.second, DUMMY_PROBABILITY);
if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) {
final int bigramCountBeforeGC =
- Integer.parseInt(binaryDictionary.getPropertyForTests(
+ Integer.parseInt(binaryDictionary.getPropertyForTest(
BinaryDictionary.BIGRAM_COUNT_QUERY));
while (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) {
- binaryDictionary.flushWithGC();
+ forcePassingShortTime(binaryDictionary);
}
final int bigramCountAfterGC =
- Integer.parseInt(binaryDictionary.getPropertyForTests(
+ Integer.parseInt(binaryDictionary.getPropertyForTest(
BinaryDictionary.BIGRAM_COUNT_QUERY));
assertTrue(bigramCountBeforeGC > bigramCountAfterGC);
}
}
- assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTests(
+ assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTest(
BinaryDictionary.BIGRAM_COUNT_QUERY)) > 0);
- assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTests(
+ assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTest(
BinaryDictionary.BIGRAM_COUNT_QUERY)) <= maxBigramCount);
+ forcePassingLongTime(binaryDictionary);
+ assertEquals(0, Integer.parseInt(binaryDictionary.getPropertyForTest(
+ BinaryDictionary.BIGRAM_COUNT_QUERY)));
+ }
+
+ public void testOverflowBigrams() {
+ testOverflowBigrams(FormatSpec.VERSION4);
+ }
+
+ private void testOverflowBigrams(final int formatVersion) {
+ final int bigramCount = 20000;
+ final int unigramCount = 1000;
+ final int unigramTypedCount = 20;
+ final int eachBigramTypedCount = 5;
+ final int strongBigramTypedCount = 20;
+ final int weakBigramTypedCount = 1;
+ final int codePointSetSize = 50;
+ final long seed = System.currentTimeMillis();
+ final Random random = new Random(seed);
+
+ File dictFile = null;
+ try {
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
+ } catch (IOException e) {
+ fail("IOException while writing an initial dictionary : " + e);
+ }
+ BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
+ 0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
+ Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
+ setCurrentTimeForTestMode(mCurrentTime);
+ final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random);
+
+ final ArrayList<String> words = new ArrayList<String>();
+ for (int i = 0; i < unigramCount; i++) {
+ final String word = CodePointUtils.generateWord(random, codePointSet);
+ words.add(word);
+ for (int j = 0; j < unigramTypedCount; j++) {
+ addUnigramWord(binaryDictionary, word, DUMMY_PROBABILITY);
+ }
+ }
+ final String strong = "strong";
+ final String weak = "weak";
+ final String target = "target";
+ for (int j = 0; j < unigramTypedCount; j++) {
+ addUnigramWord(binaryDictionary, strong, DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, weak, DUMMY_PROBABILITY);
+ addUnigramWord(binaryDictionary, target, DUMMY_PROBABILITY);
+ }
+ binaryDictionary.flushWithGC();
+ for (int j = 0; j < strongBigramTypedCount; j++) {
+ addBigramWords(binaryDictionary, strong, target, DUMMY_PROBABILITY);
+ }
+ for (int j = 0; j < weakBigramTypedCount; j++) {
+ addBigramWords(binaryDictionary, weak, target, DUMMY_PROBABILITY);
+ }
+ assertTrue(binaryDictionary.isValidBigram(strong, target));
+ assertTrue(binaryDictionary.isValidBigram(weak, target));
+
+ for (int i = 0; i < bigramCount; i++) {
+ final int word0Index = random.nextInt(words.size());
+ final String word0 = words.get(word0Index);
+ final int index = random.nextInt(words.size() - 1);
+ final int word1Index = (index >= word0Index) ? index + 1 : index;
+ final String word1 = words.get(word1Index);
+
+ for (int j = 0; j < eachBigramTypedCount; j++) {
+ addBigramWords(binaryDictionary, word0, word1, DUMMY_PROBABILITY);
+ }
+ if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) {
+ final int bigramCountBeforeGC =
+ Integer.parseInt(binaryDictionary.getPropertyForTest(
+ BinaryDictionary.BIGRAM_COUNT_QUERY));
+ binaryDictionary.flushWithGC();
+ final int bigramCountAfterGC =
+ Integer.parseInt(binaryDictionary.getPropertyForTest(
+ BinaryDictionary.BIGRAM_COUNT_QUERY));
+ assertTrue(bigramCountBeforeGC > bigramCountAfterGC);
+ assertTrue(binaryDictionary.isValidBigram(strong, target));
+ assertFalse(binaryDictionary.isValidBigram(weak, target));
+ break;
+ }
+ }
}
}
diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
index 5b8f0e977..c1adf6557 100644
--- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java
@@ -23,6 +23,10 @@ import android.util.Pair;
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.FileUtils;
+import com.android.inputmethod.latin.utils.LanguageModelParam;
import java.io.File;
import java.io.IOException;
@@ -33,39 +37,45 @@ import java.util.Locale;
import java.util.Map;
import java.util.Random;
+// TODO Use the seed passed as an argument for makedict test.
@LargeTest
public class BinaryDictionaryTests extends AndroidTestCase {
private static final String TEST_DICT_FILE_EXTENSION = ".testDict";
private static final String TEST_LOCALE = "test";
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
+ private File createEmptyDictionaryAndGetFile(final String dictId,
+ final int formatVersion) throws IOException {
+ if (formatVersion == FormatSpec.VERSION4) {
+ return createEmptyVer4DictionaryAndGetFile(dictId);
+ } else {
+ throw new IOException("Dictionary format version " + formatVersion
+ + " is not supported.");
+ }
}
- private File createEmptyDictionaryAndGetFile(final String filename) throws IOException {
- final File file = File.createTempFile(filename, TEST_DICT_FILE_EXTENSION,
+ private File createEmptyVer4DictionaryAndGetFile(final String dictId) throws IOException {
+ final File file = File.createTempFile(dictId, TEST_DICT_FILE_EXTENSION,
getContext().getCacheDir());
+ file.delete();
+ file.mkdir();
Map<String, String> attributeMap = new HashMap<String, String>();
- attributeMap.put(FormatSpec.FileHeader.SUPPORTS_DYNAMIC_UPDATE_ATTRIBUTE,
- FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE);
- if (BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(),
- 3 /* dictVersion */, attributeMap)) {
+ if (BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(), FormatSpec.VERSION4,
+ Locale.ENGLISH, attributeMap)) {
return file;
} else {
- throw new IOException("Empty dictionary cannot be created.");
+ throw new IOException("Empty dictionary " + file.getAbsolutePath()
+ + " cannot be created.");
}
}
public void testIsValidDictionary() {
+ testIsValidDictionary(FormatSpec.VERSION4);
+ }
+
+ private void testIsValidDictionary(final int formatVersion) {
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
@@ -77,7 +87,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
binaryDictionary.close();
assertFalse("binaryDictionary must be invalid after closing.",
binaryDictionary.isValidDictionary());
- dictFile.delete();
+ FileUtils.deleteRecursively(dictFile);
binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), 0 /* offset */,
dictFile.length(), true /* useFullEditDistance */, Locale.getDefault(),
TEST_LOCALE, true /* isUpdatable */);
@@ -86,10 +96,73 @@ public class BinaryDictionaryTests extends AndroidTestCase {
binaryDictionary.close();
}
+ public void testAddTooLongWord() {
+ testAddTooLongWord(FormatSpec.VERSION4);
+ }
+
+ private void testAddTooLongWord(final int formatVersion) {
+ File dictFile = null;
+ try {
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
+ } catch (IOException e) {
+ fail("IOException while writing an initial dictionary : " + e);
+ }
+ final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
+ 0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
+ Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
+
+ final StringBuffer stringBuilder = new StringBuffer();
+ for (int i = 0; i < Constants.DICTIONARY_MAX_WORD_LENGTH; i++) {
+ stringBuilder.append('a');
+ }
+ final String validLongWord = stringBuilder.toString();
+ stringBuilder.append('a');
+ final String invalidLongWord = stringBuilder.toString();
+ final int probability = 100;
+ addUnigramWord(binaryDictionary, "aaa", probability);
+ addUnigramWord(binaryDictionary, validLongWord, probability);
+ addUnigramWord(binaryDictionary, invalidLongWord, probability);
+ // Too long short cut.
+ binaryDictionary.addUnigramWord("a", probability, invalidLongWord,
+ 10 /* shortcutProbability */, false /* isNotAWord */, false /* isBlacklisted */,
+ BinaryDictionary.NOT_A_VALID_TIMESTAMP);
+ addUnigramWord(binaryDictionary, "abc", probability);
+ final int updatedProbability = 200;
+ // Update.
+ addUnigramWord(binaryDictionary, validLongWord, updatedProbability);
+ addUnigramWord(binaryDictionary, invalidLongWord, updatedProbability);
+ addUnigramWord(binaryDictionary, "abc", updatedProbability);
+
+ assertEquals(probability, binaryDictionary.getFrequency("aaa"));
+ assertEquals(updatedProbability, binaryDictionary.getFrequency(validLongWord));
+ assertEquals(BinaryDictionary.NOT_A_PROBABILITY,
+ binaryDictionary.getFrequency(invalidLongWord));
+ assertEquals(updatedProbability, binaryDictionary.getFrequency("abc"));
+ dictFile.delete();
+ }
+
+ private void addUnigramWord(final BinaryDictionary binaryDictionary, final String word,
+ final int probability) {
+ binaryDictionary.addUnigramWord(word, probability, "" /* shortcutTarget */,
+ BinaryDictionary.NOT_A_PROBABILITY /* shortcutProbability */,
+ false /* isNotAWord */, false /* isBlacklisted */,
+ BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */);
+ }
+
+ private void addBigramWords(final BinaryDictionary binaryDictionary, final String word0,
+ final String word1, final int probability) {
+ binaryDictionary.addBigramWords(word0, word1, probability,
+ BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */);
+ }
+
public void testAddUnigramWord() {
+ testAddUnigramWord(FormatSpec.VERSION4);
+ }
+
+ private void testAddUnigramWord(final int formatVersion) {
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
@@ -98,21 +171,21 @@ public class BinaryDictionaryTests extends AndroidTestCase {
Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
final int probability = 100;
- binaryDictionary.addUnigramWord("aaa", probability);
+ addUnigramWord(binaryDictionary, "aaa", probability);
// Reallocate and create.
- binaryDictionary.addUnigramWord("aab", probability);
+ addUnigramWord(binaryDictionary, "aab", probability);
// Insert into children.
- binaryDictionary.addUnigramWord("aac", probability);
+ addUnigramWord(binaryDictionary, "aac", probability);
// Make terminal.
- binaryDictionary.addUnigramWord("aa", probability);
+ addUnigramWord(binaryDictionary, "aa", probability);
// Create children.
- binaryDictionary.addUnigramWord("aaaa", probability);
+ addUnigramWord(binaryDictionary, "aaaa", probability);
// Reallocate and make termianl.
- binaryDictionary.addUnigramWord("a", probability);
+ addUnigramWord(binaryDictionary, "a", probability);
final int updatedProbability = 200;
// Update.
- binaryDictionary.addUnigramWord("aaa", updatedProbability);
+ addUnigramWord(binaryDictionary, "aaa", updatedProbability);
assertEquals(probability, binaryDictionary.getFrequency("aab"));
assertEquals(probability, binaryDictionary.getFrequency("aac"));
@@ -125,13 +198,17 @@ public class BinaryDictionaryTests extends AndroidTestCase {
}
public void testRandomlyAddUnigramWord() {
+ testRandomlyAddUnigramWord(FormatSpec.VERSION4);
+ }
+
+ private void testRandomlyAddUnigramWord(final int formatVersion) {
final int wordCount = 1000;
final int codePointSetSize = 50;
final long seed = System.currentTimeMillis();
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
@@ -148,7 +225,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
probabilityMap.put(word, random.nextInt(0xFF));
}
for (String word : probabilityMap.keySet()) {
- binaryDictionary.addUnigramWord(word, probabilityMap.get(word));
+ addUnigramWord(binaryDictionary, word, probabilityMap.get(word));
}
for (String word : probabilityMap.keySet()) {
assertEquals(word, (int)probabilityMap.get(word), binaryDictionary.getFrequency(word));
@@ -157,9 +234,13 @@ public class BinaryDictionaryTests extends AndroidTestCase {
}
public void testAddBigramWords() {
+ testAddBigramWords(FormatSpec.VERSION4);
+ }
+
+ private void testAddBigramWords(final int formatVersion) {
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
@@ -170,13 +251,13 @@ public class BinaryDictionaryTests extends AndroidTestCase {
final int unigramProbability = 100;
final int bigramProbability = 10;
final int updatedBigramProbability = 15;
- binaryDictionary.addUnigramWord("aaa", unigramProbability);
- binaryDictionary.addUnigramWord("abb", unigramProbability);
- binaryDictionary.addUnigramWord("bcc", unigramProbability);
- binaryDictionary.addBigramWords("aaa", "abb", bigramProbability);
- binaryDictionary.addBigramWords("aaa", "bcc", bigramProbability);
- binaryDictionary.addBigramWords("abb", "aaa", bigramProbability);
- binaryDictionary.addBigramWords("abb", "bcc", bigramProbability);
+ addUnigramWord(binaryDictionary, "aaa", unigramProbability);
+ addUnigramWord(binaryDictionary, "abb", unigramProbability);
+ addUnigramWord(binaryDictionary, "bcc", unigramProbability);
+ addBigramWords(binaryDictionary, "aaa", "abb", bigramProbability);
+ addBigramWords(binaryDictionary, "aaa", "bcc", bigramProbability);
+ addBigramWords(binaryDictionary, "abb", "aaa", bigramProbability);
+ addBigramWords(binaryDictionary, "abb", "bcc", bigramProbability);
final int probability = binaryDictionary.calculateProbability(unigramProbability,
bigramProbability);
@@ -189,7 +270,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
assertEquals(probability, binaryDictionary.getBigramProbability("abb", "aaa"));
assertEquals(probability, binaryDictionary.getBigramProbability("abb", "bcc"));
- binaryDictionary.addBigramWords("aaa", "abb", updatedBigramProbability);
+ addBigramWords(binaryDictionary, "aaa", "abb", updatedBigramProbability);
final int updatedProbability = binaryDictionary.calculateProbability(unigramProbability,
updatedBigramProbability);
assertEquals(updatedProbability, binaryDictionary.getBigramProbability("aaa", "abb"));
@@ -205,22 +286,26 @@ public class BinaryDictionaryTests extends AndroidTestCase {
binaryDictionary.getBigramProbability("aaa", "aaa"));
// Testing bigram link.
- binaryDictionary.addUnigramWord("abcde", unigramProbability);
- binaryDictionary.addUnigramWord("fghij", unigramProbability);
- binaryDictionary.addBigramWords("abcde", "fghij", bigramProbability);
- binaryDictionary.addUnigramWord("fgh", unigramProbability);
- binaryDictionary.addUnigramWord("abc", unigramProbability);
- binaryDictionary.addUnigramWord("f", unigramProbability);
+ addUnigramWord(binaryDictionary, "abcde", unigramProbability);
+ addUnigramWord(binaryDictionary, "fghij", unigramProbability);
+ addBigramWords(binaryDictionary, "abcde", "fghij", bigramProbability);
+ addUnigramWord(binaryDictionary, "fgh", unigramProbability);
+ addUnigramWord(binaryDictionary, "abc", unigramProbability);
+ addUnigramWord(binaryDictionary, "f", unigramProbability);
assertEquals(probability, binaryDictionary.getBigramProbability("abcde", "fghij"));
assertEquals(Dictionary.NOT_A_PROBABILITY,
binaryDictionary.getBigramProbability("abcde", "fgh"));
- binaryDictionary.addBigramWords("abcde", "fghij", updatedBigramProbability);
+ addBigramWords(binaryDictionary, "abcde", "fghij", updatedBigramProbability);
assertEquals(updatedProbability, binaryDictionary.getBigramProbability("abcde", "fghij"));
dictFile.delete();
}
public void testRandomlyAddBigramWords() {
+ testRandomlyAddBigramWords(FormatSpec.VERSION4);
+ }
+
+ private void testRandomlyAddBigramWords(final int formatVersion) {
final int wordCount = 100;
final int bigramCount = 1000;
final int codePointSetSize = 50;
@@ -229,7 +314,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
@@ -249,7 +334,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
words.add(word);
final int unigramProbability = random.nextInt(0xFF);
unigramProbabilities.put(word, unigramProbability);
- binaryDictionary.addUnigramWord(word, unigramProbability);
+ addUnigramWord(binaryDictionary, word, unigramProbability);
}
for (int i = 0; i < bigramCount; i++) {
@@ -262,7 +347,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
bigramWords.add(bigram);
final int bigramProbability = random.nextInt(0xF);
bigramProbabilities.put(bigram, bigramProbability);
- binaryDictionary.addBigramWords(word0, word1, bigramProbability);
+ addBigramWords(binaryDictionary, word0, word1, bigramProbability);
}
for (final Pair<String, String> bigram : bigramWords) {
@@ -278,9 +363,13 @@ public class BinaryDictionaryTests extends AndroidTestCase {
}
public void testRemoveBigramWords() {
+ testRemoveBigramWords(FormatSpec.VERSION4);
+ }
+
+ private void testRemoveBigramWords(final int formatVersion) {
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
@@ -289,13 +378,13 @@ public class BinaryDictionaryTests extends AndroidTestCase {
Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
final int unigramProbability = 100;
final int bigramProbability = 10;
- binaryDictionary.addUnigramWord("aaa", unigramProbability);
- binaryDictionary.addUnigramWord("abb", unigramProbability);
- binaryDictionary.addUnigramWord("bcc", unigramProbability);
- binaryDictionary.addBigramWords("aaa", "abb", bigramProbability);
- binaryDictionary.addBigramWords("aaa", "bcc", bigramProbability);
- binaryDictionary.addBigramWords("abb", "aaa", bigramProbability);
- binaryDictionary.addBigramWords("abb", "bcc", bigramProbability);
+ addUnigramWord(binaryDictionary, "aaa", unigramProbability);
+ addUnigramWord(binaryDictionary, "abb", unigramProbability);
+ addUnigramWord(binaryDictionary, "bcc", unigramProbability);
+ addBigramWords(binaryDictionary, "aaa", "abb", bigramProbability);
+ addBigramWords(binaryDictionary, "aaa", "bcc", bigramProbability);
+ addBigramWords(binaryDictionary, "abb", "aaa", bigramProbability);
+ addBigramWords(binaryDictionary, "abb", "bcc", bigramProbability);
assertEquals(true, binaryDictionary.isValidBigram("aaa", "abb"));
assertEquals(true, binaryDictionary.isValidBigram("aaa", "bcc"));
@@ -304,7 +393,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
binaryDictionary.removeBigramWords("aaa", "abb");
assertEquals(false, binaryDictionary.isValidBigram("aaa", "abb"));
- binaryDictionary.addBigramWords("aaa", "abb", bigramProbability);
+ addBigramWords(binaryDictionary, "aaa", "abb", bigramProbability);
assertEquals(true, binaryDictionary.isValidBigram("aaa", "abb"));
@@ -324,9 +413,13 @@ public class BinaryDictionaryTests extends AndroidTestCase {
}
public void testFlushDictionary() {
+ testFlushDictionary(FormatSpec.VERSION4);
+ }
+
+ private void testFlushDictionary(final int formatVersion) {
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
@@ -335,8 +428,8 @@ public class BinaryDictionaryTests extends AndroidTestCase {
Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
final int probability = 100;
- binaryDictionary.addUnigramWord("aaa", probability);
- binaryDictionary.addUnigramWord("abcd", probability);
+ addUnigramWord(binaryDictionary, "aaa", probability);
+ addUnigramWord(binaryDictionary, "abcd", probability);
// Close without flushing.
binaryDictionary.close();
@@ -347,8 +440,8 @@ public class BinaryDictionaryTests extends AndroidTestCase {
assertEquals(Dictionary.NOT_A_PROBABILITY, binaryDictionary.getFrequency("aaa"));
assertEquals(Dictionary.NOT_A_PROBABILITY, binaryDictionary.getFrequency("abcd"));
- binaryDictionary.addUnigramWord("aaa", probability);
- binaryDictionary.addUnigramWord("abcd", probability);
+ addUnigramWord(binaryDictionary, "aaa", probability);
+ addUnigramWord(binaryDictionary, "abcd", probability);
binaryDictionary.flush();
binaryDictionary.close();
@@ -358,7 +451,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
assertEquals(probability, binaryDictionary.getFrequency("aaa"));
assertEquals(probability, binaryDictionary.getFrequency("abcd"));
- binaryDictionary.addUnigramWord("bcde", probability);
+ addUnigramWord(binaryDictionary, "bcde", probability);
binaryDictionary.flush();
binaryDictionary.close();
@@ -372,9 +465,13 @@ public class BinaryDictionaryTests extends AndroidTestCase {
}
public void testFlushWithGCDictionary() {
+ testFlushWithGCDictionary(FormatSpec.VERSION4);
+ }
+
+ private void testFlushWithGCDictionary(final int formatVersion) {
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
@@ -384,13 +481,13 @@ public class BinaryDictionaryTests extends AndroidTestCase {
final int unigramProbability = 100;
final int bigramProbability = 10;
- binaryDictionary.addUnigramWord("aaa", unigramProbability);
- binaryDictionary.addUnigramWord("abb", unigramProbability);
- binaryDictionary.addUnigramWord("bcc", unigramProbability);
- binaryDictionary.addBigramWords("aaa", "abb", bigramProbability);
- binaryDictionary.addBigramWords("aaa", "bcc", bigramProbability);
- binaryDictionary.addBigramWords("abb", "aaa", bigramProbability);
- binaryDictionary.addBigramWords("abb", "bcc", bigramProbability);
+ addUnigramWord(binaryDictionary, "aaa", unigramProbability);
+ addUnigramWord(binaryDictionary, "abb", unigramProbability);
+ addUnigramWord(binaryDictionary, "bcc", unigramProbability);
+ addBigramWords(binaryDictionary, "aaa", "abb", bigramProbability);
+ addBigramWords(binaryDictionary, "aaa", "bcc", bigramProbability);
+ addBigramWords(binaryDictionary, "abb", "aaa", bigramProbability);
+ addBigramWords(binaryDictionary, "abb", "bcc", bigramProbability);
binaryDictionary.flushWithGC();
binaryDictionary.close();
@@ -415,8 +512,12 @@ public class BinaryDictionaryTests extends AndroidTestCase {
dictFile.delete();
}
- // TODO: Evaluate performance of GC
public void testAddBigramWordsAndFlashWithGC() {
+ testAddBigramWordsAndFlashWithGC(FormatSpec.VERSION4);
+ }
+
+ // TODO: Evaluate performance of GC
+ private void testAddBigramWordsAndFlashWithGC(final int formatVersion) {
final int wordCount = 100;
final int bigramCount = 1000;
final int codePointSetSize = 30;
@@ -425,7 +526,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
@@ -446,7 +547,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
words.add(word);
final int unigramProbability = random.nextInt(0xFF);
unigramProbabilities.put(word, unigramProbability);
- binaryDictionary.addUnigramWord(word, unigramProbability);
+ addUnigramWord(binaryDictionary, word, unigramProbability);
}
for (int i = 0; i < bigramCount; i++) {
@@ -459,7 +560,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
bigramWords.add(bigram);
final int bigramProbability = random.nextInt(0xF);
bigramProbabilities.put(bigram, bigramProbability);
- binaryDictionary.addBigramWords(word0, word1, bigramProbability);
+ addBigramWords(binaryDictionary, word0, word1, bigramProbability);
}
binaryDictionary.flushWithGC();
@@ -480,7 +581,11 @@ public class BinaryDictionaryTests extends AndroidTestCase {
dictFile.delete();
}
- public void testRandomOperetionsAndFlashWithGC() {
+ public void testRandomOperationsAndFlashWithGC() {
+ testRandomOperationsAndFlashWithGC(FormatSpec.VERSION4);
+ }
+
+ private void testRandomOperationsAndFlashWithGC(final int formatVersion) {
final int flashWithGCIterationCount = 50;
final int operationCountInEachIteration = 200;
final int initialUnigramCount = 100;
@@ -494,7 +599,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
@@ -513,7 +618,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
words.add(word);
final int unigramProbability = random.nextInt(0xFF);
unigramProbabilities.put(word, unigramProbability);
- binaryDictionary.addUnigramWord(word, unigramProbability);
+ addUnigramWord(binaryDictionary, word, unigramProbability);
}
binaryDictionary.flushWithGC();
binaryDictionary.close();
@@ -529,7 +634,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
words.add(word);
final int unigramProbability = random.nextInt(0xFF);
unigramProbabilities.put(word, unigramProbability);
- binaryDictionary.addUnigramWord(word, unigramProbability);
+ addUnigramWord(binaryDictionary, word, unigramProbability);
}
// Add bigram.
if (random.nextFloat() < addBigramProb && words.size() > 2) {
@@ -547,7 +652,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
final Pair<String, String> bigram = new Pair<String, String>(word0, word1);
bigramWords.add(bigram);
bigramProbabilities.put(bigram, bigramProbability);
- binaryDictionary.addBigramWords(word0, word1, bigramProbability);
+ addBigramWords(binaryDictionary, word0, word1, bigramProbability);
}
// Remove bigram.
if (random.nextFloat() < removeBigramProb && !bigramWords.isEmpty()) {
@@ -588,6 +693,10 @@ public class BinaryDictionaryTests extends AndroidTestCase {
}
public void testAddManyUnigramsAndFlushWithGC() {
+ testAddManyUnigramsAndFlushWithGC(FormatSpec.VERSION4);
+ }
+
+ private void testAddManyUnigramsAndFlushWithGC(final int formatVersion) {
final int flashWithGCIterationCount = 3;
final int codePointSetSize = 50;
@@ -596,7 +705,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
@@ -615,7 +724,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
words.add(word);
final int unigramProbability = random.nextInt(0xFF);
unigramProbabilities.put(word, unigramProbability);
- binaryDictionary.addUnigramWord(word, unigramProbability);
+ addUnigramWord(binaryDictionary, word, unigramProbability);
}
for (int j = 0; j < words.size(); j++) {
@@ -632,6 +741,10 @@ public class BinaryDictionaryTests extends AndroidTestCase {
}
public void testUnigramAndBigramCount() {
+ testUnigramAndBigramCount(FormatSpec.VERSION4);
+ }
+
+ private void testUnigramAndBigramCount(final int formatVersion) {
final int flashWithGCIterationCount = 10;
final int codePointSetSize = 50;
final int unigramCountPerIteration = 1000;
@@ -641,7 +754,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
File dictFile = null;
try {
- dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary");
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
} catch (IOException e) {
fail("IOException while writing an initial dictionary : " + e);
}
@@ -659,7 +772,7 @@ public class BinaryDictionaryTests extends AndroidTestCase {
final String word = CodePointUtils.generateWord(random, codePointSet);
words.add(word);
final int unigramProbability = random.nextInt(0xFF);
- binaryDictionary.addUnigramWord(word, unigramProbability);
+ addUnigramWord(binaryDictionary, word, unigramProbability);
}
for (int j = 0; j < bigramCountPerIteration; j++) {
final String word0 = words.get(random.nextInt(words.size()));
@@ -669,20 +782,408 @@ public class BinaryDictionaryTests extends AndroidTestCase {
}
bigrams.add(new Pair<String, String>(word0, word1));
final int bigramProbability = random.nextInt(0xF);
- binaryDictionary.addBigramWords(word0, word1, bigramProbability);
+ addBigramWords(binaryDictionary, word0, word1, bigramProbability);
}
assertEquals(new HashSet<String>(words).size(), Integer.parseInt(
- binaryDictionary.getPropertyForTests(BinaryDictionary.UNIGRAM_COUNT_QUERY)));
+ binaryDictionary.getPropertyForTest(BinaryDictionary.UNIGRAM_COUNT_QUERY)));
assertEquals(new HashSet<Pair<String, String>>(bigrams).size(), Integer.parseInt(
- binaryDictionary.getPropertyForTests(BinaryDictionary.BIGRAM_COUNT_QUERY)));
+ binaryDictionary.getPropertyForTest(BinaryDictionary.BIGRAM_COUNT_QUERY)));
binaryDictionary.flushWithGC();
assertEquals(new HashSet<String>(words).size(), Integer.parseInt(
- binaryDictionary.getPropertyForTests(BinaryDictionary.UNIGRAM_COUNT_QUERY)));
+ binaryDictionary.getPropertyForTest(BinaryDictionary.UNIGRAM_COUNT_QUERY)));
assertEquals(new HashSet<Pair<String, String>>(bigrams).size(), Integer.parseInt(
- binaryDictionary.getPropertyForTests(BinaryDictionary.BIGRAM_COUNT_QUERY)));
+ binaryDictionary.getPropertyForTest(BinaryDictionary.BIGRAM_COUNT_QUERY)));
binaryDictionary.close();
}
dictFile.delete();
}
+
+ public void testAddMultipleDictionaryEntries() {
+ testAddMultipleDictionaryEntries(FormatSpec.VERSION4);
+ }
+
+ private void testAddMultipleDictionaryEntries(final int formatVersion) {
+ final int codePointSetSize = 20;
+ final int lmParamCount = 1000;
+ final double bigramContinueRate = 0.9;
+ final long seed = System.currentTimeMillis();
+ final Random random = new Random(seed);
+
+ File dictFile = null;
+ try {
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
+ } catch (IOException e) {
+ fail("IOException while writing an initial dictionary : " + e);
+ }
+
+ final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random);
+ final HashMap<String, Integer> unigramProbabilities = new HashMap<String, Integer>();
+ final HashMap<Pair<String, String>, Integer> bigramProbabilities =
+ new HashMap<Pair<String, String>, Integer>();
+
+ final LanguageModelParam[] languageModelParams = new LanguageModelParam[lmParamCount];
+ String prevWord = null;
+ for (int i = 0; i < languageModelParams.length; i++) {
+ final String word = CodePointUtils.generateWord(random, codePointSet);
+ final int probability = random.nextInt(0xFF);
+ final int bigramProbability = random.nextInt(0xF);
+ unigramProbabilities.put(word, probability);
+ if (prevWord == null) {
+ languageModelParams[i] = new LanguageModelParam(word, probability,
+ BinaryDictionary.NOT_A_VALID_TIMESTAMP);
+ } else {
+ languageModelParams[i] = new LanguageModelParam(prevWord, word, probability,
+ bigramProbability, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
+ bigramProbabilities.put(new Pair<String, String>(prevWord, word),
+ bigramProbability);
+ }
+ prevWord = (random.nextDouble() < bigramContinueRate) ? word : null;
+ }
+
+ final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
+ 0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
+ Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
+ binaryDictionary.addMultipleDictionaryEntries(languageModelParams);
+
+ for (Map.Entry<String, Integer> entry : unigramProbabilities.entrySet()) {
+ assertEquals((int)entry.getValue(), binaryDictionary.getFrequency(entry.getKey()));
+ }
+
+ for (Map.Entry<Pair<String, String>, Integer> entry : bigramProbabilities.entrySet()) {
+ final String word0 = entry.getKey().first;
+ final String word1 = entry.getKey().second;
+ final int unigramProbability = unigramProbabilities.get(word1);
+ final int bigramProbability = entry.getValue();
+ final int probability = binaryDictionary.calculateProbability(
+ unigramProbability, bigramProbability);
+ assertEquals(probability, binaryDictionary.getBigramProbability(word0, word1));
+ }
+ }
+
+ public void testGetWordProperties() {
+ testGetWordProperties(FormatSpec.VERSION4);
+ }
+
+ private void testGetWordProperties(final int formatVersion) {
+ final long seed = System.currentTimeMillis();
+ final Random random = new Random(seed);
+ final int UNIGRAM_COUNT = 1000;
+ final int BIGRAM_COUNT = 1000;
+ final int codePointSetSize = 20;
+ final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random);
+
+ File dictFile = null;
+ try {
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
+ } catch (IOException e) {
+ fail("IOException while writing an initial dictionary : " + e);
+ }
+ final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
+ 0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
+ Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
+
+ final WordProperty invalidWordProperty = binaryDictionary.getWordProperty("dummyWord");
+ assertFalse(invalidWordProperty.isValid());
+
+ final ArrayList<String> words = new ArrayList<String>();
+ final HashMap<String, Integer> wordProbabilities = new HashMap<String, Integer>();
+ final HashMap<String, HashSet<String>> bigrams = new HashMap<String, HashSet<String>>();
+ final HashMap<Pair<String, String>, Integer> bigramProbabilities =
+ new HashMap<Pair<String, String>, Integer>();
+
+ for (int i = 0; i < UNIGRAM_COUNT; i++) {
+ final String word = CodePointUtils.generateWord(random, codePointSet);
+ final int unigramProbability = random.nextInt(0xFF);
+ final boolean isNotAWord = random.nextBoolean();
+ final boolean isBlacklisted = random.nextBoolean();
+ // TODO: Add tests for historical info.
+ binaryDictionary.addUnigramWord(word, unigramProbability,
+ null /* shortcutTarget */, BinaryDictionary.NOT_A_PROBABILITY,
+ isNotAWord, isBlacklisted, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
+ if (binaryDictionary.needsToRunGC(false /* mindsBlockByGC */)) {
+ binaryDictionary.flushWithGC();
+ }
+ words.add(word);
+ wordProbabilities.put(word, unigramProbability);
+ final WordProperty wordProperty = binaryDictionary.getWordProperty(word);
+ assertEquals(word, wordProperty.mWord);
+ assertTrue(wordProperty.isValid());
+ assertEquals(isNotAWord, wordProperty.mIsNotAWord);
+ assertEquals(isBlacklisted, wordProperty.mIsBlacklistEntry);
+ assertEquals(false, wordProperty.mHasBigrams);
+ assertEquals(false, wordProperty.mHasShortcuts);
+ assertEquals(unigramProbability, wordProperty.mProbabilityInfo.mProbability);
+ assertTrue(wordProperty.mShortcutTargets.isEmpty());
+ }
+
+ for (int i = 0; i < BIGRAM_COUNT; i++) {
+ final int word0Index = random.nextInt(wordProbabilities.size());
+ final int word1Index = random.nextInt(wordProbabilities.size());
+ if (word0Index == word1Index) {
+ continue;
+ }
+ final String word0 = words.get(word0Index);
+ final String word1 = words.get(word1Index);
+ final int bigramProbability = random.nextInt(0xF);
+ binaryDictionary.addBigramWords(word0, word1, bigramProbability,
+ BinaryDictionary.NOT_A_VALID_TIMESTAMP);
+ if (binaryDictionary.needsToRunGC(false /* mindsBlockByGC */)) {
+ binaryDictionary.flushWithGC();
+ }
+ if (!bigrams.containsKey(word0)) {
+ final HashSet<String> bigramWord1s = new HashSet<String>();
+ bigrams.put(word0, bigramWord1s);
+ }
+ bigrams.get(word0).add(word1);
+ bigramProbabilities.put(new Pair<String, String>(word0, word1), bigramProbability);
+ }
+
+ for (int i = 0; i < words.size(); i++) {
+ final String word0 = words.get(i);
+ if (!bigrams.containsKey(word0)) {
+ continue;
+ }
+ final HashSet<String> bigramWord1s = bigrams.get(word0);
+ final WordProperty wordProperty = binaryDictionary.getWordProperty(word0);
+ assertEquals(bigramWord1s.size(), wordProperty.mBigrams.size());
+ for (int j = 0; j < wordProperty.mBigrams.size(); j++) {
+ final String word1 = wordProperty.mBigrams.get(j).mWord;
+ assertTrue(bigramWord1s.contains(word1));
+ final int probability = wordProperty.mBigrams.get(j).getProbability();
+ assertEquals((int)bigramProbabilities.get(new Pair<String, String>(word0, word1)),
+ probability);
+ assertEquals(wordProperty.mBigrams.get(j).getProbability(), probability);
+ }
+ }
+ }
+
+ public void testIterateAllWords() {
+ testIterateAllWords(FormatSpec.VERSION4);
+ }
+
+ private void testIterateAllWords(final int formatVersion) {
+ final long seed = System.currentTimeMillis();
+ final Random random = new Random(seed);
+ final int UNIGRAM_COUNT = 1000;
+ final int BIGRAM_COUNT = 1000;
+ final int codePointSetSize = 20;
+ final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random);
+
+ File dictFile = null;
+ try {
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
+ } catch (IOException e) {
+ fail("IOException while writing an initial dictionary : " + e);
+ }
+ final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
+ 0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
+ Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
+
+ final WordProperty invalidWordProperty = binaryDictionary.getWordProperty("dummyWord");
+ assertFalse(invalidWordProperty.isValid());
+
+ final ArrayList<String> words = new ArrayList<String>();
+ final HashMap<String, Integer> wordProbabilitiesToCheckLater =
+ new HashMap<String, Integer>();
+ final HashMap<String, HashSet<String>> bigrams = new HashMap<String, HashSet<String>>();
+ final HashMap<Pair<String, String>, Integer> bigramProbabilitiesToCheckLater =
+ new HashMap<Pair<String, String>, Integer>();
+
+ for (int i = 0; i < UNIGRAM_COUNT; i++) {
+ final String word = CodePointUtils.generateWord(random, codePointSet);
+ final int unigramProbability = random.nextInt(0xFF);
+ addUnigramWord(binaryDictionary, word, unigramProbability);
+ if (binaryDictionary.needsToRunGC(false /* mindsBlockByGC */)) {
+ binaryDictionary.flushWithGC();
+ }
+ words.add(word);
+ wordProbabilitiesToCheckLater.put(word, unigramProbability);
+ }
+
+ for (int i = 0; i < BIGRAM_COUNT; i++) {
+ final int word0Index = random.nextInt(wordProbabilitiesToCheckLater.size());
+ final int word1Index = random.nextInt(wordProbabilitiesToCheckLater.size());
+ if (word0Index == word1Index) {
+ continue;
+ }
+ final String word0 = words.get(word0Index);
+ final String word1 = words.get(word1Index);
+ final int bigramProbability = random.nextInt(0xF);
+ binaryDictionary.addBigramWords(word0, word1, bigramProbability,
+ BinaryDictionary.NOT_A_VALID_TIMESTAMP);
+ if (binaryDictionary.needsToRunGC(false /* mindsBlockByGC */)) {
+ binaryDictionary.flushWithGC();
+ }
+ if (!bigrams.containsKey(word0)) {
+ final HashSet<String> bigramWord1s = new HashSet<String>();
+ bigrams.put(word0, bigramWord1s);
+ }
+ bigrams.get(word0).add(word1);
+ bigramProbabilitiesToCheckLater.put(
+ new Pair<String, String>(word0, word1), bigramProbability);
+ }
+
+ final HashSet<String> wordSet = new HashSet<String>(words);
+ final HashSet<Pair<String, String>> bigramSet =
+ new HashSet<Pair<String,String>>(bigramProbabilitiesToCheckLater.keySet());
+ int token = 0;
+ do {
+ final BinaryDictionary.GetNextWordPropertyResult result =
+ binaryDictionary.getNextWordProperty(token);
+ final WordProperty wordProperty = result.mWordProperty;
+ final String word0 = wordProperty.mWord;
+ assertEquals((int)wordProbabilitiesToCheckLater.get(word0),
+ wordProperty.mProbabilityInfo.mProbability);
+ wordSet.remove(word0);
+ final HashSet<String> bigramWord1s = bigrams.get(word0);
+ for (int j = 0; j < wordProperty.mBigrams.size(); j++) {
+ final String word1 = wordProperty.mBigrams.get(j).mWord;
+ assertTrue(bigramWord1s.contains(word1));
+ final int probability = wordProperty.mBigrams.get(j).getProbability();
+ final Pair<String, String> bigram = new Pair<String, String>(word0, word1);
+ assertEquals((int)bigramProbabilitiesToCheckLater.get(bigram), probability);
+ bigramSet.remove(bigram);
+ }
+ token = result.mNextToken;
+ } while (token != 0);
+ assertTrue(wordSet.isEmpty());
+ assertTrue(bigramSet.isEmpty());
+ }
+
+ public void testAddShortcuts() {
+ testAddShortcuts(FormatSpec.VERSION4);
+ }
+
+ private void testAddShortcuts(final int formatVersion) {
+ File dictFile = null;
+ try {
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
+ } catch (IOException e) {
+ fail("IOException while writing an initial dictionary : " + e);
+ }
+ final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
+ 0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
+ Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
+
+ final int unigramProbability = 100;
+ final int shortcutProbability = 10;
+ binaryDictionary.addUnigramWord("aaa", unigramProbability, "zzz",
+ shortcutProbability, false /* isNotAWord */, false /* isBlacklisted */,
+ 0 /* timestamp */);
+ WordProperty wordProperty = binaryDictionary.getWordProperty("aaa");
+ assertEquals(1, wordProperty.mShortcutTargets.size());
+ assertEquals("zzz", wordProperty.mShortcutTargets.get(0).mWord);
+ assertEquals(shortcutProbability, wordProperty.mShortcutTargets.get(0).getProbability());
+ final int updatedShortcutProbability = 2;
+ binaryDictionary.addUnigramWord("aaa", unigramProbability, "zzz",
+ updatedShortcutProbability, false /* isNotAWord */, false /* isBlacklisted */,
+ 0 /* timestamp */);
+ wordProperty = binaryDictionary.getWordProperty("aaa");
+ assertEquals(1, wordProperty.mShortcutTargets.size());
+ assertEquals("zzz", wordProperty.mShortcutTargets.get(0).mWord);
+ assertEquals(updatedShortcutProbability,
+ wordProperty.mShortcutTargets.get(0).getProbability());
+ binaryDictionary.addUnigramWord("aaa", unigramProbability, "yyy",
+ shortcutProbability, false /* isNotAWord */, false /* isBlacklisted */,
+ 0 /* timestamp */);
+ final HashMap<String, Integer> shortcutTargets = new HashMap<String, Integer>();
+ shortcutTargets.put("zzz", updatedShortcutProbability);
+ shortcutTargets.put("yyy", shortcutProbability);
+ wordProperty = binaryDictionary.getWordProperty("aaa");
+ assertEquals(2, wordProperty.mShortcutTargets.size());
+ for (WeightedString shortcutTarget : wordProperty.mShortcutTargets) {
+ assertTrue(shortcutTargets.containsKey(shortcutTarget.mWord));
+ assertEquals((int)shortcutTargets.get(shortcutTarget.mWord),
+ shortcutTarget.getProbability());
+ shortcutTargets.remove(shortcutTarget.mWord);
+ }
+ shortcutTargets.put("zzz", updatedShortcutProbability);
+ shortcutTargets.put("yyy", shortcutProbability);
+ binaryDictionary.flushWithGC();
+ wordProperty = binaryDictionary.getWordProperty("aaa");
+ assertEquals(2, wordProperty.mShortcutTargets.size());
+ for (WeightedString shortcutTarget : wordProperty.mShortcutTargets) {
+ assertTrue(shortcutTargets.containsKey(shortcutTarget.mWord));
+ assertEquals((int)shortcutTargets.get(shortcutTarget.mWord),
+ shortcutTarget.getProbability());
+ shortcutTargets.remove(shortcutTarget.mWord);
+ }
+ }
+
+ public void testAddManyShortcuts() {
+ testAddManyShortcuts(FormatSpec.VERSION4);
+ }
+
+ private void testAddManyShortcuts(final int formatVersion) {
+ final long seed = System.currentTimeMillis();
+ final Random random = new Random(seed);
+ final int UNIGRAM_COUNT = 1000;
+ final int SHORTCUT_COUNT = 10000;
+ final int codePointSetSize = 20;
+ final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random);
+
+ final ArrayList<String> words = new ArrayList<String>();
+ final HashMap<String, Integer> unigramProbabilities = new HashMap<String, Integer>();
+ final HashMap<String, HashMap<String, Integer>> shortcutTargets =
+ new HashMap<String, HashMap<String, Integer>>();
+
+ File dictFile = null;
+ try {
+ dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion);
+ } catch (IOException e) {
+ fail("IOException while writing an initial dictionary : " + e);
+ }
+ final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(),
+ 0 /* offset */, dictFile.length(), true /* useFullEditDistance */,
+ Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */);
+
+ for (int i = 0; i < UNIGRAM_COUNT; i++) {
+ final String word = CodePointUtils.generateWord(random, codePointSet);
+ final int unigramProbability = random.nextInt(0xFF);
+ addUnigramWord(binaryDictionary, word, unigramProbability);
+ words.add(word);
+ unigramProbabilities.put(word, unigramProbability);
+ if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) {
+ binaryDictionary.flushWithGC();
+ }
+ }
+ for (int i = 0; i < SHORTCUT_COUNT; i++) {
+ final String shortcutTarget = CodePointUtils.generateWord(random, codePointSet);
+ final int shortcutProbability = random.nextInt(0xF);
+ final String word = words.get(random.nextInt(words.size()));
+ final int unigramProbability = unigramProbabilities.get(word);
+ binaryDictionary.addUnigramWord(word, unigramProbability, shortcutTarget,
+ shortcutProbability, false /* isNotAWord */, false /* isBlacklisted */,
+ 0 /* timestamp */);
+ if (shortcutTargets.containsKey(word)) {
+ final HashMap<String, Integer> shortcutTargetsOfWord = shortcutTargets.get(word);
+ shortcutTargetsOfWord.put(shortcutTarget, shortcutProbability);
+ } else {
+ final HashMap<String, Integer> shortcutTargetsOfWord =
+ new HashMap<String, Integer>();
+ shortcutTargetsOfWord.put(shortcutTarget, shortcutProbability);
+ shortcutTargets.put(word, shortcutTargetsOfWord);
+ }
+ if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) {
+ binaryDictionary.flushWithGC();
+ }
+ }
+
+ for (final String word : words) {
+ final WordProperty wordProperty = binaryDictionary.getWordProperty(word);
+ assertEquals((int)unigramProbabilities.get(word),
+ wordProperty.mProbabilityInfo.mProbability);
+ if (!shortcutTargets.containsKey(word)) {
+ // The word does not have shortcut targets.
+ continue;
+ }
+ assertEquals(shortcutTargets.get(word).size(), wordProperty.mShortcutTargets.size());
+ for (final WeightedString shortcutTarget : wordProperty.mShortcutTargets) {
+ final String targetCodePonts = shortcutTarget.mWord;
+ assertEquals((int)shortcutTargets.get(word).get(targetCodePonts),
+ shortcutTarget.getProbability());
+ }
+ }
+ }
}
diff --git a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
index c4fd5a0c4..6e894decf 100644
--- a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
+++ b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
@@ -50,8 +50,7 @@ public class BlueUnderlineTests extends InputTestsBase {
final SpanGetter spanBefore = new SpanGetter(mEditText.getText(), SuggestionSpan.class);
assertEquals("extend blue underline, span start", EXPECTED_SPAN_START, spanBefore.mStart);
assertEquals("extend blue underline, span end", EXPECTED_SPAN_END, spanBefore.mEnd);
- assertEquals("extend blue underline, span color", true,
- spanBefore.isAutoCorrectionIndicator());
+ assertTrue("extend blue underline, span color", spanBefore.isAutoCorrectionIndicator());
sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
runMessages();
// Now we have been able to re-evaluate the word, there shouldn't be an auto-correction span
@@ -61,6 +60,7 @@ public class BlueUnderlineTests extends InputTestsBase {
public void testBlueUnderlineOnBackspace() {
final String STRING_TO_TYPE = "tgis";
+ final int typedLength = STRING_TO_TYPE.length();
final int EXPECTED_SUGGESTION_SPAN_START = -1;
final int EXPECTED_UNDERLINE_SPAN_START = 0;
final int EXPECTED_UNDERLINE_SPAN_END = 4;
@@ -68,6 +68,8 @@ public class BlueUnderlineTests extends InputTestsBase {
sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
runMessages();
type(Constants.CODE_SPACE);
+ // typedLength + 1 because we also typed a space
+ mLatinIME.onUpdateSelection(0, 0, typedLength + 1, typedLength + 1, -1, -1);
sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
runMessages();
type(Constants.CODE_DELETE);
@@ -77,8 +79,8 @@ public class BlueUnderlineTests extends InputTestsBase {
sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
runMessages();
final SpanGetter suggestionSpan = new SpanGetter(mEditText.getText(), SuggestionSpan.class);
- assertEquals("show no blue underline after backspace, span start should be -1",
- EXPECTED_SUGGESTION_SPAN_START, suggestionSpan.mStart);
+ assertFalse("show no blue underline after backspace, span should not be the auto-"
+ + "correction indicator", suggestionSpan.isAutoCorrectionIndicator());
final SpanGetter underlineSpan = new SpanGetter(mEditText.getText(), UnderlineSpan.class);
assertEquals("should be composing, so should have an underline span",
EXPECTED_UNDERLINE_SPAN_START, underlineSpan.mStart);
@@ -104,7 +106,8 @@ public class BlueUnderlineTests extends InputTestsBase {
sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
runMessages();
final SpanGetter span = new SpanGetter(mEditText.getText(), SuggestionSpan.class);
- assertNull("blue underline removed when cursor is moved", span.mSpan);
+ assertFalse("blue underline removed when cursor is moved",
+ span.isAutoCorrectionIndicator());
}
public void testComposingStopsOnSpace() {
diff --git a/tests/src/com/android/inputmethod/latin/EditDistanceTests.java b/tests/src/com/android/inputmethod/latin/EditDistanceTests.java
index 0b7fcbbe8..ffec20ab2 100644
--- a/tests/src/com/android/inputmethod/latin/EditDistanceTests.java
+++ b/tests/src/com/android/inputmethod/latin/EditDistanceTests.java
@@ -21,16 +21,6 @@ import android.test.suitebuilder.annotation.SmallTest;
@SmallTest
public class EditDistanceTests extends AndroidTestCase {
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
/*
* dist(kitten, sitting) == 3
*
diff --git a/tests/src/com/android/inputmethod/latin/ExpandableDictionaryTests.java b/tests/src/com/android/inputmethod/latin/ExpandableDictionaryTests.java
deleted file mode 100644
index 6aae1044e..000000000
--- a/tests/src/com/android/inputmethod/latin/ExpandableDictionaryTests.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2013 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.latin;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-/**
- * Unit test for ExpandableDictionary
- */
-@SmallTest
-public class ExpandableDictionaryTests extends AndroidTestCase {
-
- private final static int UNIGRAM_FREQ = 50;
- // See UserBinaryDictionary for more information about this variable.
- // For tests, its actual value does not matter.
- private final static int SHORTCUT_FREQ = 14;
-
- public void testAddWordAndGetWordFrequency() {
- final ExpandableDictionary dict = new ExpandableDictionary(Dictionary.TYPE_USER);
-
- // Add words
- dict.addWord("abcde", "abcde", UNIGRAM_FREQ, SHORTCUT_FREQ);
- dict.addWord("abcef", null, UNIGRAM_FREQ + 1, 0);
-
- // Check words
- assertFalse(dict.isValidWord("abcde"));
- assertEquals(UNIGRAM_FREQ, dict.getWordFrequency("abcde"));
- assertTrue(dict.isValidWord("abcef"));
- assertEquals(UNIGRAM_FREQ+1, dict.getWordFrequency("abcef"));
-
- dict.addWord("abc", null, UNIGRAM_FREQ + 2, 0);
- assertTrue(dict.isValidWord("abc"));
- assertEquals(UNIGRAM_FREQ + 2, dict.getWordFrequency("abc"));
-
- // Add existing word with lower frequency
- dict.addWord("abc", null, UNIGRAM_FREQ, 0);
- assertEquals(UNIGRAM_FREQ + 2, dict.getWordFrequency("abc"));
-
- // Add existing word with higher frequency
- dict.addWord("abc", null, UNIGRAM_FREQ + 3, 0);
- assertEquals(UNIGRAM_FREQ + 3, dict.getWordFrequency("abc"));
- }
-}
diff --git a/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java b/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java
index cadd0f8f3..cf528d010 100644
--- a/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java
@@ -20,6 +20,7 @@ import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.inputmethod.latin.makedict.FusionDictionary;
+import com.android.inputmethod.latin.makedict.ProbabilityInfo;
import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
import java.util.HashMap;
@@ -31,18 +32,18 @@ import java.util.HashMap;
public class FusionDictionaryTests extends AndroidTestCase {
public void testFindWordInTree() {
FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
- new FusionDictionary.DictionaryOptions(new HashMap<String,String>(), false, false));
+ new FusionDictionary.DictionaryOptions(new HashMap<String,String>()));
- dict.add("abc", 10, null, false /* isNotAWord */);
+ dict.add("abc", new ProbabilityInfo(10), null, false /* isNotAWord */);
assertNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "aaa"));
assertNotNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "abc"));
- dict.add("aa", 10, null, false /* isNotAWord */);
+ dict.add("aa", new ProbabilityInfo(10), null, false /* isNotAWord */);
assertNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "aaa"));
assertNotNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "aa"));
- dict.add("babcd", 10, null, false /* isNotAWord */);
- dict.add("bacde", 10, null, false /* isNotAWord */);
+ dict.add("babcd", new ProbabilityInfo(10), null, false /* isNotAWord */);
+ dict.add("bacde", new ProbabilityInfo(10), null, false /* isNotAWord */);
assertNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "ba"));
assertNotNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "babcd"));
assertNotNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "bacde"));
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTests.java b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
index 8ad8689d8..ab9751380 100644
--- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java
+++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
@@ -307,12 +307,14 @@ public class InputLogicTests extends InputTestsBase {
}
public void testResumeSuggestionOnBackspace() {
- final String WORD_TO_TYPE = "and this ";
- type(WORD_TO_TYPE);
+ final String STRING_TO_TYPE = "and this ";
+ final int typedLength = STRING_TO_TYPE.length();
+ type(STRING_TO_TYPE);
assertEquals("resume suggestion on backspace", -1,
BaseInputConnection.getComposingSpanStart(mEditText.getText()));
assertEquals("resume suggestion on backspace", -1,
BaseInputConnection.getComposingSpanEnd(mEditText.getText()));
+ mLatinIME.onUpdateSelection(0, 0, typedLength, typedLength, -1, -1);
type(Constants.CODE_DELETE);
assertEquals("resume suggestion on backspace", 4,
BaseInputConnection.getComposingSpanStart(mEditText.getText()));
@@ -348,4 +350,108 @@ public class InputLogicTests extends InputTestsBase {
helperTestComposing("a'", true);
}
// TODO: Add some tests for non-BMP characters
+
+ public void testAutoCorrectByUserHistory() {
+ final String WORD_TO_BE_CORRECTED = "qpmx";
+ final String NOT_CORRECTED_RESULT = "qpmx ";
+ final String DESIRED_WORD = "qpmz";
+ final String CORRECTED_RESULT = "qpmz ";
+ final int typeCountNotToAutocorrect = 3;
+ final int typeCountToAutoCorrect = 16;
+ int startIndex = 0;
+ int endIndex = 0;
+
+ for (int i = 0; i < typeCountNotToAutocorrect; i++) {
+ type(DESIRED_WORD);
+ type(Constants.CODE_SPACE);
+ }
+ startIndex = mEditText.getText().length();
+ type(WORD_TO_BE_CORRECTED);
+ type(Constants.CODE_SPACE);
+ endIndex = mEditText.getText().length();
+ assertEquals("not auto-corrected by user history", NOT_CORRECTED_RESULT,
+ mEditText.getText().subSequence(startIndex, endIndex).toString());
+ for (int i = typeCountNotToAutocorrect; i < typeCountToAutoCorrect; i++) {
+ type(DESIRED_WORD);
+ type(Constants.CODE_SPACE);
+ }
+ startIndex = mEditText.getText().length();
+ type(WORD_TO_BE_CORRECTED);
+ type(Constants.CODE_SPACE);
+ endIndex = mEditText.getText().length();
+ assertEquals("auto-corrected by user history",
+ CORRECTED_RESULT, mEditText.getText().subSequence(startIndex, endIndex).toString());
+ }
+
+ public void testPredictionsAfterSpace() {
+ final String WORD_TO_TYPE = "Barack ";
+ type(WORD_TO_TYPE);
+ sleep(DELAY_TO_WAIT_FOR_PREDICTIONS);
+ runMessages();
+ // Test the first prediction is displayed
+ final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest();
+ assertEquals("predictions after space", "Obama",
+ suggestedWords.size() > 0 ? suggestedWords.getWord(0) : null);
+ }
+
+ public void testPredictionsAfterManualPick() {
+ final String WORD_TO_TYPE = "Barack";
+ type(WORD_TO_TYPE);
+ // Choose the auto-correction, which is always in position 0. For "Barack", the
+ // auto-correction should be "Barack".
+ pickSuggestionManually(0, WORD_TO_TYPE);
+ sleep(DELAY_TO_WAIT_FOR_PREDICTIONS);
+ runMessages();
+ // Test the first prediction is displayed
+ final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest();
+ assertEquals("predictions after manual pick", "Obama",
+ suggestedWords.size() > 0 ? suggestedWords.getWord(0) : null);
+ }
+
+ public void testNoPredictionsAfterPeriod() {
+ final String WORD_TO_TYPE = "Barack. ";
+ type(WORD_TO_TYPE);
+ sleep(DELAY_TO_WAIT_FOR_PREDICTIONS);
+ runMessages();
+ // Test the first prediction is not displayed
+ final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest();
+ assertEquals("no prediction after period", 0, suggestedWords.size());
+ }
+
+ public void testPredictionsAfterRecorrection() {
+ final String PREFIX = "A ";
+ final String WORD_TO_TYPE = "Barack";
+ final String FIRST_NON_TYPED_SUGGESTION = "Barrack";
+ final int endOfPrefix = PREFIX.length();
+ final int endOfWord = endOfPrefix + WORD_TO_TYPE.length();
+ final int endOfSuggestion = endOfPrefix + FIRST_NON_TYPED_SUGGESTION.length();
+ final int indexForManualCursor = endOfPrefix + 3; // +3 because it's after "Bar" in "Barack"
+ type(PREFIX);
+ mLatinIME.onUpdateSelection(0, 0, endOfPrefix, endOfPrefix, -1, -1);
+ type(WORD_TO_TYPE);
+ pickSuggestionManually(1, FIRST_NON_TYPED_SUGGESTION);
+ mLatinIME.onUpdateSelection(endOfPrefix, endOfPrefix, endOfSuggestion, endOfSuggestion,
+ -1, -1);
+ runMessages();
+ type(" ");
+ mLatinIME.onUpdateSelection(endOfSuggestion, endOfSuggestion,
+ endOfSuggestion + 1, endOfSuggestion + 1, -1, -1);
+ sleep(DELAY_TO_WAIT_FOR_PREDICTIONS);
+ runMessages();
+ // Simulate a manual cursor move
+ mInputConnection.setSelection(indexForManualCursor, indexForManualCursor);
+ mLatinIME.onUpdateSelection(endOfSuggestion + 1, endOfSuggestion + 1,
+ indexForManualCursor, indexForManualCursor, -1, -1);
+ sleep(DELAY_TO_WAIT_FOR_PREDICTIONS);
+ runMessages();
+ pickSuggestionManually(0, WORD_TO_TYPE);
+ mLatinIME.onUpdateSelection(indexForManualCursor, indexForManualCursor,
+ endOfWord, endOfWord, -1, -1);
+ sleep(DELAY_TO_WAIT_FOR_PREDICTIONS);
+ runMessages();
+ // Test the first prediction is displayed
+ final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest();
+ assertEquals("predictions after recorrection", "Obama",
+ suggestedWords.size() > 0 ? suggestedWords.getWord(0) : null);
+ }
}
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTestsLanguageWithoutSpaces.java b/tests/src/com/android/inputmethod/latin/InputLogicTestsLanguageWithoutSpaces.java
index 0f0ebafb9..e38ba721e 100644
--- a/tests/src/com/android/inputmethod/latin/InputLogicTestsLanguageWithoutSpaces.java
+++ b/tests/src/com/android/inputmethod/latin/InputLogicTestsLanguageWithoutSpaces.java
@@ -99,7 +99,8 @@ public class InputLogicTestsLanguageWithoutSpaces extends InputTestsBase {
assertEquals("predictions in lang without spaces", "Barack",
mEditText.getText().toString());
// Test the first prediction is displayed
+ final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest();
assertEquals("predictions in lang without spaces", "Obama",
- mLatinIME.getFirstSuggestedWord());
+ suggestedWords.size() > 0 ? suggestedWords.getWord(0) : null);
}
}
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTestsNonEnglish.java b/tests/src/com/android/inputmethod/latin/InputLogicTestsNonEnglish.java
index 2d736e338..1257ae297 100644
--- a/tests/src/com/android/inputmethod/latin/InputLogicTestsNonEnglish.java
+++ b/tests/src/com/android/inputmethod/latin/InputLogicTestsNonEnglish.java
@@ -60,7 +60,7 @@ public class InputLogicTestsNonEnglish extends InputTestsBase {
sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
runMessages();
assertTrue("type word then type space should display punctuation strip",
- mLatinIME.isShowingPunctuationList());
+ mLatinIME.getSuggestedWordsForTest().isPunctuationSuggestions());
pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
assertEquals("type word then type space then punctuation from strip twice for French",
@@ -84,8 +84,9 @@ public class InputLogicTestsNonEnglish extends InputTestsBase {
type(WORD_TO_TYPE);
sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
runMessages();
+ final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest();
assertEquals("type word then type space yields predictions for French",
- EXPECTED_RESULT, mLatinIME.getFirstSuggestedWord());
+ EXPECTED_RESULT, suggestedWords.size() > 0 ? suggestedWords.getWord(0) : null);
} finally {
setBooleanPreference(NEXT_WORD_PREDICTION_OPTION, previousNextWordPredictionOption,
defaultNextWordPredictionOption);
diff --git a/tests/src/com/android/inputmethod/latin/InputPointersTests.java b/tests/src/com/android/inputmethod/latin/InputPointersTests.java
index 5095f9606..1a47cddf4 100644
--- a/tests/src/com/android/inputmethod/latin/InputPointersTests.java
+++ b/tests/src/com/android/inputmethod/latin/InputPointersTests.java
@@ -55,14 +55,22 @@ public class InputPointersTests extends AndroidTestCase {
final InputPointers src = new InputPointers(DEFAULT_CAPACITY);
final int limit = src.getXCoordinates().length * 2 + 10;
for (int i = 0; i < limit; i++) {
- src.addPointer(i, i * 2, i * 3, i * 4);
+ final int x = i;
+ final int y = i * 2;
+ final int pointerId = i * 3;
+ final int time = i * 4;
+ src.addPointer(x, y, pointerId, time);
assertEquals("size after add " + i, i + 1, src.getPointerSize());
}
for (int i = 0; i < limit; i++) {
- assertEquals("xCoordinates at " + i, i, src.getXCoordinates()[i]);
- assertEquals("yCoordinates at " + i, i * 2, src.getYCoordinates()[i]);
- assertEquals("pointerIds at " + i, i * 3, src.getPointerIds()[i]);
- assertEquals("times at " + i, i * 4, src.getTimes()[i]);
+ final int x = i;
+ final int y = i * 2;
+ final int pointerId = i * 3;
+ final int time = i * 4;
+ assertEquals("xCoordinates at " + i, x, src.getXCoordinates()[i]);
+ assertEquals("yCoordinates at " + i, y, src.getYCoordinates()[i]);
+ assertEquals("pointerIds at " + i, pointerId, src.getPointerIds()[i]);
+ assertEquals("times at " + i, time, src.getTimes()[i]);
}
}
@@ -70,14 +78,22 @@ public class InputPointersTests extends AndroidTestCase {
final InputPointers src = new InputPointers(DEFAULT_CAPACITY);
final int limit = 1000, step = 100;
for (int i = 0; i < limit; i += step) {
- src.addPointer(i, i, i * 2, i * 3, i * 4);
+ final int x = i;
+ final int y = i * 2;
+ final int pointerId = i * 3;
+ final int time = i * 4;
+ src.addPointerAt(i, x, y, pointerId, time);
assertEquals("size after add at " + i, i + 1, src.getPointerSize());
}
for (int i = 0; i < limit; i += step) {
- assertEquals("xCoordinates at " + i, i, src.getXCoordinates()[i]);
- assertEquals("yCoordinates at " + i, i * 2, src.getYCoordinates()[i]);
- assertEquals("pointerIds at " + i, i * 3, src.getPointerIds()[i]);
- assertEquals("times at " + i, i * 4, src.getTimes()[i]);
+ final int x = i;
+ final int y = i * 2;
+ final int pointerId = i * 3;
+ final int time = i * 4;
+ assertEquals("xCoordinates at " + i, x, src.getXCoordinates()[i]);
+ assertEquals("yCoordinates at " + i, y, src.getYCoordinates()[i]);
+ assertEquals("pointerIds at " + i, pointerId, src.getPointerIds()[i]);
+ assertEquals("times at " + i, time, src.getTimes()[i]);
}
}
@@ -85,7 +101,11 @@ public class InputPointersTests extends AndroidTestCase {
final InputPointers src = new InputPointers(DEFAULT_CAPACITY);
final int limit = src.getXCoordinates().length * 2 + 10;
for (int i = 0; i < limit; i++) {
- src.addPointer(i, i * 2, i * 3, i * 4);
+ final int x = i;
+ final int y = i * 2;
+ final int pointerId = i * 3;
+ final int time = i * 4;
+ src.addPointer(x, y, pointerId, time);
}
final InputPointers dst = new InputPointers(DEFAULT_CAPACITY);
dst.set(src);
@@ -100,7 +120,11 @@ public class InputPointersTests extends AndroidTestCase {
final InputPointers src = new InputPointers(DEFAULT_CAPACITY);
final int limit = 100;
for (int i = 0; i < limit; i++) {
- src.addPointer(i, i * 2, i * 3, i * 4);
+ final int x = i;
+ final int y = i * 2;
+ final int pointerId = i * 3;
+ final int time = i * 4;
+ src.addPointer(x, y, pointerId, time);
}
final InputPointers dst = new InputPointers(DEFAULT_CAPACITY);
dst.copy(src);
@@ -121,106 +145,135 @@ public class InputPointersTests extends AndroidTestCase {
}
public void testAppend() {
- final InputPointers src = new InputPointers(DEFAULT_CAPACITY);
- final int srcLen = 100;
- for (int i = 0; i < srcLen; i++) {
- src.addPointer(i, i * 2, i * 3, i * 4);
- }
- final int dstLen = 50;
+ final int dstLength = 50;
final InputPointers dst = new InputPointers(DEFAULT_CAPACITY);
- for (int i = 0; i < dstLen; i++) {
- final int value = -i - 1;
- dst.addPointer(value * 4, value * 3, value * 2, value);
+ for (int i = 0; i < dstLength; i++) {
+ final int x = i * 4;
+ final int y = i * 3;
+ final int pointerId = i * 2;
+ final int time = i;
+ dst.addPointer(x, y, pointerId, time);
}
final InputPointers dstCopy = new InputPointers(DEFAULT_CAPACITY);
dstCopy.copy(dst);
- dst.append(src, 0, 0);
- assertEquals("size after append zero", dstLen, dst.getPointerSize());
+ final ResizableIntArray srcXCoords = new ResizableIntArray(DEFAULT_CAPACITY);
+ final ResizableIntArray srcYCoords = new ResizableIntArray(DEFAULT_CAPACITY);
+ final ResizableIntArray srcPointerIds = new ResizableIntArray(DEFAULT_CAPACITY);
+ final ResizableIntArray srcTimes = new ResizableIntArray(DEFAULT_CAPACITY);
+ final int srcLength = 100;
+ final int srcPointerId = 10;
+ for (int i = 0; i < srcLength; i++) {
+ final int x = i;
+ final int y = i * 2;
+ // The time value must be larger than <code>dst</code>.
+ final int time = i * 4 + dstLength;
+ srcXCoords.add(x);
+ srcYCoords.add(y);
+ srcPointerIds.add(srcPointerId);
+ srcTimes.add(time);
+ }
+
+ final int startPos = 0;
+ dst.append(srcPointerId, srcTimes, srcXCoords, srcYCoords,
+ startPos, 0 /* length */);
+ assertEquals("size after append zero", dstLength, dst.getPointerSize());
assertIntArrayEquals("xCoordinates after append zero",
- dstCopy.getXCoordinates(), 0, dst.getXCoordinates(), 0, dstLen);
+ dstCopy.getXCoordinates(), startPos, dst.getXCoordinates(), startPos, dstLength);
assertIntArrayEquals("yCoordinates after append zero",
- dstCopy.getYCoordinates(), 0, dst.getYCoordinates(), 0, dstLen);
+ dstCopy.getYCoordinates(), startPos, dst.getYCoordinates(), startPos, dstLength);
assertIntArrayEquals("pointerIds after append zero",
- dstCopy.getPointerIds(), 0, dst.getPointerIds(), 0, dstLen);
+ dstCopy.getPointerIds(), startPos, dst.getPointerIds(), startPos, dstLength);
assertIntArrayEquals("times after append zero",
- dstCopy.getTimes(), 0, dst.getTimes(), 0, dstLen);
+ dstCopy.getTimes(), startPos, dst.getTimes(), startPos, dstLength);
- dst.append(src, 0, srcLen);
- assertEquals("size after append", dstLen + srcLen, dst.getPointerSize());
+ dst.append(srcPointerId, srcTimes, srcXCoords, srcYCoords,
+ startPos, srcLength);
+ assertEquals("size after append", dstLength + srcLength, dst.getPointerSize());
assertTrue("primitive length after append",
- dst.getPointerIds().length >= dstLen + srcLen);
+ dst.getPointerIds().length >= dstLength + srcLength);
assertIntArrayEquals("original xCoordinates values after append",
- dstCopy.getXCoordinates(), 0, dst.getXCoordinates(), 0, dstLen);
+ dstCopy.getXCoordinates(), startPos, dst.getXCoordinates(), startPos, dstLength);
assertIntArrayEquals("original yCoordinates values after append",
- dstCopy.getYCoordinates(), 0, dst.getYCoordinates(), 0, dstLen);
+ dstCopy.getYCoordinates(), startPos, dst.getYCoordinates(), startPos, dstLength);
assertIntArrayEquals("original pointerIds values after append",
- dstCopy.getPointerIds(), 0, dst.getPointerIds(), 0, dstLen);
+ dstCopy.getPointerIds(), startPos, dst.getPointerIds(), startPos, dstLength);
assertIntArrayEquals("original times values after append",
- dstCopy.getTimes(), 0, dst.getTimes(), 0, dstLen);
+ dstCopy.getTimes(), startPos, dst.getTimes(), startPos, dstLength);
assertIntArrayEquals("appended xCoordinates values after append",
- src.getXCoordinates(), 0, dst.getXCoordinates(), dstLen, srcLen);
+ srcXCoords.getPrimitiveArray(), startPos, dst.getXCoordinates(),
+ dstLength, srcLength);
assertIntArrayEquals("appended yCoordinates values after append",
- src.getYCoordinates(), 0, dst.getYCoordinates(), dstLen, srcLen);
+ srcYCoords.getPrimitiveArray(), startPos, dst.getYCoordinates(),
+ dstLength, srcLength);
assertIntArrayEquals("appended pointerIds values after append",
- src.getPointerIds(), 0, dst.getPointerIds(), dstLen, srcLen);
+ srcPointerIds.getPrimitiveArray(), startPos, dst.getPointerIds(),
+ dstLength, srcLength);
assertIntArrayEquals("appended times values after append",
- src.getTimes(), 0, dst.getTimes(), dstLen, srcLen);
+ srcTimes.getPrimitiveArray(), startPos, dst.getTimes(), dstLength, srcLength);
}
public void testAppendResizableIntArray() {
- final int srcLen = 100;
+ final int dstLength = 50;
+ final InputPointers dst = new InputPointers(DEFAULT_CAPACITY);
+ for (int i = 0; i < dstLength; i++) {
+ final int x = i * 4;
+ final int y = i * 3;
+ final int pointerId = i * 2;
+ final int time = i;
+ dst.addPointer(x, y, pointerId, time);
+ }
+ final InputPointers dstCopy = new InputPointers(DEFAULT_CAPACITY);
+ dstCopy.copy(dst);
+
+ final int srcLength = 100;
final int srcPointerId = 1;
- final int[] srcPointerIds = new int[srcLen];
+ final int[] srcPointerIds = new int[srcLength];
Arrays.fill(srcPointerIds, srcPointerId);
final ResizableIntArray srcTimes = new ResizableIntArray(DEFAULT_CAPACITY);
final ResizableIntArray srcXCoords = new ResizableIntArray(DEFAULT_CAPACITY);
final ResizableIntArray srcYCoords= new ResizableIntArray(DEFAULT_CAPACITY);
- for (int i = 0; i < srcLen; i++) {
- srcTimes.add(i * 2);
- srcXCoords.add(i * 3);
- srcYCoords.add(i * 4);
+ for (int i = 0; i < srcLength; i++) {
+ // The time value must be larger than <code>dst</code>.
+ final int time = i * 2 + dstLength;
+ final int x = i * 3;
+ final int y = i * 4;
+ srcTimes.add(time);
+ srcXCoords.add(x);
+ srcYCoords.add(y);
}
- final int dstLen = 50;
- final InputPointers dst = new InputPointers(DEFAULT_CAPACITY);
- for (int i = 0; i < dstLen; i++) {
- final int value = -i - 1;
- dst.addPointer(value * 4, value * 3, value * 2, value);
- }
- final InputPointers dstCopy = new InputPointers(DEFAULT_CAPACITY);
- dstCopy.copy(dst);
dst.append(srcPointerId, srcTimes, srcXCoords, srcYCoords, 0, 0);
- assertEquals("size after append zero", dstLen, dst.getPointerSize());
+ assertEquals("size after append zero", dstLength, dst.getPointerSize());
assertIntArrayEquals("xCoordinates after append zero",
- dstCopy.getXCoordinates(), 0, dst.getXCoordinates(), 0, dstLen);
+ dstCopy.getXCoordinates(), 0, dst.getXCoordinates(), 0, dstLength);
assertIntArrayEquals("yCoordinates after append zero",
- dstCopy.getYCoordinates(), 0, dst.getYCoordinates(), 0, dstLen);
+ dstCopy.getYCoordinates(), 0, dst.getYCoordinates(), 0, dstLength);
assertIntArrayEquals("pointerIds after append zero",
- dstCopy.getPointerIds(), 0, dst.getPointerIds(), 0, dstLen);
+ dstCopy.getPointerIds(), 0, dst.getPointerIds(), 0, dstLength);
assertIntArrayEquals("times after append zero",
- dstCopy.getTimes(), 0, dst.getTimes(), 0, dstLen);
+ dstCopy.getTimes(), 0, dst.getTimes(), 0, dstLength);
- dst.append(srcPointerId, srcTimes, srcXCoords, srcYCoords, 0, srcLen);
- assertEquals("size after append", dstLen + srcLen, dst.getPointerSize());
+ dst.append(srcPointerId, srcTimes, srcXCoords, srcYCoords, 0, srcLength);
+ assertEquals("size after append", dstLength + srcLength, dst.getPointerSize());
assertTrue("primitive length after append",
- dst.getPointerIds().length >= dstLen + srcLen);
+ dst.getPointerIds().length >= dstLength + srcLength);
assertIntArrayEquals("original xCoordinates values after append",
- dstCopy.getXCoordinates(), 0, dst.getXCoordinates(), 0, dstLen);
+ dstCopy.getXCoordinates(), 0, dst.getXCoordinates(), 0, dstLength);
assertIntArrayEquals("original yCoordinates values after append",
- dstCopy.getYCoordinates(), 0, dst.getYCoordinates(), 0, dstLen);
+ dstCopy.getYCoordinates(), 0, dst.getYCoordinates(), 0, dstLength);
assertIntArrayEquals("original pointerIds values after append",
- dstCopy.getPointerIds(), 0, dst.getPointerIds(), 0, dstLen);
+ dstCopy.getPointerIds(), 0, dst.getPointerIds(), 0, dstLength);
assertIntArrayEquals("original times values after append",
- dstCopy.getTimes(), 0, dst.getTimes(), 0, dstLen);
+ dstCopy.getTimes(), 0, dst.getTimes(), 0, dstLength);
assertIntArrayEquals("appended xCoordinates values after append",
- srcXCoords.getPrimitiveArray(), 0, dst.getXCoordinates(), dstLen, srcLen);
+ srcXCoords.getPrimitiveArray(), 0, dst.getXCoordinates(), dstLength, srcLength);
assertIntArrayEquals("appended yCoordinates values after append",
- srcYCoords.getPrimitiveArray(), 0, dst.getYCoordinates(), dstLen, srcLen);
+ srcYCoords.getPrimitiveArray(), 0, dst.getYCoordinates(), dstLength, srcLength);
assertIntArrayEquals("appended pointerIds values after append",
- srcPointerIds, 0, dst.getPointerIds(), dstLen, srcLen);
+ srcPointerIds, 0, dst.getPointerIds(), dstLength, srcLength);
assertIntArrayEquals("appended times values after append",
- srcTimes.getPrimitiveArray(), 0, dst.getTimes(), dstLen, srcLen);
+ srcTimes.getPrimitiveArray(), 0, dst.getTimes(), dstLength, srcLength);
}
// TODO: Consolidate this method with
@@ -250,14 +303,24 @@ public class InputPointersTests extends AndroidTestCase {
final int limit = 100;
final int shiftAmount = 20;
for (int i = 0; i < limit; i++) {
- src.addPointer(i, i * 2, i * 3, i * 4);
+ final int x = i;
+ final int y = i * 2;
+ final int pointerId = i * 3;
+ final int time = i * 4;
+ src.addPointer(x, y, pointerId, time);
}
src.shift(shiftAmount);
+ assertEquals("length after shift", src.getPointerSize(), limit - shiftAmount);
for (int i = 0; i < limit - shiftAmount; ++i) {
- assertEquals("xCoordinates at " + i, i + shiftAmount, src.getXCoordinates()[i]);
- assertEquals("yCoordinates at " + i, (i + shiftAmount) * 2, src.getYCoordinates()[i]);
- assertEquals("pointerIds at " + i, (i + shiftAmount) * 3, src.getPointerIds()[i]);
- assertEquals("times at " + i, (i + shiftAmount) * 4, src.getTimes()[i]);
+ final int oldIndex = i + shiftAmount;
+ final int x = oldIndex;
+ final int y = oldIndex * 2;
+ final int pointerId = oldIndex * 3;
+ final int time = oldIndex * 4;
+ assertEquals("xCoordinates at " + i, x, src.getXCoordinates()[i]);
+ assertEquals("yCoordinates at " + i, y, src.getYCoordinates()[i]);
+ assertEquals("pointerIds at " + i, pointerId, src.getPointerIds()[i]);
+ assertEquals("times at " + i, time, src.getTimes()[i]);
}
}
}
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
index b9b52a6f3..690c559e8 100644
--- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -25,35 +25,49 @@ import android.text.InputType;
import android.text.SpannableStringBuilder;
import android.text.style.CharacterStyle;
import android.text.style.SuggestionSpan;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputMethodSubtype;
import android.widget.EditText;
import android.widget.FrameLayout;
+import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.settings.DebugSettings;
+import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.utils.LocaleUtils;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
import java.util.Locale;
+import java.util.concurrent.TimeUnit;
public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
+ private static final String TAG = InputTestsBase.class.getSimpleName();
- private static final String PREF_DEBUG_MODE = "debug_mode";
+ // Default value for auto-correction threshold. This is the string representation of the
+ // index in the resources array of auto-correction threshold settings.
+ private static final String DEFAULT_AUTO_CORRECTION_THRESHOLD = "1";
- // The message that sets the underline is posted with a 200 ms delay
- protected static final int DELAY_TO_WAIT_FOR_UNDERLINE = 200;
+ // The message that sets the underline is posted with a 500 ms delay
+ protected static final int DELAY_TO_WAIT_FOR_UNDERLINE = 500;
// The message that sets predictions is posted with a 200 ms delay
protected static final int DELAY_TO_WAIT_FOR_PREDICTIONS = 200;
+ private final int TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS = 60;
protected LatinIME mLatinIME;
protected Keyboard mKeyboard;
protected MyEditText mEditText;
protected View mInputView;
protected InputConnection mInputConnection;
+ private boolean mPreviousDebugSetting;
+ private boolean mPreviousBigramPredictionSettings;
+ private String mPreviousAutoCorrectSetting;
// A helper class to ease span tests
public static class SpanGetter {
@@ -135,13 +149,30 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
final boolean previousSetting = prefs.getBoolean(key, defaultValue);
final SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(key, value);
- editor.commit();
+ editor.apply();
+ return previousSetting;
+ }
+
+ protected String setStringPreference(final String key, final String value,
+ final String defaultValue) {
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mLatinIME);
+ final String previousSetting = prefs.getString(key, defaultValue);
+ final SharedPreferences.Editor editor = prefs.edit();
+ editor.putString(key, value);
+ editor.apply();
return previousSetting;
}
// returns the previous setting value
protected boolean setDebugMode(final boolean value) {
- return setBooleanPreference(PREF_DEBUG_MODE, value, false);
+ return setBooleanPreference(DebugSettings.PREF_DEBUG_MODE, value, false);
+ }
+
+ protected EditorInfo enrichEditorInfo(final EditorInfo ei) {
+ // Some tests that inherit from us need to add some data in the EditorInfo (see
+ // AppWorkaroundsTests#enrichEditorInfo() for a concrete example of this). Since we
+ // control the EditorInfo, we supply a hook here for children to override.
+ return ei;
}
@Override
@@ -154,15 +185,19 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
mEditText.setEnabled(true);
setupService();
mLatinIME = getService();
- final boolean previousDebugSetting = setDebugMode(true);
+ mPreviousDebugSetting = setDebugMode(true);
+ mPreviousBigramPredictionSettings = setBooleanPreference(Settings.PREF_BIGRAM_PREDICTIONS,
+ true, true /* defaultValue */);
+ mPreviousAutoCorrectSetting = setStringPreference(Settings.PREF_AUTO_CORRECTION_THRESHOLD,
+ DEFAULT_AUTO_CORRECTION_THRESHOLD, DEFAULT_AUTO_CORRECTION_THRESHOLD);
mLatinIME.onCreate();
- setDebugMode(previousDebugSetting);
- final EditorInfo ei = new EditorInfo();
+ EditorInfo ei = new EditorInfo();
final InputConnection ic = mEditText.onCreateInputConnection(ei);
final LayoutInflater inflater =
(LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final ViewGroup vg = new FrameLayout(getContext());
mInputView = inflater.inflate(R.layout.input_view, vg);
+ ei = enrichEditorInfo(ei);
mLatinIME.onCreateInputMethodInterface().startInput(ic, ei);
mLatinIME.setInputView(mInputView);
mLatinIME.onBindInput();
@@ -170,6 +205,22 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
mLatinIME.onStartInputView(ei, false);
mInputConnection = ic;
changeLanguage("en_US");
+ // Run messages to avoid the messages enqueued by startInputView() and its friends
+ // to run on a later call and ruin things. We need to wait first because some of them
+ // can be posted with a delay (notably, MSG_RESUME_SUGGESTIONS)
+ sleep(DELAY_TO_WAIT_FOR_PREDICTIONS);
+ runMessages();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mLatinIME.mHandler.removeAllMessages();
+ setBooleanPreference(Settings.PREF_BIGRAM_PREDICTIONS, mPreviousBigramPredictionSettings,
+ true /* defaultValue */);
+ setStringPreference(Settings.PREF_AUTO_CORRECTION_THRESHOLD, mPreviousAutoCorrectSetting,
+ DEFAULT_AUTO_CORRECTION_THRESHOLD);
+ setDebugMode(mPreviousDebugSetting);
+ super.tearDown();
}
// We need to run the messages added to the handler from LatinIME. The only way to do
@@ -224,40 +275,55 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> {
}
}
- protected void waitForDictionaryToBeLoaded() {
- int remainingAttempts = 300;
- while (remainingAttempts > 0 && mLatinIME.isCurrentlyWaitingForMainDictionary()) {
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- // Don't do much
- } finally {
- --remainingAttempts;
- }
+ protected void waitForDictionariesToBeLoaded() {
+ try {
+ mLatinIME.waitForLoadingDictionaries(
+ TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ Log.e(TAG, "Interrupted during waiting for loading main dictionary.", e);
}
}
protected void changeLanguage(final String locale) {
changeLanguageWithoutWait(locale);
- waitForDictionaryToBeLoaded();
+ waitForDictionariesToBeLoaded();
}
protected void changeLanguageWithoutWait(final String locale) {
mEditText.mCurrentLocale = LocaleUtils.constructLocaleFromString(locale);
- SubtypeSwitcher.getInstance().forceLocale(mEditText.mCurrentLocale);
+ // TODO: this is forcing a QWERTY keyboard for all locales, which is wrong.
+ // It's still better than using whatever keyboard is the current one, but we
+ // should actually use the default keyboard for this locale.
+ // TODO: Use {@link InputMethodSubtype.InputMethodSubtypeBuilder} directly or indirectly so
+ // that {@link InputMethodSubtype#isAsciiCapable} can return the correct value.
+ final String EXTRA_VALUE_FOR_TEST =
+ "KeyboardLayoutSet=" + SubtypeLocaleUtils.QWERTY
+ + "," + Constants.Subtype.ExtraValue.ASCII_CAPABLE
+ + "," + Constants.Subtype.ExtraValue.ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE
+ + "," + Constants.Subtype.ExtraValue.EMOJI_CAPABLE;
+ final InputMethodSubtype subtype = InputMethodSubtypeCompatUtils.newInputMethodSubtype(
+ R.string.subtype_no_language_qwerty,
+ R.drawable.ic_ime_switcher_dark,
+ locale,
+ Constants.Subtype.KEYBOARD_MODE,
+ EXTRA_VALUE_FOR_TEST,
+ false /* isAuxiliary */,
+ false /* overridesImplicitlyEnabledSubtype */,
+ 0 /* id */);
+ SubtypeSwitcher.getInstance().forceSubtype(subtype);
mLatinIME.loadKeyboard();
runMessages();
mKeyboard = mLatinIME.mKeyboardSwitcher.getKeyboard();
+ mLatinIME.clearPersonalizedDictionariesForTest();
}
protected void changeKeyboardLocaleAndDictLocale(final String keyboardLocale,
final String dictLocale) {
changeLanguage(keyboardLocale);
if (!keyboardLocale.equals(dictLocale)) {
- mLatinIME.replaceMainDictionaryForTest(
- LocaleUtils.constructLocaleFromString(dictLocale));
+ mLatinIME.replaceDictionariesForTest(LocaleUtils.constructLocaleFromString(dictLocale));
}
- waitForDictionaryToBeLoaded();
+ waitForDictionariesToBeLoaded();
}
protected void pickSuggestionManually(final int index, final String suggestion) {
diff --git a/tests/src/com/android/inputmethod/latin/LatinImeStressTests.java b/tests/src/com/android/inputmethod/latin/LatinImeStressTests.java
index 5e98cdf8d..db14b8329 100644
--- a/tests/src/com/android/inputmethod/latin/LatinImeStressTests.java
+++ b/tests/src/com/android/inputmethod/latin/LatinImeStressTests.java
@@ -41,7 +41,7 @@ public class LatinImeStressTests extends InputTestsBase {
}
}
}
- public void testSwitchLanguagesAndInputRandamCodePoints() {
+ public void testSwitchLanguagesAndInputRandomCodePoints() {
final String[] locales = {"en_US", "de", "el", "es", "fi", "it", "nl", "pt", "ru"};
final int switchCount = 50;
final int maxWordCountToTypeInEachIteration = 20;
diff --git a/tests/src/com/android/inputmethod/latin/PunctuationTests.java b/tests/src/com/android/inputmethod/latin/PunctuationTests.java
index 84ff6b307..c253e6488 100644
--- a/tests/src/com/android/inputmethod/latin/PunctuationTests.java
+++ b/tests/src/com/android/inputmethod/latin/PunctuationTests.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.latin;
+import android.provider.Settings.Secure;
import android.test.suitebuilder.annotation.LargeTest;
import com.android.inputmethod.latin.R;
@@ -40,7 +41,7 @@ public class PunctuationTests extends InputTestsBase {
sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
runMessages();
assertTrue("type word then type space should display punctuation strip",
- mLatinIME.isShowingPunctuationList());
+ mLatinIME.getSuggestedWordsForTest().isPunctuationSuggestions());
pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
pickSuggestionManually(0, PUNCTUATION_FROM_STRIP);
assertEquals("type word then type space then punctuation from strip twice",
@@ -153,7 +154,9 @@ public class PunctuationTests extends InputTestsBase {
final String WORD_TO_TYPE = "you'f ";
final String EXPECTED_RESULT = "you'd ";
type(WORD_TO_TYPE);
- assertEquals("auto-correction with single quote inside",
+ assertEquals("auto-correction with single quote inside. ID = "
+ + Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID)
+ + " ; Suggestions = " + mLatinIME.getSuggestedWordsForTest(),
EXPECTED_RESULT, mEditText.getText().toString());
}
@@ -161,7 +164,37 @@ public class PunctuationTests extends InputTestsBase {
final String WORD_TO_TYPE = "'tgis' ";
final String EXPECTED_RESULT = "'this' ";
type(WORD_TO_TYPE);
- assertEquals("auto-correction with single quotes around",
+ assertEquals("auto-correction with single quotes around. ID = "
+ + Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID)
+ + " ; Suggestions = " + mLatinIME.getSuggestedWordsForTest(),
+ EXPECTED_RESULT, mEditText.getText().toString());
+ }
+
+ public void testAutoSpaceWithDoubleQuotes() {
+ final String STRING_TO_TYPE = "He said\"hello\"to me. I replied,\"hi\"."
+ + "Then, 5\"passed. He said\"bye\"and left.";
+ final String EXPECTED_RESULT = "He said \"hello\" to me. I replied, \"hi\". "
+ + "Then, 5\" passed. He said \"bye\" and left. \"";
+ // Split by double quote, so that we can type the double quotes individually.
+ for (final String partToType : STRING_TO_TYPE.split("\"")) {
+ // Split at word boundaries. This regexp means "anywhere that is preceded
+ // by a word character but not followed by a word character, OR that is not
+ // preceded by a word character but followed by a word character".
+ // We need to input word by word because auto-spaces are only active when
+ // manually picking or gesturing (which we can't simulate yet), but only words
+ // can be picked.
+ final String[] wordsToType = partToType.split("(?<=\\w)(?!\\w)|(?<!\\w)(?=\\w)");
+ for (final String wordToType : wordsToType) {
+ type(wordToType);
+ if (wordToType.matches("^\\w+$")) {
+ // Only pick selection if that was a word, because if that was not a word,
+ // then we don't have a composition.
+ pickSuggestionManually(0, wordToType);
+ }
+ }
+ type("\"");
+ }
+ assertEquals("auto-space with double quotes",
EXPECTED_RESULT, mEditText.getText().toString());
}
}
diff --git a/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java b/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java
index c0dd9933c..7f0743543 100644
--- a/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java
+++ b/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java
@@ -16,15 +16,13 @@
package com.android.inputmethod.latin;
-import com.android.inputmethod.latin.utils.TextRange;
-
+import android.content.res.Resources;
import android.inputmethodservice.InputMethodService;
import android.os.Parcel;
import android.test.AndroidTestCase;
import android.test.MoreAsserts;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.SpannableString;
-import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.SuggestionSpan;
import android.view.inputmethod.ExtractedText;
@@ -32,6 +30,11 @@ import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputConnectionWrapper;
+import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
+import com.android.inputmethod.latin.utils.RunInLocale;
+import com.android.inputmethod.latin.utils.StringUtils;
+import com.android.inputmethod.latin.utils.TextRange;
+
import java.util.Locale;
@SmallTest
@@ -39,11 +42,19 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase {
// The following is meant to be a reasonable default for
// the "word_separators" resource.
- private static final String sSeparators = ".,:;!?-";
+ private SpacingAndPunctuations mSpacingAndPunctuations;
@Override
protected void setUp() throws Exception {
super.setUp();
+ final RunInLocale<SpacingAndPunctuations> job = new RunInLocale<SpacingAndPunctuations>() {
+ @Override
+ protected SpacingAndPunctuations job(final Resources res) {
+ return new SpacingAndPunctuations(res);
+ }
+ };
+ final Resources res = getContext().getResources();
+ mSpacingAndPunctuations = job.runInLocale(res, Locale.ENGLISH);
}
private class MockConnection extends InputConnectionWrapper {
@@ -137,9 +148,12 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase {
*/
public void testGetPreviousWord() {
// If one of the following cases breaks, the bigram suggestions won't work.
- assertEquals(RichInputConnection.getNthPreviousWord("abc def", sSeparators, 2), "abc");
- assertNull(RichInputConnection.getNthPreviousWord("abc", sSeparators, 2));
- assertNull(RichInputConnection.getNthPreviousWord("abc. def", sSeparators, 2));
+ assertEquals(RichInputConnection.getNthPreviousWord(
+ "abc def", mSpacingAndPunctuations, 2), "abc");
+ assertNull(RichInputConnection.getNthPreviousWord(
+ "abc", mSpacingAndPunctuations, 2));
+ assertNull(RichInputConnection.getNthPreviousWord(
+ "abc. def", mSpacingAndPunctuations, 2));
// The following tests reflect the current behavior of the function
// RichInputConnection#getNthPreviousWord.
@@ -148,20 +162,34 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase {
// this function if needed - especially since it does not seem very
// logical. These tests are just there to catch any unintentional
// changes in the behavior of the RichInputConnection#getPreviousWord method.
- assertEquals(RichInputConnection.getNthPreviousWord("abc def ", sSeparators, 2), "abc");
- assertEquals(RichInputConnection.getNthPreviousWord("abc def.", sSeparators, 2), "abc");
- assertEquals(RichInputConnection.getNthPreviousWord("abc def .", sSeparators, 2), "def");
- assertNull(RichInputConnection.getNthPreviousWord("abc ", sSeparators, 2));
-
- assertEquals(RichInputConnection.getNthPreviousWord("abc def", sSeparators, 1), "def");
- assertEquals(RichInputConnection.getNthPreviousWord("abc def ", sSeparators, 1), "def");
- assertNull(RichInputConnection.getNthPreviousWord("abc def.", sSeparators, 1));
- assertNull(RichInputConnection.getNthPreviousWord("abc def .", sSeparators, 1));
+ assertEquals(RichInputConnection.getNthPreviousWord(
+ "abc def ", mSpacingAndPunctuations, 2), "abc");
+ assertEquals(RichInputConnection.getNthPreviousWord(
+ "abc def.", mSpacingAndPunctuations, 2), "abc");
+ assertEquals(RichInputConnection.getNthPreviousWord(
+ "abc def .", mSpacingAndPunctuations, 2), "def");
+ assertNull(RichInputConnection.getNthPreviousWord(
+ "abc ", mSpacingAndPunctuations, 2));
+
+ assertEquals(RichInputConnection.getNthPreviousWord(
+ "abc def", mSpacingAndPunctuations, 1), "def");
+ assertEquals(RichInputConnection.getNthPreviousWord(
+ "abc def ", mSpacingAndPunctuations, 1), "def");
+ assertNull(RichInputConnection.getNthPreviousWord(
+ "abc def.", mSpacingAndPunctuations, 1));
+ assertNull(RichInputConnection.getNthPreviousWord(
+ "abc def .", mSpacingAndPunctuations, 1));
}
/**
* Test logic in getting the word range at the cursor.
*/
+ private static final int[] SPACE = { Constants.CODE_SPACE };
+ static final int[] TAB = { Constants.CODE_TAB };
+ private static final int[] SPACE_TAB = StringUtils.toSortedCodePointArray(" \t");
+ // A character that needs surrogate pair to represent its code point (U+2008A).
+ private static final String SUPPLEMENTARY_CHAR = "\uD840\uDC8A";
+
public void testGetWordRangeAtCursor() {
ExtractedText et = new ExtractedText();
final MockInputMethodService mockInputMethodService = new MockInputMethodService();
@@ -173,48 +201,47 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase {
ic.beginBatchEdit();
// basic case
- r = ic.getWordRangeAtCursor(" ", 0);
+ r = ic.getWordRangeAtCursor(SPACE, 0);
assertTrue(TextUtils.equals("word", r.mWord));
// more than one word
- r = ic.getWordRangeAtCursor(" ", 1);
+ r = ic.getWordRangeAtCursor(SPACE, 1);
assertTrue(TextUtils.equals("word word", r.mWord));
ic.endBatchEdit();
// tab character instead of space
mockInputMethodService.setInputConnection(new MockConnection("one\tword\two", "rd", et));
ic.beginBatchEdit();
- r = ic.getWordRangeAtCursor("\t", 1);
+ r = ic.getWordRangeAtCursor(TAB, 1);
ic.endBatchEdit();
assertTrue(TextUtils.equals("word\tword", r.mWord));
// only one word doesn't go too far
mockInputMethodService.setInputConnection(new MockConnection("one\tword\two", "rd", et));
ic.beginBatchEdit();
- r = ic.getWordRangeAtCursor("\t", 1);
+ r = ic.getWordRangeAtCursor(TAB, 1);
ic.endBatchEdit();
assertTrue(TextUtils.equals("word\tword", r.mWord));
// tab or space
mockInputMethodService.setInputConnection(new MockConnection("one word\two", "rd", et));
ic.beginBatchEdit();
- r = ic.getWordRangeAtCursor(" \t", 1);
+ r = ic.getWordRangeAtCursor(SPACE_TAB, 1);
ic.endBatchEdit();
assertTrue(TextUtils.equals("word\tword", r.mWord));
// tab or space multiword
mockInputMethodService.setInputConnection(new MockConnection("one word\two", "rd", et));
ic.beginBatchEdit();
- r = ic.getWordRangeAtCursor(" \t", 2);
+ r = ic.getWordRangeAtCursor(SPACE_TAB, 2);
ic.endBatchEdit();
assertTrue(TextUtils.equals("one word\tword", r.mWord));
// splitting on supplementary character
- final String supplementaryChar = "\uD840\uDC8A";
mockInputMethodService.setInputConnection(
- new MockConnection("one word" + supplementaryChar + "wo", "rd", et));
+ new MockConnection("one word" + SUPPLEMENTARY_CHAR + "wo", "rd", et));
ic.beginBatchEdit();
- r = ic.getWordRangeAtCursor(supplementaryChar, 0);
+ r = ic.getWordRangeAtCursor(StringUtils.toSortedCodePointArray(SUPPLEMENTARY_CHAR), 0);
ic.endBatchEdit();
assertTrue(TextUtils.equals("word", r.mWord));
}
@@ -244,7 +271,7 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase {
TextRange r;
SuggestionSpan[] suggestions;
- r = ic.getWordRangeAtCursor(" ", 0);
+ r = ic.getWordRangeAtCursor(SPACE, 0);
suggestions = r.getSuggestionSpansAtWord();
assertEquals(suggestions.length, 1);
MoreAsserts.assertEquals(suggestions[0].getSuggestions(), SUGGESTIONS1);
@@ -256,7 +283,7 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase {
text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS2, 0 /* flags */),
10 /* start */, 16 /* end */, 0 /* flags */);
mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos));
- r = ic.getWordRangeAtCursor(" ", 0);
+ r = ic.getWordRangeAtCursor(SPACE, 0);
suggestions = r.getSuggestionSpansAtWord();
assertEquals(suggestions.length, 2);
MoreAsserts.assertEquals(suggestions[0].getSuggestions(), SUGGESTIONS1);
@@ -269,7 +296,7 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase {
text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS2, 0 /* flags */),
5 /* start */, 16 /* end */, 0 /* flags */);
mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos));
- r = ic.getWordRangeAtCursor(" ", 0);
+ r = ic.getWordRangeAtCursor(SPACE, 0);
suggestions = r.getSuggestionSpansAtWord();
assertEquals(suggestions.length, 1);
MoreAsserts.assertEquals(suggestions[0].getSuggestions(), SUGGESTIONS1);
@@ -281,7 +308,7 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase {
text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS2, 0 /* flags */),
10 /* start */, 20 /* end */, 0 /* flags */);
mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos));
- r = ic.getWordRangeAtCursor(" ", 0);
+ r = ic.getWordRangeAtCursor(SPACE, 0);
suggestions = r.getSuggestionSpansAtWord();
assertEquals(suggestions.length, 1);
MoreAsserts.assertEquals(suggestions[0].getSuggestions(), SUGGESTIONS1);
@@ -293,7 +320,7 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase {
text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS2, 0 /* flags */),
5 /* start */, 20 /* end */, 0 /* flags */);
mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos));
- r = ic.getWordRangeAtCursor(" ", 0);
+ r = ic.getWordRangeAtCursor(SPACE, 0);
suggestions = r.getSuggestionSpansAtWord();
assertEquals(suggestions.length, 1);
MoreAsserts.assertEquals(suggestions[0].getSuggestions(), SUGGESTIONS1);
@@ -305,7 +332,7 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase {
text.setSpan(new SuggestionSpan(Locale.ENGLISH, SUGGESTIONS2, 0 /* flags */),
5 /* start */, 20 /* end */, 0 /* flags */);
mockInputMethodService.setInputConnection(new MockConnection(text, cursorPos));
- r = ic.getWordRangeAtCursor(" ", 0);
+ r = ic.getWordRangeAtCursor(SPACE, 0);
suggestions = r.getSuggestionSpansAtWord();
assertEquals(suggestions.length, 0);
}
diff --git a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
index 375352067..8fe473523 100644
--- a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
+++ b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java
@@ -46,10 +46,9 @@ public class SuggestedWordsTests extends AndroidTestCase {
}
final SuggestedWords words = new SuggestedWords(
- list,
+ list, null /* rawSuggestions */,
false /* typedWordValid */,
false /* willAutoCorrect */,
- false /* isPunctuationSuggestions */,
false /* isObsoleteSuggestions */,
false /* isPrediction*/);
assertEquals(NUMBER_OF_ADDED_SUGGESTIONS + 1, words.size());
diff --git a/tests/src/com/android/inputmethod/latin/WordComposerTests.java b/tests/src/com/android/inputmethod/latin/WordComposerTests.java
index 1434c6b63..d68bb5c54 100644
--- a/tests/src/com/android/inputmethod/latin/WordComposerTests.java
+++ b/tests/src/com/android/inputmethod/latin/WordComposerTests.java
@@ -19,6 +19,9 @@ package com.android.inputmethod.latin;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.inputmethod.latin.utils.CoordinateUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
+
/**
* Unit tests for WordComposer.
*/
@@ -26,10 +29,20 @@ import android.test.suitebuilder.annotation.SmallTest;
public class WordComposerTests extends AndroidTestCase {
public void testMoveCursor() {
final WordComposer wc = new WordComposer();
+ // BMP is the Basic Multilingual Plane, as defined by Unicode. This includes
+ // most characters for most scripts, including all Roman alphabet languages,
+ // CJK, Arabic, Hebrew. Notable exceptions include some emoji and some
+ // very rare Chinese ideograms. BMP characters can be encoded on 2 bytes
+ // in UTF-16, whereas those outside the BMP need 4 bytes.
+ // http://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane
final String STR_WITHIN_BMP = "abcdef";
- wc.setComposingWord(STR_WITHIN_BMP, null);
- assertEquals(wc.size(),
- STR_WITHIN_BMP.codePointCount(0, STR_WITHIN_BMP.length()));
+ final int[] CODEPOINTS_WITHIN_BMP = StringUtils.toCodePointArray(STR_WITHIN_BMP);
+ final int[] COORDINATES_WITHIN_BMP =
+ CoordinateUtils.newCoordinateArray(CODEPOINTS_WITHIN_BMP.length,
+ Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
+ final String PREVWORD = "prevword";
+ wc.setComposingWord(CODEPOINTS_WITHIN_BMP, COORDINATES_WITHIN_BMP, PREVWORD);
+ assertEquals(wc.size(), STR_WITHIN_BMP.codePointCount(0, STR_WITHIN_BMP.length()));
assertFalse(wc.isCursorFrontOrMiddleOfComposingWord());
wc.setCursorPositionWithinWord(2);
assertTrue(wc.isCursorFrontOrMiddleOfComposingWord());
@@ -43,15 +56,26 @@ public class WordComposerTests extends AndroidTestCase {
// Move the cursor to after the 'f'
assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(1));
assertFalse(wc.isCursorFrontOrMiddleOfComposingWord());
+ // Check the previous word is still there
+ assertEquals(PREVWORD, wc.getPreviousWordForSuggestion());
// Move the cursor past the end of the word
assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(1));
assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(15));
+ // Do what LatinIME does when the cursor is moved outside of the word,
+ // and check the behavior is correct.
+ wc.reset();
+ assertNull(wc.getPreviousWordForSuggestion());
// \uD861\uDED7 is 𨛗, a character outside the BMP
final String STR_WITH_SUPPLEMENTARY_CHAR = "abcde\uD861\uDED7fgh";
- wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null);
- assertEquals(wc.size(), STR_WITH_SUPPLEMENTARY_CHAR.codePointCount(0,
- STR_WITH_SUPPLEMENTARY_CHAR.length()));
+ final int[] CODEPOINTS_WITH_SUPPLEMENTARY_CHAR =
+ StringUtils.toCodePointArray(STR_WITH_SUPPLEMENTARY_CHAR);
+ final int[] COORDINATES_WITH_SUPPLEMENTARY_CHAR =
+ CoordinateUtils.newCoordinateArray(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR.length,
+ Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
+ wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
+ null /* previousWord */);
+ assertEquals(wc.size(), CODEPOINTS_WITH_SUPPLEMENTARY_CHAR.length);
assertFalse(wc.isCursorFrontOrMiddleOfComposingWord());
wc.setCursorPositionWithinWord(3);
assertTrue(wc.isCursorFrontOrMiddleOfComposingWord());
@@ -59,34 +83,48 @@ public class WordComposerTests extends AndroidTestCase {
assertTrue(wc.isCursorFrontOrMiddleOfComposingWord());
assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(1));
assertFalse(wc.isCursorFrontOrMiddleOfComposingWord());
+ assertNull(wc.getPreviousWordForSuggestion());
- wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null);
+ wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
+ STR_WITHIN_BMP);
wc.setCursorPositionWithinWord(3);
assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(7));
+ assertEquals(STR_WITHIN_BMP, wc.getPreviousWordForSuggestion());
- wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null);
+ wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
+ STR_WITH_SUPPLEMENTARY_CHAR);
wc.setCursorPositionWithinWord(3);
assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(7));
+ assertEquals(STR_WITH_SUPPLEMENTARY_CHAR, wc.getPreviousWordForSuggestion());
- wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null);
+ wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
+ STR_WITHIN_BMP);
wc.setCursorPositionWithinWord(3);
assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(-3));
assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(-1));
+ assertEquals(STR_WITHIN_BMP, wc.getPreviousWordForSuggestion());
- wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null);
+ wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
+ null /* previousWord */);
wc.setCursorPositionWithinWord(3);
assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(-9));
+ assertNull(wc.getPreviousWordForSuggestion());
- wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null);
+ wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
+ STR_WITH_SUPPLEMENTARY_CHAR);
assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(-10));
+ assertEquals(STR_WITH_SUPPLEMENTARY_CHAR, wc.getPreviousWordForSuggestion());
- wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null);
+ wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
+ null /* previousWord */);
assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(-11));
- wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null);
+ wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
+ null /* previousWord */);
assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(0));
- wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null);
+ wc.setComposingWord(CODEPOINTS_WITH_SUPPLEMENTARY_CHAR, COORDINATES_WITH_SUPPLEMENTARY_CHAR,
+ null /* previousWord */);
wc.setCursorPositionWithinWord(2);
assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(0));
}
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
index 32c07e106..e21e340c2 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java
@@ -17,30 +17,30 @@
package com.android.inputmethod.latin.makedict;
import android.test.AndroidTestCase;
-import android.test.MoreAsserts;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
+import android.util.Pair;
import android.util.SparseArray;
+import com.android.inputmethod.latin.BinaryDictionary;
import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding;
import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
-import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
-import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
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.ByteArrayDictBuffer;
import com.android.inputmethod.latin.utils.CollectionUtils;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
@@ -52,18 +52,18 @@ import java.util.TreeMap;
@LargeTest
public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
private static final String TAG = BinaryDictDecoderEncoderTests.class.getSimpleName();
- private static final int DEFAULT_MAX_UNIGRAMS = 100;
+ private static final int DEFAULT_MAX_UNIGRAMS = 300;
private static final int DEFAULT_CODE_POINT_SET_SIZE = 50;
+ private static final int LARGE_CODE_POINT_SET_SIZE = 300;
private static final int UNIGRAM_FREQ = 10;
private static final int BIGRAM_FREQ = 50;
private static final int TOLERANCE_OF_BIGRAM_FREQ = 5;
private static final int NUM_OF_NODES_HAVING_SHORTCUTS = 50;
private static final int NUM_OF_SHORTCUTS = 5;
- private static final int USE_BYTE_ARRAY = 1;
- private static final int USE_BYTE_BUFFER = 2;
-
private static final ArrayList<String> sWords = CollectionUtils.newArrayList();
+ private static final ArrayList<String> sWordsWithVariousCodePoints =
+ CollectionUtils.newArrayList();
private static final SparseArray<List<Integer>> sEmptyBigrams =
CollectionUtils.newSparseArray();
private static final SparseArray<List<Integer>> sStarBigrams = CollectionUtils.newSparseArray();
@@ -71,33 +71,18 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
CollectionUtils.newSparseArray();
private static final HashMap<String, List<String>> sShortcuts = CollectionUtils.newHashMap();
- private static final FormatSpec.FormatOptions VERSION2 = new FormatSpec.FormatOptions(2);
- private static final FormatSpec.FormatOptions VERSION3_WITHOUT_DYNAMIC_UPDATE =
- new FormatSpec.FormatOptions(3, false /* supportsDynamicUpdate */);
- private static final FormatSpec.FormatOptions VERSION3_WITH_DYNAMIC_UPDATE =
- new FormatSpec.FormatOptions(3, true /* supportsDynamicUpdate */);
- private static final FormatSpec.FormatOptions VERSION4_WITHOUT_DYNAMIC_UPDATE =
- new FormatSpec.FormatOptions(4, false /* supportsDynamicUpdate */);
- private static final FormatSpec.FormatOptions VERSION4_WITH_DYNAMIC_UPDATE =
- new FormatSpec.FormatOptions(4, true /* supportsDynamicUpdate */);
- private static final FormatSpec.FormatOptions VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP =
- new FormatSpec.FormatOptions(4, true /* supportsDynamicUpdate */,
- true /* hasTimestamp */);
-
- private static final String TEST_DICT_FILE_EXTENSION = ".testDict";
-
public BinaryDictDecoderEncoderTests() {
this(System.currentTimeMillis(), DEFAULT_MAX_UNIGRAMS);
}
public BinaryDictDecoderEncoderTests(final long seed, final int maxUnigrams) {
super();
+ BinaryDictionary.setCurrentTimeForTest(0);
Log.e(TAG, "Testing dictionary: seed is " + seed);
final Random random = new Random(seed);
sWords.clear();
- final int[] codePointSet = CodePointUtils.generateCodePointSet(DEFAULT_CODE_POINT_SET_SIZE,
- random);
- generateWords(maxUnigrams, random, codePointSet);
+ sWordsWithVariousCodePoints.clear();
+ generateWords(maxUnigrams, random);
for (int i = 0; i < sWords.size(); ++i) {
sChainBigrams.put(i, new ArrayList<Integer>());
@@ -124,23 +109,35 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
}
}
- private DictEncoder getDictEncoder(final File file, final FormatOptions formatOptions) {
- if (formatOptions.mVersion == FormatSpec.VERSION4) {
- return new Ver4DictEncoder(getContext().getCacheDir());
- } else if (formatOptions.mVersion == 3 || formatOptions.mVersion == 2) {
- return new Ver3DictEncoder(file);
- } else {
- throw new RuntimeException("The format option has a wrong version : "
- + formatOptions.mVersion);
- }
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ BinaryDictionary.setCurrentTimeForTest(0);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ // Quit test mode.
+ BinaryDictionary.setCurrentTimeForTest(-1);
+ super.tearDown();
}
- private void generateWords(final int number, final Random random, final int[] codePointSet) {
+ private void generateWords(final int number, final Random random) {
+ final int[] codePointSet = CodePointUtils.generateCodePointSet(DEFAULT_CODE_POINT_SET_SIZE,
+ random);
final Set<String> wordSet = CollectionUtils.newHashSet();
while (wordSet.size() < number) {
wordSet.add(CodePointUtils.generateWord(random, codePointSet));
}
sWords.addAll(wordSet);
+
+ final int[] largeCodePointSet = CodePointUtils.generateCodePointSet(
+ LARGE_CODE_POINT_SET_SIZE, random);
+ wordSet.clear();
+ while (wordSet.size() < number) {
+ wordSet.add(CodePointUtils.generateWord(random, largeCodePointSet));
+ }
+ sWordsWithVariousCodePoints.addAll(wordSet);
}
/**
@@ -156,8 +153,8 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
shortcuts.add(new WeightedString(shortcut, UNIGRAM_FREQ));
}
}
- dict.add(word, UNIGRAM_FREQ, (shortcutMap == null) ? null : shortcuts,
- false /* isNotAWord */);
+ dict.add(word, new ProbabilityInfo(UNIGRAM_FREQ),
+ (shortcutMap == null) ? null : shortcuts, false /* isNotAWord */);
}
}
@@ -167,7 +164,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
for (int i = 0; i < bigrams.size(); ++i) {
final int w1 = bigrams.keyAt(i);
for (int w2 : bigrams.valueAt(i)) {
- dict.setBigram(words.get(w1), words.get(w2), BIGRAM_FREQ);
+ dict.setBigram(words.get(w1), words.get(w2), new ProbabilityInfo(BIGRAM_FREQ));
}
}
}
@@ -186,7 +183,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
long now = -1, diff = -1;
try {
- final DictEncoder dictEncoder = getDictEncoder(file, formatOptions);
+ final DictEncoder dictEncoder = BinaryDictUtils.getDictEncoder(file, formatOptions);
now = System.currentTimeMillis();
// If you need to dump the dict to a textual file, uncomment the line below and the
@@ -241,56 +238,22 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
private String outputOptions(final int bufferType,
final FormatSpec.FormatOptions formatOptions) {
String result = " : buffer type = "
- + ((bufferType == USE_BYTE_BUFFER) ? "byte buffer" : "byte array");
- result += " : version = " + formatOptions.mVersion;
- return result + ", supportsDynamicUpdate = " + formatOptions.mSupportsDynamicUpdate;
- }
-
- private DictionaryOptions getDictionaryOptions(final String id, final String version) {
- final DictionaryOptions options = new DictionaryOptions(new HashMap<String, String>(),
- false, false);
- options.mAttributes.put("version", version);
- options.mAttributes.put("dictionary", id);
- return options;
+ + ((bufferType == BinaryDictUtils.USE_BYTE_BUFFER) ? "byte buffer" : "byte array");
+ return result + " : version = " + formatOptions.mVersion;
}
- private File setUpDictionaryFile(final String name, final String version) {
- File file = null;
- try {
- file = new File(getContext().getCacheDir(), name + "." + version
- + TEST_DICT_FILE_EXTENSION);
- file.createNewFile();
- } catch (IOException e) {
- // do nothing
- }
- assertTrue("Failed to create the dictionary file.", file.exists());
- return file;
- }
-
- private DictDecoder getDictDecoder(final File file, final int bufferType,
- final FormatOptions formatOptions, final DictionaryOptions dictOptions) {
- if (formatOptions.mVersion == FormatSpec.VERSION4) {
- final FileHeader header = new FileHeader(0, dictOptions, formatOptions);
- return FormatSpec.getDictDecoder(new File(getContext().getCacheDir(),
- header.getId() + "." + header.getVersion()), bufferType);
- } else {
- return FormatSpec.getDictDecoder(file, bufferType);
- }
- }
// Tests for readDictionaryBinary and writeDictionaryBinary
private long timeReadingAndCheckDict(final File file, final List<String> words,
final SparseArray<List<Integer>> bigrams,
- final HashMap<String, List<String>> shortcutMap, final int bufferType,
- final FormatOptions formatOptions, final DictionaryOptions dictOptions) {
+ final HashMap<String, List<String>> shortcutMap, final int bufferType) {
long now, diff = -1;
FusionDictionary dict = null;
try {
- final DictDecoder dictDecoder = getDictDecoder(file, bufferType, formatOptions,
- dictOptions);
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, bufferType);
now = System.currentTimeMillis();
- dict = dictDecoder.readDictionaryBinary(null, false /* deleteDictIfBroken */);
+ dict = dictDecoder.readDictionaryBinary(false /* deleteDictIfBroken */);
diff = System.currentTimeMillis() - now;
} catch (IOException e) {
Log.e(TAG, "IOException while reading dictionary", e);
@@ -310,17 +273,17 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
final String dictName = "runReadAndWrite";
final String dictVersion = Long.toString(System.currentTimeMillis());
- final File file = setUpDictionaryFile(dictName, dictVersion);
+ final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions,
+ getContext().getCacheDir());
final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
- getDictionaryOptions(dictName, dictVersion));
+ BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions));
addUnigrams(words.size(), dict, words, shortcuts);
addBigrams(dict, words, bigrams);
checkDictionary(dict, words, bigrams, shortcuts);
final long write = timeWritingDictToFile(file, dict, formatOptions);
- final long read = timeReadingAndCheckDict(file, words, bigrams, shortcuts, bufferType,
- formatOptions, dict.mOptions);
+ final long read = timeReadingAndCheckDict(file, words, bigrams, shortcuts, bufferType);
return "PROF: read=" + read + "ms, write=" + write + "ms :" + message
+ " : " + outputOptions(bufferType, formatOptions);
@@ -340,6 +303,9 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
"chain with shortcuts"));
results.add(runReadAndWrite(sWords, sStarBigrams, sShortcuts, bufferType, formatOptions,
"star with shortcuts"));
+ results.add(runReadAndWrite(sWordsWithVariousCodePoints, sEmptyBigrams,
+ null /* shortcuts */, bufferType, formatOptions,
+ "unigram with various code points"));
}
// Unit test for CharEncoding.readString and CharEncoding.writeString.
@@ -349,8 +315,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
final byte[] buffer = new byte[50 * 3];
final DictBuffer dictBuffer = new ByteArrayDictBuffer(buffer);
for (final String word : sWords) {
- Log.d("testReadAndWriteString", "write : " + word);
- Arrays.fill(buffer, (byte)0);
+ Arrays.fill(buffer, (byte) 0);
CharEncoding.writeString(buffer, 0, word);
dictBuffer.position(0);
final String str = CharEncoding.readString(dictBuffer);
@@ -361,13 +326,12 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
public void testReadAndWriteWithByteBuffer() {
final List<String> results = CollectionUtils.newArrayList();
- runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION2);
- runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITHOUT_DYNAMIC_UPDATE);
- runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITH_DYNAMIC_UPDATE);
- runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION4_WITHOUT_DYNAMIC_UPDATE);
- runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION4_WITH_DYNAMIC_UPDATE);
- runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP);
-
+ runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_BUFFER,
+ BinaryDictUtils.VERSION2_OPTIONS);
+ runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_BUFFER,
+ BinaryDictUtils.VERSION4_OPTIONS_WITHOUT_TIMESTAMP);
+ runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_BUFFER,
+ BinaryDictUtils.VERSION4_OPTIONS_WITH_TIMESTAMP);
for (final String result : results) {
Log.d(TAG, result);
}
@@ -376,12 +340,12 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
public void testReadAndWriteWithByteArray() {
final List<String> results = CollectionUtils.newArrayList();
- runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION2);
- runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITHOUT_DYNAMIC_UPDATE);
- runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITH_DYNAMIC_UPDATE);
- runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION4_WITHOUT_DYNAMIC_UPDATE);
- runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION4_WITH_DYNAMIC_UPDATE);
- runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP);
+ runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_ARRAY,
+ BinaryDictUtils.VERSION2_OPTIONS);
+ runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_ARRAY,
+ BinaryDictUtils.VERSION4_OPTIONS_WITHOUT_TIMESTAMP);
+ runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_ARRAY,
+ BinaryDictUtils.VERSION4_OPTIONS_WITH_TIMESTAMP);
for (final String result : results) {
Log.d(TAG, result);
@@ -394,53 +358,54 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
final SparseArray<List<Integer>> expectedBigrams,
final TreeMap<Integer, String> resultWords,
final TreeMap<Integer, Integer> resultFrequencies,
- final TreeMap<Integer, ArrayList<PendingAttribute>> resultBigrams) {
+ final TreeMap<Integer, ArrayList<PendingAttribute>> resultBigrams,
+ final boolean checkProbability) {
// check unigrams
final Set<String> actualWordsSet = new HashSet<String>(resultWords.values());
final Set<String> expectedWordsSet = new HashSet<String>(expectedWords);
assertEquals(actualWordsSet, expectedWordsSet);
-
- for (int freq : resultFrequencies.values()) {
- assertEquals(freq, UNIGRAM_FREQ);
+ if (checkProbability) {
+ for (int freq : resultFrequencies.values()) {
+ assertEquals(freq, UNIGRAM_FREQ);
+ }
}
// check bigrams
- final HashMap<String, List<String>> expBigrams = new HashMap<String, List<String>>();
+ final HashMap<String, Set<String>> expBigrams = new HashMap<String, Set<String>>();
for (int i = 0; i < expectedBigrams.size(); ++i) {
final String word1 = expectedWords.get(expectedBigrams.keyAt(i));
for (int w2 : expectedBigrams.valueAt(i)) {
if (expBigrams.get(word1) == null) {
- expBigrams.put(word1, new ArrayList<String>());
+ expBigrams.put(word1, new HashSet<String>());
}
expBigrams.get(word1).add(expectedWords.get(w2));
}
}
- final HashMap<String, List<String>> actBigrams = new HashMap<String, List<String>>();
+ final HashMap<String, Set<String>> actBigrams = new HashMap<String, Set<String>>();
for (Entry<Integer, ArrayList<PendingAttribute>> entry : resultBigrams.entrySet()) {
final String word1 = resultWords.get(entry.getKey());
final int unigramFreq = resultFrequencies.get(entry.getKey());
for (PendingAttribute attr : entry.getValue()) {
final String word2 = resultWords.get(attr.mAddress);
if (actBigrams.get(word1) == null) {
- actBigrams.put(word1, new ArrayList<String>());
+ actBigrams.put(word1, new HashSet<String>());
}
actBigrams.get(word1).add(word2);
- final int bigramFreq = BinaryDictIOUtils.reconstructBigramFrequency(
- unigramFreq, attr.mFrequency);
- assertTrue(Math.abs(bigramFreq - BIGRAM_FREQ) < TOLERANCE_OF_BIGRAM_FREQ);
+ if (checkProbability) {
+ final int bigramFreq = BinaryDictIOUtils.reconstructBigramFrequency(
+ unigramFreq, attr.mFrequency);
+ assertTrue(Math.abs(bigramFreq - BIGRAM_FREQ) < TOLERANCE_OF_BIGRAM_FREQ);
+ }
}
}
-
assertEquals(actBigrams, expBigrams);
}
private long timeAndCheckReadUnigramsAndBigramsBinary(final File file, final List<String> words,
final SparseArray<List<Integer>> bigrams, final int bufferType,
- final FormatOptions formatOptions, final DictionaryOptions dictOptions) {
- FileInputStream inStream = null;
-
+ final boolean checkProbability) {
final TreeMap<Integer, String> resultWords = CollectionUtils.newTreeMap();
final TreeMap<Integer, ArrayList<PendingAttribute>> resultBigrams =
CollectionUtils.newTreeMap();
@@ -448,8 +413,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
long now = -1, diff = -1;
try {
- final DictDecoder dictDecoder = getDictDecoder(file, bufferType, formatOptions,
- dictOptions);
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, bufferType);
now = System.currentTimeMillis();
dictDecoder.readUnigramsAndBigramsBinary(resultWords, resultFreqs, resultBigrams);
diff = System.currentTimeMillis() - now;
@@ -457,17 +421,9 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
Log.e(TAG, "IOException", e);
} catch (UnsupportedFormatException e) {
Log.e(TAG, "UnsupportedFormatException", e);
- } finally {
- if (inStream != null) {
- try {
- inStream.close();
- } catch (IOException e) {
- // do nothing
- }
- }
}
- checkWordMap(words, bigrams, resultWords, resultFreqs, resultBigrams);
+ checkWordMap(words, bigrams, resultWords, resultFreqs, resultBigrams, checkProbability);
return diff;
}
@@ -476,20 +432,24 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
final FormatSpec.FormatOptions formatOptions, final String message) {
final String dictName = "runReadUnigrams";
final String dictVersion = Long.toString(System.currentTimeMillis());
- final File file = setUpDictionaryFile(dictName, dictVersion);
+ final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions,
+ getContext().getCacheDir());
// making the dictionary from lists of words.
final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
- getDictionaryOptions(dictName, dictVersion));
+ BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions));
addUnigrams(words.size(), dict, words, null /* shortcutMap */);
addBigrams(dict, words, bigrams);
timeWritingDictToFile(file, dict, formatOptions);
+ // Caveat: Currently, the Java code to read a v4 dictionary doesn't calculate the
+ // probability when there's a timestamp for the entry.
+ // TODO: Abandon the Java code, and implement the v4 dictionary reading code in native.
long wordMap = timeAndCheckReadUnigramsAndBigramsBinary(file, words, bigrams, bufferType,
- formatOptions, dict.mOptions);
+ !formatOptions.mHasTimestamp /* checkProbability */);
long fullReading = timeReadingAndCheckDict(file, words, bigrams, null /* shortcutMap */,
- bufferType, formatOptions, dict.mOptions);
+ bufferType);
return "readDictionaryBinary=" + fullReading + ", readUnigramsAndBigramsBinary=" + wordMap
+ " : " + message + " : " + outputOptions(bufferType, formatOptions);
@@ -508,13 +468,8 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
public void testReadUnigramsAndBigramsBinaryWithByteBuffer() {
final ArrayList<String> results = CollectionUtils.newArrayList();
- runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION2);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITHOUT_DYNAMIC_UPDATE);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITH_DYNAMIC_UPDATE);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION4_WITHOUT_DYNAMIC_UPDATE);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION4_WITH_DYNAMIC_UPDATE);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER,
- VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP);
+ runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_BUFFER,
+ BinaryDictUtils.VERSION2_OPTIONS);
for (final String result : results) {
Log.d(TAG, result);
@@ -524,13 +479,8 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
public void testReadUnigramsAndBigramsBinaryWithByteArray() {
final ArrayList<String> results = CollectionUtils.newArrayList();
- runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION2);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITHOUT_DYNAMIC_UPDATE);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITH_DYNAMIC_UPDATE);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION4_WITHOUT_DYNAMIC_UPDATE);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION4_WITH_DYNAMIC_UPDATE);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY,
- VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP);
+ runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_ARRAY,
+ BinaryDictUtils.VERSION2_OPTIONS);
for (final String result : results) {
Log.d(TAG, result);
@@ -541,7 +491,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
private String getWordFromBinary(final DictDecoder dictDecoder, final int address) {
if (dictDecoder.getPosition() != 0) dictDecoder.setPosition(0);
- FileHeader fileHeader = null;
+ DictionaryHeader fileHeader = null;
try {
fileHeader = dictDecoder.readHeader();
} catch (IOException e) {
@@ -550,8 +500,8 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
return null;
}
if (fileHeader == null) return null;
- return BinaryDictDecoderUtils.getWordAtPosition(dictDecoder, fileHeader.mHeaderSize,
- address, fileHeader.mFormatOptions).mWord;
+ return BinaryDictDecoderUtils.getWordAtPosition(dictDecoder, fileHeader.mBodyOffset,
+ address).mWord;
}
private long checkGetTerminalPosition(final DictDecoder dictDecoder, final String word,
@@ -578,20 +528,21 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
final FormatOptions formatOptions, final String message) {
final String dictName = "testGetTerminalPosition";
final String dictVersion = Long.toString(System.currentTimeMillis());
- final File file = setUpDictionaryFile(dictName, dictVersion);
+ final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions,
+ getContext().getCacheDir());
final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
- getDictionaryOptions(dictName, dictVersion));
+ BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions));
addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */);
addBigrams(dict, words, bigrams);
timeWritingDictToFile(file, dict, formatOptions);
- final DictDecoder dictDecoder = getDictDecoder(file, DictDecoder.USE_BYTEARRAY,
- formatOptions, dict.mOptions);
+ final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, DictDecoder.USE_BYTEARRAY);
try {
dictDecoder.openDictBuffer();
} catch (IOException e) {
- // ignore
+ Log.e(TAG, "IOException while opening the buffer", e);
+ } catch (UnsupportedFormatException e) {
Log.e(TAG, "IOException while opening the buffer", e);
}
assertTrue("Can't get the buffer", dictDecoder.isDictBufferOpen());
@@ -638,65 +589,110 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase {
public void testGetTerminalPosition() {
final ArrayList<String> results = CollectionUtils.newArrayList();
- runGetTerminalPositionTests(USE_BYTE_ARRAY, VERSION2);
- runGetTerminalPositionTests(USE_BYTE_ARRAY, VERSION3_WITHOUT_DYNAMIC_UPDATE);
- runGetTerminalPositionTests(USE_BYTE_ARRAY, VERSION3_WITH_DYNAMIC_UPDATE);
- runGetTerminalPositionTests(USE_BYTE_ARRAY, VERSION4_WITHOUT_DYNAMIC_UPDATE);
- runGetTerminalPositionTests(USE_BYTE_ARRAY, VERSION4_WITH_DYNAMIC_UPDATE);
- runGetTerminalPositionTests(USE_BYTE_ARRAY, VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP);
-
- runGetTerminalPositionTests(USE_BYTE_BUFFER, VERSION2);
- runGetTerminalPositionTests(USE_BYTE_BUFFER, VERSION3_WITHOUT_DYNAMIC_UPDATE);
- runGetTerminalPositionTests(USE_BYTE_BUFFER, VERSION3_WITH_DYNAMIC_UPDATE);
- runGetTerminalPositionTests(USE_BYTE_BUFFER, VERSION4_WITHOUT_DYNAMIC_UPDATE);
- runGetTerminalPositionTests(USE_BYTE_BUFFER, VERSION4_WITH_DYNAMIC_UPDATE);
- runGetTerminalPositionTests(USE_BYTE_BUFFER, VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP);
+ runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_ARRAY,
+ BinaryDictUtils.VERSION2_OPTIONS);
+ runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_BUFFER,
+ BinaryDictUtils.VERSION2_OPTIONS);
for (final String result : results) {
Log.d(TAG, result);
}
}
- private void runTestDeleteWord(final FormatOptions formatOptions) {
- final String dictName = "testDeleteWord";
+ public void testVer2DictGetWordProperty() {
+ final FormatOptions formatOptions = BinaryDictUtils.VERSION2_OPTIONS;
+ final ArrayList<String> words = sWords;
+ final HashMap<String, List<String>> shortcuts = sShortcuts;
+ final String dictName = "testGetWordProperty";
final String dictVersion = Long.toString(System.currentTimeMillis());
- final File file = setUpDictionaryFile(dictName, dictVersion);
-
final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
- new FusionDictionary.DictionaryOptions(
- new HashMap<String, String>(), false, false));
- addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */);
+ BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions));
+ addUnigrams(words.size(), dict, words, shortcuts);
+ addBigrams(dict, words, sEmptyBigrams);
+ final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions,
+ getContext().getCacheDir());
+ file.delete();
timeWritingDictToFile(file, dict, formatOptions);
-
- final DictUpdater dictUpdater;
- if (formatOptions.mVersion == 3) {
- dictUpdater = new Ver3DictUpdater(file, DictDecoder.USE_WRITABLE_BYTEBUFFER);
- } else if (formatOptions.mVersion == 4) {
- dictUpdater = new Ver4DictUpdater(file, DictDecoder.USE_WRITABLE_BYTEBUFFER);
- } else {
- throw new RuntimeException("DictUpdater for version " + formatOptions.mVersion
- + " doesn't exist.");
- }
-
- try {
- MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD,
- dictUpdater.getTerminalPosition(sWords.get(0)));
- dictUpdater.deleteWord(sWords.get(0));
- assertEquals(FormatSpec.NOT_VALID_WORD,
- dictUpdater.getTerminalPosition(sWords.get(0)));
-
- MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD,
- dictUpdater.getTerminalPosition(sWords.get(5)));
- dictUpdater.deleteWord(sWords.get(5));
- assertEquals(FormatSpec.NOT_VALID_WORD,
- dictUpdater.getTerminalPosition(sWords.get(5)));
- } catch (IOException e) {
- } catch (UnsupportedFormatException e) {
+ final BinaryDictionary binaryDictionary = new BinaryDictionary(file.getAbsolutePath(),
+ 0 /* offset */, file.length(), true /* useFullEditDistance */,
+ Locale.ENGLISH, dictName, false /* isUpdatable */);
+ for (final String word : words) {
+ final WordProperty wordProperty = binaryDictionary.getWordProperty(word);
+ assertEquals(word, wordProperty.mWord);
+ assertEquals(UNIGRAM_FREQ, wordProperty.getProbability());
+ if (shortcuts.containsKey(word)) {
+ assertEquals(shortcuts.get(word).size(), wordProperty.mShortcutTargets.size());
+ final List<String> shortcutList = shortcuts.get(word);
+ assertTrue(wordProperty.mHasShortcuts);
+ for (final WeightedString shortcutTarget : wordProperty.mShortcutTargets) {
+ assertTrue(shortcutList.contains(shortcutTarget.mWord));
+ assertEquals(UNIGRAM_FREQ, shortcutTarget.getProbability());
+ shortcutList.remove(shortcutTarget.mWord);
+ }
+ assertTrue(shortcutList.isEmpty());
+ }
}
}
- public void testDeleteWord() {
- runTestDeleteWord(VERSION3_WITH_DYNAMIC_UPDATE);
- runTestDeleteWord(VERSION4_WITH_DYNAMIC_UPDATE);
+ public void testVer2DictIteration() {
+ final FormatOptions formatOptions = BinaryDictUtils.VERSION2_OPTIONS;
+ final ArrayList<String> words = sWords;
+ final HashMap<String, List<String>> shortcuts = sShortcuts;
+ final SparseArray<List<Integer>> bigrams = sEmptyBigrams;
+ final String dictName = "testGetWordProperty";
+ final String dictVersion = Long.toString(System.currentTimeMillis());
+ final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
+ BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions));
+ addUnigrams(words.size(), dict, words, shortcuts);
+ addBigrams(dict, words, bigrams);
+ final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions,
+ getContext().getCacheDir());
+ timeWritingDictToFile(file, dict, formatOptions);
+ Log.d(TAG, file.getAbsolutePath());
+ final BinaryDictionary binaryDictionary = new BinaryDictionary(file.getAbsolutePath(),
+ 0 /* offset */, file.length(), true /* useFullEditDistance */,
+ Locale.ENGLISH, dictName, false /* isUpdatable */);
+
+ final HashSet<String> wordSet = new HashSet<String>(words);
+ final HashSet<Pair<String, String>> bigramSet = new HashSet<Pair<String,String>>();
+
+ for (int i = 0; i < words.size(); i++) {
+ final List<Integer> bigramList = bigrams.get(i);
+ if (bigramList != null) {
+ for (final Integer word1Index : bigramList) {
+ final String word1 = words.get(word1Index);
+ bigramSet.add(new Pair<String, String>(words.get(i), word1));
+ }
+ }
+ }
+ int token = 0;
+ do {
+ final BinaryDictionary.GetNextWordPropertyResult result =
+ binaryDictionary.getNextWordProperty(token);
+ final WordProperty wordProperty = result.mWordProperty;
+ final String word0 = wordProperty.mWord;
+ assertEquals(UNIGRAM_FREQ, wordProperty.mProbabilityInfo.mProbability);
+ wordSet.remove(word0);
+ if (shortcuts.containsKey(word0)) {
+ assertEquals(shortcuts.get(word0).size(), wordProperty.mShortcutTargets.size());
+ final List<String> shortcutList = shortcuts.get(word0);
+ assertNotNull(wordProperty.mShortcutTargets);
+ for (final WeightedString shortcutTarget : wordProperty.mShortcutTargets) {
+ assertTrue(shortcutList.contains(shortcutTarget.mWord));
+ assertEquals(UNIGRAM_FREQ, shortcutTarget.getProbability());
+ shortcutList.remove(shortcutTarget.mWord);
+ }
+ assertTrue(shortcutList.isEmpty());
+ }
+ for (int j = 0; j < wordProperty.mBigrams.size(); j++) {
+ final String word1 = wordProperty.mBigrams.get(j).mWord;
+ final Pair<String, String> bigram = new Pair<String, String>(word0, word1);
+ assertTrue(bigramSet.contains(bigram));
+ bigramSet.remove(bigram);
+ }
+ token = result.mNextToken;
+ } while (token != 0);
+ assertTrue(wordSet.isEmpty());
+ assertTrue(bigramSet.isEmpty());
}
}
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
deleted file mode 100644
index afe5adb73..000000000
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright (C) 2012 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.latin.makedict;
-
-import android.test.AndroidTestCase;
-import android.test.MoreAsserts;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-
-import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer;
-import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
-import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray;
-import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
-import com.android.inputmethod.latin.utils.CollectionUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Random;
-
-@LargeTest
-public class BinaryDictIOUtilsTests extends AndroidTestCase {
- private static final String TAG = BinaryDictIOUtilsTests.class.getSimpleName();
- private static final FormatSpec.FormatOptions FORMAT_OPTIONS =
- new FormatSpec.FormatOptions(3, true);
-
- private static final ArrayList<String> sWords = CollectionUtils.newArrayList();
- public static final int DEFAULT_MAX_UNIGRAMS = 1500;
- private final int mMaxUnigrams;
-
- private static final String TEST_DICT_FILE_EXTENSION = ".testDict";
-
- private static final int VERSION3 = 3;
- private static final int VERSION4 = 4;
-
- private static final String[] CHARACTERS = {
- "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
- "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
- "\u00FC" /* ü */, "\u00E2" /* â */, "\u00F1" /* ñ */, // accented characters
- "\u4E9C" /* 亜 */, "\u4F0A" /* 伊 */, "\u5B87" /* 宇 */, // kanji
- "\uD841\uDE28" /* 𠘨 */, "\uD840\uDC0B" /* 𠀋 */, "\uD861\uDED7" /* 𨛗 */ // surrogate pair
- };
-
- public BinaryDictIOUtilsTests() {
- // 1500 is the default max unigrams
- this(System.currentTimeMillis(), DEFAULT_MAX_UNIGRAMS);
- }
-
- public BinaryDictIOUtilsTests(final long seed, final int maxUnigrams) {
- super();
- Log.d(TAG, "Seed for test is " + seed + ", maxUnigrams is " + maxUnigrams);
- mMaxUnigrams = maxUnigrams;
- final Random random = new Random(seed);
- sWords.clear();
- for (int i = 0; i < maxUnigrams; ++i) {
- sWords.add(generateWord(random.nextInt()));
- }
- }
-
- // Utilities for test
- private String generateWord(final int value) {
- final int lengthOfChars = CHARACTERS.length;
- StringBuilder builder = new StringBuilder("");
- long lvalue = Math.abs((long)value);
- while (lvalue > 0) {
- builder.append(CHARACTERS[(int)(lvalue % lengthOfChars)]);
- lvalue /= lengthOfChars;
- }
- if (builder.toString().equals("")) return "a";
- return builder.toString();
- }
-
- private static void printPtNode(final PtNodeInfo info) {
- Log.d(TAG, " PtNode at " + info.mOriginalAddress);
- Log.d(TAG, " flags = " + info.mFlags);
- Log.d(TAG, " parentAddress = " + info.mParentAddress);
- Log.d(TAG, " characters = " + new String(info.mCharacters, 0,
- info.mCharacters.length));
- if (info.mFrequency != -1) Log.d(TAG, " frequency = " + info.mFrequency);
- if (info.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS) {
- Log.d(TAG, " children address = no children address");
- } else {
- Log.d(TAG, " children address = " + info.mChildrenAddress);
- }
- if (info.mShortcutTargets != null) {
- for (final WeightedString ws : info.mShortcutTargets) {
- Log.d(TAG, " shortcuts = " + ws.mWord);
- }
- }
- if (info.mBigrams != null) {
- for (final PendingAttribute attr : info.mBigrams) {
- Log.d(TAG, " bigram = " + attr.mAddress);
- }
- }
- Log.d(TAG, " end address = " + info.mEndAddress);
- }
-
- private static void printNode(final Ver3DictDecoder dictDecoder,
- final FormatSpec.FormatOptions formatOptions) {
- final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
- Log.d(TAG, "Node at " + dictBuffer.position());
- final int count = BinaryDictDecoderUtils.readPtNodeCount(dictBuffer);
- Log.d(TAG, " ptNodeCount = " + count);
- for (int i = 0; i < count; ++i) {
- final PtNodeInfo currentInfo = dictDecoder.readPtNode(dictBuffer.position(),
- formatOptions);
- printPtNode(currentInfo);
- }
- if (formatOptions.mSupportsDynamicUpdate) {
- final int forwardLinkAddress = dictBuffer.readUnsignedInt24();
- Log.d(TAG, " forwardLinkAddress = " + forwardLinkAddress);
- }
- }
-
- @SuppressWarnings("unused")
- private static void printBinaryFile(final Ver3DictDecoder dictDecoder)
- throws IOException, UnsupportedFormatException {
- final FileHeader fileHeader = dictDecoder.readHeader();
- final DictBuffer dictBuffer = dictDecoder.getDictBuffer();
- while (dictBuffer.position() < dictBuffer.limit()) {
- printNode(dictDecoder, fileHeader.mFormatOptions);
- }
- }
-
- private int getWordPosition(final File file, final String word) {
- int position = FormatSpec.NOT_VALID_WORD;
-
- try {
- final Ver3DictDecoder dictDecoder = new Ver3DictDecoder(file,
- DictDecoder.USE_READONLY_BYTEBUFFER);
- position = dictDecoder.getTerminalPosition(word);
- } catch (IOException e) {
- } catch (UnsupportedFormatException e) {
- }
- return position;
- }
-
- /**
- * Find a word using the DictDecoder.
- *
- * @param dictDecoder the dict decoder
- * @param word the word searched
- * @return the found ptNodeInfo
- * @throws IOException
- * @throws UnsupportedFormatException
- */
- private static PtNodeInfo findWordByBinaryDictReader(final DictDecoder dictDecoder,
- final String word) throws IOException, UnsupportedFormatException {
- int position = dictDecoder.getTerminalPosition(word);
- if (position != FormatSpec.NOT_VALID_WORD) {
- dictDecoder.setPosition(0);
- final FileHeader header = dictDecoder.readHeader();
- dictDecoder.setPosition(position);
- return dictDecoder.readPtNode(position, header.mFormatOptions);
- }
- return null;
- }
-
- private PtNodeInfo findWordFromFile(final File file, final String word) {
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file);
- PtNodeInfo info = null;
- try {
- dictDecoder.openDictBuffer();
- info = findWordByBinaryDictReader(dictDecoder, word);
- } catch (IOException e) {
- } catch (UnsupportedFormatException e) {
- }
- return info;
- }
-
- // return amount of time to insert a word
- private long insertAndCheckWord(final File file, final String word, final int frequency,
- final boolean exist, final ArrayList<WeightedString> bigrams,
- final ArrayList<WeightedString> shortcuts, final int formatVersion) {
- long amountOfTime = -1;
- try {
- final DictUpdater dictUpdater;
- if (formatVersion == VERSION3) {
- dictUpdater = new Ver3DictUpdater(file, DictDecoder.USE_WRITABLE_BYTEBUFFER);
- } else {
- throw new RuntimeException("DictUpdater for version " + formatVersion + " doesn't"
- + " exist.");
- }
-
- if (!exist) {
- assertEquals(FormatSpec.NOT_VALID_WORD, getWordPosition(file, word));
- }
- final long now = System.nanoTime();
- dictUpdater.insertWord(word, frequency, bigrams, shortcuts, false, false);
- amountOfTime = System.nanoTime() - now;
- MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, getWordPosition(file, word));
- } catch (IOException e) {
- Log.e(TAG, "Raised an IOException while inserting a word", e);
- } catch (UnsupportedFormatException e) {
- Log.e(TAG, "Raised an UnsupportedFormatException error while inserting a word", e);
- }
- return amountOfTime;
- }
-
- private void deleteWord(final File file, final String word, final int formatVersion) {
- try {
- final DictUpdater dictUpdater;
- if (formatVersion == VERSION3) {
- dictUpdater = new Ver3DictUpdater(file, DictDecoder.USE_WRITABLE_BYTEBUFFER);
- } else {
- throw new RuntimeException("DictUpdater for version " + formatVersion + " doesn't"
- + " exist.");
- }
- dictUpdater.deleteWord(word);
- } catch (IOException e) {
- } catch (UnsupportedFormatException e) {
- }
- }
-
- private void checkReverseLookup(final File file, final String word, final int position) {
-
- try {
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file);
- final FileHeader fileHeader = dictDecoder.readHeader();
- assertEquals(word,
- BinaryDictDecoderUtils.getWordAtPosition(dictDecoder, fileHeader.mHeaderSize,
- position, fileHeader.mFormatOptions).mWord);
- } catch (IOException e) {
- Log.e(TAG, "Raised an IOException while looking up a word", e);
- } catch (UnsupportedFormatException e) {
- Log.e(TAG, "Raised an UnsupportedFormatException error while looking up a word", e);
- }
- }
-
- private void runTestInsertWord(final int formatVersion) {
- File file = null;
- try {
- file = File.createTempFile("testInsertWord", TEST_DICT_FILE_EXTENSION,
- getContext().getCacheDir());
- } catch (IOException e) {
- fail("IOException while creating temporary file: " + e);
- }
-
- // set an initial dictionary.
- final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
- new FusionDictionary.DictionaryOptions(new HashMap<String,String>(), false, false));
- dict.add("abcd", 10, null, false);
-
- try {
- final DictEncoder dictEncoder = new Ver3DictEncoder(file);
- dictEncoder.writeDictionary(dict, FORMAT_OPTIONS);
- } catch (IOException e) {
- fail("IOException while writing an initial dictionary : " + e);
- } catch (UnsupportedFormatException e) {
- fail("UnsupportedFormatException while writing an initial dictionary : " + e);
- }
-
- MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, getWordPosition(file, "abcd"));
- insertAndCheckWord(file, "abcde", 10, false, null, null, formatVersion);
-
- insertAndCheckWord(file, "abcdefghijklmn", 10, false, null, null, formatVersion);
- checkReverseLookup(file, "abcdefghijklmn", getWordPosition(file, "abcdefghijklmn"));
-
- insertAndCheckWord(file, "abcdabcd", 10, false, null, null, formatVersion);
- checkReverseLookup(file, "abcdabcd", getWordPosition(file, "abcdabcd"));
-
- // update the existing word.
- insertAndCheckWord(file, "abcdabcd", 15, true, null, null, formatVersion);
-
- // split 1
- insertAndCheckWord(file, "ab", 20, false, null, null, formatVersion);
-
- // split 2
- insertAndCheckWord(file, "ami", 30, false, null, null, formatVersion);
-
- deleteWord(file, "ami", formatVersion);
- assertEquals(FormatSpec.NOT_VALID_WORD, getWordPosition(file, "ami"));
-
- insertAndCheckWord(file, "abcdabfg", 30, false, null, null, formatVersion);
-
- deleteWord(file, "abcd", formatVersion);
- assertEquals(FormatSpec.NOT_VALID_WORD, getWordPosition(file, "abcd"));
- }
-
- public void testInsertWord() {
- runTestInsertWord(VERSION3);
- }
-
- private void runTestInsertWordWithBigrams(final int formatVersion) {
- File file = null;
- try {
- file = File.createTempFile("testInsertWordWithBigrams", TEST_DICT_FILE_EXTENSION,
- getContext().getCacheDir());
- } catch (IOException e) {
- fail("IOException while creating temporary file: " + e);
- }
-
- // set an initial dictionary.
- final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
- new FusionDictionary.DictionaryOptions(new HashMap<String,String>(), false, false));
- dict.add("abcd", 10, null, false);
- dict.add("efgh", 15, null, false);
-
- try {
- final DictEncoder dictEncoder = new Ver3DictEncoder(file);
- dictEncoder.writeDictionary(dict, FORMAT_OPTIONS);
- } catch (IOException e) {
- fail("IOException while writing an initial dictionary : " + e);
- } catch (UnsupportedFormatException e) {
- fail("UnsupportedFormatException while writing an initial dictionary : " + e);
- }
-
- final ArrayList<WeightedString> banana = new ArrayList<WeightedString>();
- banana.add(new WeightedString("banana", 10));
-
- insertAndCheckWord(file, "banana", 0, false, null, null, formatVersion);
- insertAndCheckWord(file, "recursive", 60, true, banana, null, formatVersion);
-
- final PtNodeInfo info = findWordFromFile(file, "recursive");
- int bananaPos = getWordPosition(file, "banana");
- assertNotNull(info.mBigrams);
- assertEquals(info.mBigrams.size(), 1);
- assertEquals(info.mBigrams.get(0).mAddress, bananaPos);
- }
-
- public void testInsertWordWithBigrams() {
- runTestInsertWordWithBigrams(VERSION3);
- }
-
- private void runTestRandomWords(final int formatVersion) {
- File file = null;
- try {
- file = File.createTempFile("testRandomWord", TEST_DICT_FILE_EXTENSION,
- getContext().getCacheDir());
- } catch (IOException e) {
- }
- assertNotNull(file);
-
- // set an initial dictionary.
- final FusionDictionary dict = new FusionDictionary(new PtNodeArray(),
- new FusionDictionary.DictionaryOptions(new HashMap<String, String>(), false,
- false));
- dict.add("initial", 10, null, false);
-
- try {
- final DictEncoder dictEncoder = new Ver3DictEncoder(file);
- dictEncoder.writeDictionary(dict, FORMAT_OPTIONS);
- } catch (IOException e) {
- assertTrue(false);
- } catch (UnsupportedFormatException e) {
- assertTrue(false);
- }
-
- long maxTimeToInsert = 0, sum = 0;
- long minTimeToInsert = 100000000; // 1000000000 is an upper bound for minTimeToInsert.
- int cnt = 0;
- for (final String word : sWords) {
- final long diff = insertAndCheckWord(file, word,
- cnt % FormatSpec.MAX_TERMINAL_FREQUENCY, false, null, null, formatVersion);
- maxTimeToInsert = Math.max(maxTimeToInsert, diff);
- minTimeToInsert = Math.min(minTimeToInsert, diff);
- sum += diff;
- cnt++;
- }
- cnt = 0;
- for (final String word : sWords) {
- MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, getWordPosition(file, word));
- }
-
- Log.d(TAG, "Test version " + formatVersion);
- Log.d(TAG, "max = " + ((double)maxTimeToInsert/1000000) + " ms.");
- Log.d(TAG, "min = " + ((double)minTimeToInsert/1000000) + " ms.");
- Log.d(TAG, "avg = " + ((double)sum/mMaxUnigrams/1000000) + " ms.");
- }
-
- public void testRandomWords() {
- runTestRandomWords(VERSION3);
- }
-}
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java
new file mode 100644
index 000000000..79f3e0dc9
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2013 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.latin.makedict;
+
+import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
+
+import java.io.File;
+import java.util.HashMap;
+
+public class BinaryDictUtils {
+ public static final int USE_BYTE_ARRAY = 1;
+ public static final int USE_BYTE_BUFFER = 2;
+
+ public static final String TEST_DICT_FILE_EXTENSION = ".testDict";
+
+ public static final FormatSpec.FormatOptions VERSION2_OPTIONS =
+ new FormatSpec.FormatOptions(FormatSpec.VERSION2);
+ public static final FormatSpec.FormatOptions VERSION4_OPTIONS_WITHOUT_TIMESTAMP =
+ new FormatSpec.FormatOptions(FormatSpec.VERSION4, false /* hasTimestamp */);
+ public static final FormatSpec.FormatOptions VERSION4_OPTIONS_WITH_TIMESTAMP =
+ new FormatSpec.FormatOptions(FormatSpec.VERSION4, true /* hasTimestamp */);
+
+ public static DictionaryOptions makeDictionaryOptions(final String id, final String version,
+ final FormatSpec.FormatOptions formatOptions) {
+ final DictionaryOptions options = new DictionaryOptions(new HashMap<String, String>());
+ options.mAttributes.put(DictionaryHeader.DICTIONARY_LOCALE_KEY, "en_US");
+ options.mAttributes.put(DictionaryHeader.DICTIONARY_ID_KEY, id);
+ options.mAttributes.put(DictionaryHeader.DICTIONARY_VERSION_KEY, version);
+ if (formatOptions.mHasTimestamp) {
+ options.mAttributes.put(DictionaryHeader.HAS_HISTORICAL_INFO_KEY,
+ DictionaryHeader.ATTRIBUTE_VALUE_TRUE);
+ options.mAttributes.put(DictionaryHeader.USES_FORGETTING_CURVE_KEY,
+ DictionaryHeader.ATTRIBUTE_VALUE_TRUE);
+ }
+ return options;
+ }
+
+ public static File getDictFile(final String name, final String version,
+ final FormatOptions formatOptions, final File directory) {
+ if (formatOptions.mVersion == FormatSpec.VERSION2) {
+ return new File(directory, name + "." + version + TEST_DICT_FILE_EXTENSION);
+ } else if (formatOptions.mVersion == FormatSpec.VERSION4) {
+ return new File(directory, name + "." + version);
+ } else {
+ throw new RuntimeException("the format option has a wrong version : "
+ + formatOptions.mVersion);
+ }
+ }
+
+ public static DictEncoder getDictEncoder(final File file, final FormatOptions formatOptions) {
+ if (formatOptions.mVersion == FormatSpec.VERSION4) {
+ if (!file.isDirectory()) {
+ file.mkdir();
+ }
+ return new Ver4DictEncoder(file);
+ } else if (formatOptions.mVersion == FormatSpec.VERSION2) {
+ return new Ver2DictEncoder(file);
+ } else {
+ throw new RuntimeException("The format option has a wrong version : "
+ + formatOptions.mVersion);
+ }
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/makedict/SparseTableTests.java b/tests/src/com/android/inputmethod/latin/makedict/SparseTableTests.java
deleted file mode 100644
index aeb8552bd..000000000
--- a/tests/src/com/android/inputmethod/latin/makedict/SparseTableTests.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2013 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.latin.makedict;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Random;
-
-/**
- * Unit tests for SparseTable.
- */
-@LargeTest
-public class SparseTableTests extends AndroidTestCase {
- private static final String TAG = SparseTableTests.class.getSimpleName();
-
- private final Random mRandom;
- private final ArrayList<Integer> mRandomIndex;
-
- private static final int DEFAULT_SIZE = 10000;
- private static final int BLOCK_SIZE = 8;
-
- public SparseTableTests() {
- this(System.currentTimeMillis(), DEFAULT_SIZE);
- }
-
- public SparseTableTests(final long seed, final int tableSize) {
- super();
- Log.d(TAG, "Seed for test is " + seed + ", size is " + tableSize);
- mRandom = new Random(seed);
- mRandomIndex = new ArrayList<Integer>(tableSize);
- for (int i = 0; i < tableSize; ++i) {
- mRandomIndex.add(SparseTable.NOT_EXIST);
- }
- }
-
- public void testSet() {
- final SparseTable table = new SparseTable(16, BLOCK_SIZE, 1);
- table.set(0, 3, 6);
- table.set(0, 8, 16);
- for (int i = 0; i < 16; ++i) {
- if (i == 3 || i == 8) {
- assertEquals(i * 2, table.get(0, i));
- } else {
- assertEquals(SparseTable.NOT_EXIST, table.get(0, i));
- }
- }
- }
-
- private void generateRandomIndex(final int size, final int prop) {
- for (int i = 0; i < size; ++i) {
- if (mRandom.nextInt(100) < prop) {
- mRandomIndex.set(i, mRandom.nextInt());
- } else {
- mRandomIndex.set(i, SparseTable.NOT_EXIST);
- }
- }
- }
-
- private void runTestRandomSet() {
- final SparseTable table = new SparseTable(DEFAULT_SIZE, BLOCK_SIZE, 1);
- int elementCount = 0;
- for (int i = 0; i < DEFAULT_SIZE; ++i) {
- if (mRandomIndex.get(i) != SparseTable.NOT_EXIST) {
- table.set(0, i, mRandomIndex.get(i));
- elementCount++;
- }
- }
-
- Log.d(TAG, "table size = " + table.getLookupTableSize() + " + "
- + table.getContentTableSize());
- Log.d(TAG, "the table has " + elementCount + " elements");
- for (int i = 0; i < DEFAULT_SIZE; ++i) {
- assertEquals(table.get(0, i), (int)mRandomIndex.get(i));
- }
-
- // flush and reload
- OutputStream lookupOutStream = null;
- OutputStream contentOutStream = null;
- try {
- final File lookupIndexFile = File.createTempFile("testRandomSet", ".small");
- final File contentFile = File.createTempFile("testRandomSet", ".big");
- lookupOutStream = new FileOutputStream(lookupIndexFile);
- contentOutStream = new FileOutputStream(contentFile);
- table.write(lookupOutStream, new OutputStream[] { contentOutStream });
- lookupOutStream.flush();
- contentOutStream.flush();
- final SparseTable newTable = SparseTable.readFromFiles(lookupIndexFile,
- new File[] { contentFile }, BLOCK_SIZE);
- for (int i = 0; i < DEFAULT_SIZE; ++i) {
- assertEquals(table.get(0, i), newTable.get(0, i));
- }
- } catch (IOException e) {
- Log.d(TAG, "IOException while flushing and realoding", e);
- } finally {
- if (lookupOutStream != null) {
- try {
- lookupOutStream.close();
- } catch (IOException e) {
- Log.d(TAG, "IOException while closing the stream", e);
- }
- }
- if (contentOutStream != null) {
- try {
- contentOutStream.close();
- } catch (IOException e) {
- Log.d(TAG, "IOException while closing contentStream.", e);
- }
- }
- }
- }
-
- public void testRandomSet() {
- for (int i = 0; i <= 100; i += 10) {
- generateRandomIndex(DEFAULT_SIZE, i);
- runTestRandomSet();
- }
- }
-
- public void testMultipleContents() {
- final int numOfContents = 5;
- generateRandomIndex(DEFAULT_SIZE, 20);
- final SparseTable table = new SparseTable(DEFAULT_SIZE, BLOCK_SIZE, numOfContents);
- for (int i = 0; i < mRandomIndex.size(); ++i) {
- if (mRandomIndex.get(i) != SparseTable.NOT_EXIST) {
- for (int j = 0; j < numOfContents; ++j) {
- table.set(j, i, mRandomIndex.get(i));
- }
- }
- }
-
- OutputStream lookupOutStream = null;
- OutputStream[] contentsOutStream = new OutputStream[numOfContents];
- try {
- final File lookupIndexFile = File.createTempFile("testMultipleContents", "small");
- lookupOutStream = new FileOutputStream(lookupIndexFile);
- final File[] contentFiles = new File[numOfContents];
- for (int i = 0; i < numOfContents; ++i) {
- contentFiles[i] = File.createTempFile("testMultipleContents", "big" + i);
- contentsOutStream[i] = new FileOutputStream(contentFiles[i]);
- }
- table.write(lookupOutStream, contentsOutStream);
- lookupOutStream.flush();
- for (int i = 0; i < numOfContents; ++i) {
- contentsOutStream[i].flush();
- }
- final SparseTable newTable = SparseTable.readFromFiles(lookupIndexFile, contentFiles,
- BLOCK_SIZE);
- for (int i = 0; i < numOfContents; ++i) {
- for (int j = 0; j < DEFAULT_SIZE; ++j) {
- assertEquals(table.get(i, j), newTable.get(i, j));
- }
- }
- } catch (IOException e) {
- Log.d(TAG, "IOException while flushing and reloading", e);
- } finally {
- if (lookupOutStream != null) {
- try {
- lookupOutStream.close();
- } catch (IOException e) {
- Log.d(TAG, "IOException while closing the stream", e);
- }
- }
- for (int i = 0; i < numOfContents; ++i) {
- if (contentsOutStream[i] != null) {
- try {
- contentsOutStream[i].close();
- } catch (IOException e) {
- Log.d(TAG, "IOException while closing the stream.", e);
- }
- }
- }
- }
- }
-}
diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver3DictDecoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java
index 9611599b9..a85753e6b 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/Ver3DictDecoderTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java
@@ -32,10 +32,10 @@ import java.io.FileOutputStream;
import java.io.IOException;
/**
- * Unit tests for Ver3DictDecoder
+ * Unit tests for Ver2DictDecoder
*/
-public class Ver3DictDecoderTests extends AndroidTestCase {
- private static final String TAG = Ver3DictDecoderTests.class.getSimpleName();
+public class Ver2DictDecoderTests extends AndroidTestCase {
+ private static final String TAG = Ver2DictDecoderTests.class.getSimpleName();
private final byte[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
@@ -68,7 +68,7 @@ public class Ver3DictDecoderTests extends AndroidTestCase {
}
assertNotNull(testFile);
- final Ver3DictDecoder dictDecoder = new Ver3DictDecoder(testFile, factory);
+ final Ver2DictDecoder dictDecoder = new Ver2DictDecoder(testFile, factory);
try {
dictDecoder.openDictBuffer();
} catch (Exception e) {
@@ -110,7 +110,7 @@ public class Ver3DictDecoderTests extends AndroidTestCase {
Log.e(TAG, "IOException while the creating temporary file", e);
}
- final Ver3DictDecoder dictDecoder = new Ver3DictDecoder(testFile, factory);
+ final Ver2DictDecoder dictDecoder = new Ver2DictDecoder(testFile, factory);
// the default return value of getBuffer() must be null.
assertNull("the default return value of getBuffer() is not null",
diff --git a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java
index 7c1decb71..b1239f0af 100644
--- a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java
+++ b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java
@@ -16,18 +16,19 @@
package com.android.inputmethod.latin.personalization;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
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.CollectionUtils;
+import com.android.inputmethod.latin.utils.FileUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -38,25 +39,57 @@ import java.util.concurrent.TimeUnit;
@LargeTest
public class UserHistoryDictionaryTests extends AndroidTestCase {
private static final String TAG = UserHistoryDictionaryTests.class.getSimpleName();
- private SharedPreferences mPrefs;
private static final String[] CHARACTERS = {
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
"n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"
};
- private static final int MIN_USER_HISTORY_DICTIONARY_FILE_SIZE = 1000;
- private static final int WAIT_TERMINATING_IN_MILLISECONDS = 100;
+ private int mCurrentTime = 0;
@Override
- public void setUp() {
- mPrefs = PreferenceManager.getDefaultSharedPreferences(getContext());
+ protected void setUp() throws Exception {
+ super.setUp();
+ resetCurrentTimeForTestMode();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ stopTestModeInNativeCode();
+ super.tearDown();
+ }
+
+ private void resetCurrentTimeForTestMode() {
+ mCurrentTime = 0;
+ setCurrentTimeForTestMode(mCurrentTime);
+ }
+
+ private void forcePassingShortTime() {
+ // 3 days.
+ final int timeToElapse = (int)TimeUnit.DAYS.toSeconds(3);
+ mCurrentTime += timeToElapse;
+ setCurrentTimeForTestMode(mCurrentTime);
+ }
+
+ private void forcePassingLongTime() {
+ // 60 days.
+ final int timeToElapse = (int)TimeUnit.DAYS.toSeconds(60);
+ mCurrentTime += timeToElapse;
+ setCurrentTimeForTestMode(mCurrentTime);
+ }
+
+ private static int setCurrentTimeForTestMode(final int currentTime) {
+ return BinaryDictionary.setCurrentTimeForTest(currentTime);
+ }
+
+ private static int stopTestModeInNativeCode() {
+ return BinaryDictionary.setCurrentTimeForTest(-1);
}
/**
* Generates a random word.
*/
- private String generateWord(final int value) {
+ private static String generateWord(final int value) {
final int lengthOfChars = CHARACTERS.length;
StringBuilder builder = new StringBuilder();
long lvalue = Math.abs((long)value);
@@ -67,7 +100,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
return builder.toString();
}
- private List<String> generateWords(final int number, final Random random) {
+ private static List<String> generateWords(final int number, final Random random) {
final Set<String> wordSet = CollectionUtils.newHashSet();
while (wordSet.size() < number) {
wordSet.add(generateWord(random.nextInt()));
@@ -75,10 +108,11 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
return new ArrayList<String>(wordSet);
}
- private void addToDict(final UserHistoryDictionary dict, final List<String> words) {
+ private static void addToDict(final UserHistoryDictionary dict, final List<String> words) {
String prevWord = null;
for (String word : words) {
- dict.addToDictionary(prevWord, word, true);
+ dict.addToDictionary(prevWord, word, true,
+ (int)TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()));
prevWord = word;
}
}
@@ -87,22 +121,18 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
* @param checkContents if true, checks whether written words are actually in the dictionary
* or not.
*/
- private void addAndWriteRandomWords(final String testFilenameSuffix, final int numberOfWords,
+ private void addAndWriteRandomWords(final Locale locale, final int numberOfWords,
final Random random, final boolean checkContents) {
final List<String> words = generateWords(numberOfWords, random);
- final UserHistoryDictionary dict =
- PersonalizationHelper.getUserHistoryDictionary(getContext(),
- testFilenameSuffix /* locale */, mPrefs);
+ final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary(
+ mContext, locale);
// Add random words to the user history dictionary.
addToDict(dict, words);
if (checkContents) {
- try {
- Thread.sleep(TimeUnit.MILLISECONDS.convert(5L, TimeUnit.SECONDS));
- } catch (InterruptedException e) {
- }
+ dict.waitAllTasksForTests();
for (int i = 0; i < numberOfWords; ++i) {
final String word = words.get(i);
- assertTrue(dict.isInDictionaryForTests(word));
+ assertTrue(dict.isInUnderlyingBinaryDictionaryForTests(word));
}
}
// write to file.
@@ -111,57 +141,48 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
/**
* Clear all entries in the user history dictionary.
- * @param testFilenameSuffix file name suffix used for testing.
+ * @param locale dummy locale for testing.
*/
- private void clearHistory(final String testFilenameSuffix) {
- final UserHistoryDictionary dict =
- PersonalizationHelper.getUserHistoryDictionary(getContext(),
- testFilenameSuffix /* locale */, mPrefs);
+ private void clearHistory(final Locale locale) {
+ final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary(
+ mContext, locale);
+ dict.waitAllTasksForTests();
dict.clearAndFlushDictionary();
dict.close();
+ dict.waitAllTasksForTests();
}
/**
* Shut down executer and wait until all operations of user history are done.
- * @param testFilenameSuffix file name suffix used for testing.
+ * @param locale dummy locale for testing.
*/
- private void waitForWriting(final String testFilenameSuffix) {
- try {
- final UserHistoryDictionary dict =
- PersonalizationHelper.getUserHistoryDictionary(getContext(),
- testFilenameSuffix, mPrefs);
- dict.shutdownExecutorForTests();
- while (!dict.isTerminatedForTests()) {
- Thread.sleep(WAIT_TERMINATING_IN_MILLISECONDS);
- }
- } catch (InterruptedException e) {
- Log.d(TAG, "InterruptedException: ", e);
- }
+ private void waitForWriting(final Locale locale) {
+ final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary(
+ mContext, locale);
+ dict.waitAllTasksForTests();
}
public void testRandomWords() {
Log.d(TAG, "This test can be used for profiling.");
Log.d(TAG, "Usage: please set UserHistoryDictionary.PROFILE_SAVE_RESTORE to true.");
- final String testFilenameSuffix = "testRandomWords" + System.currentTimeMillis();
- final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffix
- + ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
+ final Locale dummyLocale = new Locale("test_random_words" + System.currentTimeMillis());
+ final String dictName = ExpandableBinaryDictionary.getDictName(
+ UserHistoryDictionary.NAME, dummyLocale, null /* dictFile */);
+ final File dictFile = ExpandableBinaryDictionary.getDictFile(
+ mContext, dictName, null /* dictFile */);
final int numberOfWords = 1000;
final Random random = new Random(123456);
try {
- clearHistory(testFilenameSuffix);
- addAndWriteRandomWords(testFilenameSuffix, numberOfWords, random,
+ clearHistory(dummyLocale);
+ addAndWriteRandomWords(dummyLocale, numberOfWords, random,
true /* checksContents */);
} finally {
Log.d(TAG, "waiting for writing ...");
- waitForWriting(testFilenameSuffix);
- final File dictFile = new File(getContext().getFilesDir(), fileName);
- if (dictFile != null) {
- assertTrue(dictFile.exists());
- assertTrue(dictFile.length() >= MIN_USER_HISTORY_DICTIONARY_FILE_SIZE);
- dictFile.delete();
- }
+ waitForWriting(dummyLocale);
+ assertTrue("check exisiting of " + dictFile, dictFile.exists());
+ FileUtils.deleteRecursively(dictFile);
}
}
@@ -171,17 +192,18 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
final int numberOfWordsInsertedForEachLanguageSwitch = 100;
final File dictFiles[] = new File[numberOfLanguages];
- final String testFilenameSuffixes[] = new String[numberOfLanguages];
+ final Locale dummyLocales[] = new Locale[numberOfLanguages];
try {
final Random random = new Random(123456);
// Create filename suffixes for this test.
for (int i = 0; i < numberOfLanguages; i++) {
- testFilenameSuffixes[i] = "testSwitchingLanguages" + i;
- final String fileName = UserHistoryDictionary.NAME + "." +
- testFilenameSuffixes[i] + ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
- dictFiles[i] = new File(getContext().getFilesDir(), fileName);
- clearHistory(testFilenameSuffixes[i]);
+ dummyLocales[i] = new Locale("test_switching_languages" + i);
+ final String dictName = ExpandableBinaryDictionary.getDictName(
+ UserHistoryDictionary.NAME, dummyLocales[i], null /* dictFile */);
+ dictFiles[i] = ExpandableBinaryDictionary.getDictFile(
+ mContext, dictName, null /* dictFile */);
+ clearHistory(dummyLocales[i]);
}
final long start = System.currentTimeMillis();
@@ -189,7 +211,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
for (int i = 0; i < numberOfLanguageSwitching; i++) {
final int index = i % numberOfLanguages;
// Switch languages to testFilenameSuffixes[index].
- addAndWriteRandomWords(testFilenameSuffixes[index],
+ addAndWriteRandomWords(dummyLocales[index],
numberOfWordsInsertedForEachLanguageSwitch, random,
false /* checksContents */);
}
@@ -200,40 +222,61 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
} finally {
Log.d(TAG, "waiting for writing ...");
for (int i = 0; i < numberOfLanguages; i++) {
- waitForWriting(testFilenameSuffixes[i]);
+ waitForWriting(dummyLocales[i]);
}
- for (final File file : dictFiles) {
- if (file != null) {
- assertTrue(file.exists());
- assertTrue(file.length() >= MIN_USER_HISTORY_DICTIONARY_FILE_SIZE);
- file.delete();
- }
+ for (final File dictFile : dictFiles) {
+ assertTrue("check exisiting of " + dictFile, dictFile.exists());
+ FileUtils.deleteRecursively(dictFile);
}
}
}
public void testAddManyWords() {
- final String testFilenameSuffix = "testRandomWords" + System.currentTimeMillis();
- final int numberOfWords =
- ExpandableBinaryDictionary.ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE ?
- 10000 : 1000;
+ final Locale dummyLocale = new Locale("test_random_words" + System.currentTimeMillis());
+ final String dictName = ExpandableBinaryDictionary.getDictName(
+ UserHistoryDictionary.NAME, dummyLocale, null /* dictFile */);
+ final File dictFile = ExpandableBinaryDictionary.getDictFile(
+ mContext, dictName, null /* dictFile */);
+ final int numberOfWords = 10000;
final Random random = new Random(123456);
- clearHistory(testFilenameSuffix);
+ clearHistory(dummyLocale);
try {
- addAndWriteRandomWords(testFilenameSuffix, numberOfWords, random,
- true /* checksContents */);
+ addAndWriteRandomWords(dummyLocale, numberOfWords, random, true /* checksContents */);
} finally {
Log.d(TAG, "waiting for writing ...");
- waitForWriting(testFilenameSuffix);
- final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffix
- + ExpandableBinaryDictionary.DICT_FILE_EXTENSION;
- final File dictFile = new File(getContext().getFilesDir(), fileName);
- if (dictFile != null) {
- assertTrue(dictFile.exists());
- assertTrue(dictFile.length() >= MIN_USER_HISTORY_DICTIONARY_FILE_SIZE);
- dictFile.delete();
- }
+ waitForWriting(dummyLocale);
+ assertTrue("check exisiting of " + dictFile, dictFile.exists());
+ FileUtils.deleteRecursively(dictFile);
}
}
+ public void testDecaying() {
+ final Locale dummyLocale = new Locale("test_decaying" + System.currentTimeMillis());
+ final int numberOfWords = 5000;
+ final Random random = new Random(123456);
+ resetCurrentTimeForTestMode();
+ clearHistory(dummyLocale);
+ final List<String> words = generateWords(numberOfWords, random);
+ final UserHistoryDictionary dict =
+ PersonalizationHelper.getUserHistoryDictionary(getContext(), dummyLocale);
+ dict.waitAllTasksForTests();
+ String prevWord = null;
+ for (final String word : words) {
+ dict.addToDictionary(prevWord, word, true, mCurrentTime);
+ prevWord = word;
+ assertTrue(dict.isInUnderlyingBinaryDictionaryForTests(word));
+ }
+ forcePassingShortTime();
+ dict.decayIfNeeded();
+ dict.waitAllTasksForTests();
+ for (final String word : words) {
+ assertTrue(dict.isInUnderlyingBinaryDictionaryForTests(word));
+ }
+ forcePassingLongTime();
+ dict.decayIfNeeded();
+ dict.waitAllTasksForTests();
+ for (final String word : words) {
+ assertFalse(dict.isInUnderlyingBinaryDictionaryForTests(word));
+ }
+ }
}
diff --git a/tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java b/tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java
new file mode 100644
index 000000000..2cc22fae4
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java
@@ -0,0 +1,477 @@
+/*
+ * 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.latin.settings;
+
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.SuggestedWords;
+import com.android.inputmethod.latin.utils.RunInLocale;
+
+import junit.framework.AssertionFailedError;
+
+import java.util.Locale;
+
+@SmallTest
+public class SpacingAndPunctuationsTests extends AndroidTestCase {
+ private static final int ARMENIAN_FULL_STOP = '\u0589';
+ private static final int ARMENIAN_COMMA = '\u055D';
+
+ private int mScreenMetrics;
+
+ private boolean isPhone() {
+ return mScreenMetrics == Constants.SCREEN_METRICS_SMALL_PHONE
+ || mScreenMetrics == Constants.SCREEN_METRICS_LARGE_PHONE;
+ }
+
+ private boolean isTablet() {
+ return mScreenMetrics == Constants.SCREEN_METRICS_SMALL_TABLET
+ || mScreenMetrics == Constants.SCREEN_METRICS_LARGE_TABLET;
+ }
+
+ private SpacingAndPunctuations ENGLISH;
+ private SpacingAndPunctuations FRENCH;
+ private SpacingAndPunctuations GERMAN;
+ private SpacingAndPunctuations ARMENIAN;
+ private SpacingAndPunctuations THAI;
+ private SpacingAndPunctuations KHMER;
+ private SpacingAndPunctuations LAO;
+ private SpacingAndPunctuations ARABIC;
+ private SpacingAndPunctuations PERSIAN;
+ private SpacingAndPunctuations HEBREW;
+
+ private SpacingAndPunctuations UNITED_STATES;
+ private SpacingAndPunctuations UNITED_KINGDOM;
+ private SpacingAndPunctuations CANADA_FRENCH;
+ private SpacingAndPunctuations SWISS_GERMAN;
+ private SpacingAndPunctuations INDIA_ENGLISH;
+ private SpacingAndPunctuations ARMENIA_ARMENIAN;
+ private SpacingAndPunctuations CAMBODIA_KHMER;
+ private SpacingAndPunctuations LAOS_LAO;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mScreenMetrics = mContext.getResources().getInteger(R.integer.config_screen_metrics);
+
+ // Language only
+ ENGLISH = getSpacingAndPunctuations(Locale.ENGLISH);
+ FRENCH = getSpacingAndPunctuations(Locale.FRENCH);
+ GERMAN = getSpacingAndPunctuations(Locale.GERMAN);
+ THAI = getSpacingAndPunctuations(new Locale("th"));
+ ARMENIAN = getSpacingAndPunctuations(new Locale("hy"));
+ KHMER = getSpacingAndPunctuations(new Locale("km"));
+ LAO = getSpacingAndPunctuations(new Locale("lo"));
+ ARABIC = getSpacingAndPunctuations(new Locale("ar"));
+ PERSIAN = getSpacingAndPunctuations(new Locale("fa"));
+ HEBREW = getSpacingAndPunctuations(new Locale("iw"));
+
+ // Language and Country
+ UNITED_STATES = getSpacingAndPunctuations(Locale.US);
+ UNITED_KINGDOM = getSpacingAndPunctuations(Locale.UK);
+ CANADA_FRENCH = getSpacingAndPunctuations(Locale.CANADA_FRENCH);
+ SWISS_GERMAN = getSpacingAndPunctuations(new Locale("de", "CH"));
+ INDIA_ENGLISH = getSpacingAndPunctuations(new Locale("en", "IN"));
+ ARMENIA_ARMENIAN = getSpacingAndPunctuations(new Locale("hy", "AM"));
+ CAMBODIA_KHMER = getSpacingAndPunctuations(new Locale("km", "KH"));
+ LAOS_LAO = getSpacingAndPunctuations(new Locale("lo", "LA"));
+ }
+
+ private SpacingAndPunctuations getSpacingAndPunctuations(final Locale locale) {
+ final RunInLocale<SpacingAndPunctuations> job = new RunInLocale<SpacingAndPunctuations>() {
+ @Override
+ protected SpacingAndPunctuations job(Resources res) {
+ return new SpacingAndPunctuations(res);
+ }
+ };
+ return job.runInLocale(getContext().getResources(), locale);
+ }
+
+ private static void testingStandardWordSeparator(final SpacingAndPunctuations sp) {
+ assertTrue("Tab", sp.isWordSeparator('\t'));
+ assertTrue("Newline", sp.isWordSeparator('\n'));
+ assertTrue("Space", sp.isWordSeparator(' '));
+ assertTrue("Exclamation", sp.isWordSeparator('!'));
+ assertTrue("Quotation", sp.isWordSeparator('"'));
+ assertFalse("Number", sp.isWordSeparator('#'));
+ assertFalse("Dollar", sp.isWordSeparator('$'));
+ assertFalse("Percent", sp.isWordSeparator('%'));
+ assertTrue("Ampersand", sp.isWordSeparator('&'));
+ assertFalse("Apostrophe", sp.isWordSeparator('\''));
+ assertTrue("L Paren", sp.isWordSeparator('('));
+ assertTrue("R Paren", sp.isWordSeparator(')'));
+ assertTrue("Asterisk", sp.isWordSeparator('*'));
+ assertTrue("Plus", sp.isWordSeparator('+'));
+ assertTrue("Comma", sp.isWordSeparator(','));
+ assertFalse("Minus", sp.isWordSeparator('-'));
+ assertTrue("Period", sp.isWordSeparator('.'));
+ assertTrue("Slash", sp.isWordSeparator('/'));
+ assertTrue("Colon", sp.isWordSeparator(':'));
+ assertTrue("Semicolon", sp.isWordSeparator(';'));
+ assertTrue("L Angle", sp.isWordSeparator('<'));
+ assertTrue("Equal", sp.isWordSeparator('='));
+ assertTrue("R Angle", sp.isWordSeparator('>'));
+ assertTrue("Question", sp.isWordSeparator('?'));
+ assertFalse("Atmark", sp.isWordSeparator('@'));
+ assertTrue("L S Bracket", sp.isWordSeparator('['));
+ assertFalse("B Slash", sp.isWordSeparator('\\'));
+ assertTrue("R S Bracket", sp.isWordSeparator(']'));
+ assertFalse("Circumflex", sp.isWordSeparator('^'));
+ assertTrue("Underscore", sp.isWordSeparator('_'));
+ assertFalse("Grave", sp.isWordSeparator('`'));
+ assertTrue("L C Brace", sp.isWordSeparator('{'));
+ assertTrue("V Line", sp.isWordSeparator('|'));
+ assertTrue("R C Brace", sp.isWordSeparator('}'));
+ assertFalse("Tilde", sp.isWordSeparator('~'));
+ }
+
+ public void testWordSeparator() {
+ testingStandardWordSeparator(ENGLISH);
+ testingStandardWordSeparator(FRENCH);
+ testingStandardWordSeparator(CANADA_FRENCH);
+ testingStandardWordSeparator(ARMENIA_ARMENIAN);
+ assertTrue(ARMENIA_ARMENIAN.isWordSeparator(ARMENIAN_FULL_STOP));
+ assertTrue(ARMENIA_ARMENIAN.isWordSeparator(ARMENIAN_COMMA));
+ // TODO: We should fix these.
+ testingStandardWordSeparator(ARMENIAN);
+ assertFalse(ARMENIAN.isWordSeparator(ARMENIAN_FULL_STOP));
+ assertFalse(ARMENIAN.isWordSeparator(ARMENIAN_COMMA));
+ }
+
+ private static void testingStandardWordConnector(final SpacingAndPunctuations sp) {
+ assertFalse("Tab", sp.isWordConnector('\t'));
+ assertFalse("Newline", sp.isWordConnector('\n'));
+ assertFalse("Space", sp.isWordConnector(' '));
+ assertFalse("Exclamation", sp.isWordConnector('!'));
+ assertFalse("Quotation", sp.isWordConnector('"'));
+ assertFalse("Number", sp.isWordConnector('#'));
+ assertFalse("Dollar", sp.isWordConnector('$'));
+ assertFalse("Percent", sp.isWordConnector('%'));
+ assertFalse("Ampersand", sp.isWordConnector('&'));
+ assertTrue("Apostrophe", sp.isWordConnector('\''));
+ assertFalse("L Paren", sp.isWordConnector('('));
+ assertFalse("R Paren", sp.isWordConnector(')'));
+ assertFalse("Asterisk", sp.isWordConnector('*'));
+ assertFalse("Plus", sp.isWordConnector('+'));
+ assertFalse("Comma", sp.isWordConnector(','));
+ assertTrue("Minus", sp.isWordConnector('-'));
+ assertFalse("Period", sp.isWordConnector('.'));
+ assertFalse("Slash", sp.isWordConnector('/'));
+ assertFalse("Colon", sp.isWordConnector(':'));
+ assertFalse("Semicolon", sp.isWordConnector(';'));
+ assertFalse("L Angle", sp.isWordConnector('<'));
+ assertFalse("Equal", sp.isWordConnector('='));
+ assertFalse("R Angle", sp.isWordConnector('>'));
+ assertFalse("Question", sp.isWordConnector('?'));
+ assertFalse("Atmark", sp.isWordConnector('@'));
+ assertFalse("L S Bracket", sp.isWordConnector('['));
+ assertFalse("B Slash", sp.isWordConnector('\\'));
+ assertFalse("R S Bracket", sp.isWordConnector(']'));
+ assertFalse("Circumflex", sp.isWordConnector('^'));
+ assertFalse("Underscore", sp.isWordConnector('_'));
+ assertFalse("Grave", sp.isWordConnector('`'));
+ assertFalse("L C Brace", sp.isWordConnector('{'));
+ assertFalse("V Line", sp.isWordConnector('|'));
+ assertFalse("R C Brace", sp.isWordConnector('}'));
+ assertFalse("Tilde", sp.isWordConnector('~'));
+
+ }
+
+ public void testWordConnector() {
+ testingStandardWordConnector(ENGLISH);
+ testingStandardWordConnector(FRENCH);
+ testingStandardWordConnector(CANADA_FRENCH);
+ testingStandardWordConnector(ARMENIA_ARMENIAN);
+ }
+
+ private static void testingCommonPrecededBySpace(final SpacingAndPunctuations sp) {
+ assertFalse("Tab", sp.isUsuallyPrecededBySpace('\t'));
+ assertFalse("Newline", sp.isUsuallyPrecededBySpace('\n'));
+ assertFalse("Space", sp.isUsuallyPrecededBySpace(' '));
+ //assertFalse("Exclamation", sp.isUsuallyPrecededBySpace('!'));
+ assertFalse("Quotation", sp.isUsuallyPrecededBySpace('"'));
+ assertFalse("Number", sp.isUsuallyPrecededBySpace('#'));
+ assertFalse("Dollar", sp.isUsuallyPrecededBySpace('$'));
+ assertFalse("Percent", sp.isUsuallyPrecededBySpace('%'));
+ assertTrue("Ampersand", sp.isUsuallyPrecededBySpace('&'));
+ assertFalse("Apostrophe", sp.isUsuallyPrecededBySpace('\''));
+ assertTrue("L Paren", sp.isUsuallyPrecededBySpace('('));
+ assertFalse("R Paren", sp.isUsuallyPrecededBySpace(')'));
+ assertFalse("Asterisk", sp.isUsuallyPrecededBySpace('*'));
+ assertFalse("Plus", sp.isUsuallyPrecededBySpace('+'));
+ assertFalse("Comma", sp.isUsuallyPrecededBySpace(','));
+ assertFalse("Minus", sp.isUsuallyPrecededBySpace('-'));
+ assertFalse("Period", sp.isUsuallyPrecededBySpace('.'));
+ assertFalse("Slash", sp.isUsuallyPrecededBySpace('/'));
+ //assertFalse("Colon", sp.isUsuallyPrecededBySpace(':'));
+ //assertFalse("Semicolon", sp.isUsuallyPrecededBySpace(';'));
+ assertFalse("L Angle", sp.isUsuallyPrecededBySpace('<'));
+ assertFalse("Equal", sp.isUsuallyPrecededBySpace('='));
+ assertFalse("R Angle", sp.isUsuallyPrecededBySpace('>'));
+ //assertFalse("Question", sp.isUsuallyPrecededBySpace('?'));
+ assertFalse("Atmark", sp.isUsuallyPrecededBySpace('@'));
+ assertTrue("L S Bracket", sp.isUsuallyPrecededBySpace('['));
+ assertFalse("B Slash", sp.isUsuallyPrecededBySpace('\\'));
+ assertFalse("R S Bracket", sp.isUsuallyPrecededBySpace(']'));
+ assertFalse("Circumflex", sp.isUsuallyPrecededBySpace('^'));
+ assertFalse("Underscore", sp.isUsuallyPrecededBySpace('_'));
+ assertFalse("Grave", sp.isUsuallyPrecededBySpace('`'));
+ assertTrue("L C Brace", sp.isUsuallyPrecededBySpace('{'));
+ assertFalse("V Line", sp.isUsuallyPrecededBySpace('|'));
+ assertFalse("R C Brace", sp.isUsuallyPrecededBySpace('}'));
+ assertFalse("Tilde", sp.isUsuallyPrecededBySpace('~'));
+ }
+
+ private static void testingStandardPrecededBySpace(final SpacingAndPunctuations sp) {
+ testingCommonPrecededBySpace(sp);
+ assertFalse("Exclamation", sp.isUsuallyPrecededBySpace('!'));
+ assertFalse("Colon", sp.isUsuallyPrecededBySpace(':'));
+ assertFalse("Semicolon", sp.isUsuallyPrecededBySpace(';'));
+ assertFalse("Question", sp.isUsuallyPrecededBySpace('?'));
+ }
+
+ public void testIsUsuallyPrecededBySpace() {
+ testingStandardPrecededBySpace(ENGLISH);
+ testingCommonPrecededBySpace(FRENCH);
+ assertTrue("Exclamation", FRENCH.isUsuallyPrecededBySpace('!'));
+ assertTrue("Colon", FRENCH.isUsuallyPrecededBySpace(':'));
+ assertTrue("Semicolon", FRENCH.isUsuallyPrecededBySpace(';'));
+ assertTrue("Question", FRENCH.isUsuallyPrecededBySpace('?'));
+ testingCommonPrecededBySpace(CANADA_FRENCH);
+ assertFalse("Exclamation", CANADA_FRENCH.isUsuallyPrecededBySpace('!'));
+ assertTrue("Colon", CANADA_FRENCH.isUsuallyPrecededBySpace(':'));
+ assertFalse("Semicolon", CANADA_FRENCH.isUsuallyPrecededBySpace(';'));
+ assertFalse("Question", CANADA_FRENCH.isUsuallyPrecededBySpace('?'));
+ testingStandardPrecededBySpace(ARMENIA_ARMENIAN);
+ }
+
+ private static void testingStandardFollowedBySpace(final SpacingAndPunctuations sp) {
+ assertFalse("Tab", sp.isUsuallyFollowedBySpace('\t'));
+ assertFalse("Newline", sp.isUsuallyFollowedBySpace('\n'));
+ assertFalse("Space", sp.isUsuallyFollowedBySpace(' '));
+ assertTrue("Exclamation", sp.isUsuallyFollowedBySpace('!'));
+ assertFalse("Quotation", sp.isUsuallyFollowedBySpace('"'));
+ assertFalse("Number", sp.isUsuallyFollowedBySpace('#'));
+ assertFalse("Dollar", sp.isUsuallyFollowedBySpace('$'));
+ assertFalse("Percent", sp.isUsuallyFollowedBySpace('%'));
+ assertTrue("Ampersand", sp.isUsuallyFollowedBySpace('&'));
+ assertFalse("Apostrophe", sp.isUsuallyFollowedBySpace('\''));
+ assertFalse("L Paren", sp.isUsuallyFollowedBySpace('('));
+ assertTrue("R Paren", sp.isUsuallyFollowedBySpace(')'));
+ assertFalse("Asterisk", sp.isUsuallyFollowedBySpace('*'));
+ assertFalse("Plus", sp.isUsuallyFollowedBySpace('+'));
+ assertTrue("Comma", sp.isUsuallyFollowedBySpace(','));
+ assertFalse("Minus", sp.isUsuallyFollowedBySpace('-'));
+ assertTrue("Period", sp.isUsuallyFollowedBySpace('.'));
+ assertFalse("Slash", sp.isUsuallyFollowedBySpace('/'));
+ assertTrue("Colon", sp.isUsuallyFollowedBySpace(':'));
+ assertTrue("Semicolon", sp.isUsuallyFollowedBySpace(';'));
+ assertFalse("L Angle", sp.isUsuallyFollowedBySpace('<'));
+ assertFalse("Equal", sp.isUsuallyFollowedBySpace('='));
+ assertFalse("R Angle", sp.isUsuallyFollowedBySpace('>'));
+ assertTrue("Question", sp.isUsuallyFollowedBySpace('?'));
+ assertFalse("Atmark", sp.isUsuallyFollowedBySpace('@'));
+ assertFalse("L S Bracket", sp.isUsuallyFollowedBySpace('['));
+ assertFalse("B Slash", sp.isUsuallyFollowedBySpace('\\'));
+ assertTrue("R S Bracket", sp.isUsuallyFollowedBySpace(']'));
+ assertFalse("Circumflex", sp.isUsuallyFollowedBySpace('^'));
+ assertFalse("Underscore", sp.isUsuallyFollowedBySpace('_'));
+ assertFalse("Grave", sp.isUsuallyFollowedBySpace('`'));
+ assertFalse("L C Brace", sp.isUsuallyFollowedBySpace('{'));
+ assertFalse("V Line", sp.isUsuallyFollowedBySpace('|'));
+ assertTrue("R C Brace", sp.isUsuallyFollowedBySpace('}'));
+ assertFalse("Tilde", sp.isUsuallyFollowedBySpace('~'));
+ }
+
+ public void testIsUsuallyFollowedBySpace() {
+ testingStandardFollowedBySpace(ENGLISH);
+ testingStandardFollowedBySpace(FRENCH);
+ testingStandardFollowedBySpace(CANADA_FRENCH);
+ testingStandardFollowedBySpace(ARMENIA_ARMENIAN);
+ assertTrue(ARMENIA_ARMENIAN.isUsuallyFollowedBySpace(ARMENIAN_FULL_STOP));
+ assertTrue(ARMENIA_ARMENIAN.isUsuallyFollowedBySpace(ARMENIAN_COMMA));
+ }
+
+ private static void testingStandardSentenceSeparator(final SpacingAndPunctuations sp) {
+ assertFalse("Tab", sp.isUsuallyFollowedBySpace('\t'));
+ assertFalse("Newline", sp.isUsuallyFollowedBySpace('\n'));
+ assertFalse("Space", sp.isUsuallyFollowedBySpace(' '));
+ assertFalse("Exclamation", sp.isUsuallyFollowedBySpace('!'));
+ assertFalse("Quotation", sp.isUsuallyFollowedBySpace('"'));
+ assertFalse("Number", sp.isUsuallyFollowedBySpace('#'));
+ assertFalse("Dollar", sp.isUsuallyFollowedBySpace('$'));
+ assertFalse("Percent", sp.isUsuallyFollowedBySpace('%'));
+ assertFalse("Ampersand", sp.isUsuallyFollowedBySpace('&'));
+ assertFalse("Apostrophe", sp.isUsuallyFollowedBySpace('\''));
+ assertFalse("L Paren", sp.isUsuallyFollowedBySpace('('));
+ assertFalse("R Paren", sp.isUsuallyFollowedBySpace(')'));
+ assertFalse("Asterisk", sp.isUsuallyFollowedBySpace('*'));
+ assertFalse("Plus", sp.isUsuallyFollowedBySpace('+'));
+ assertFalse("Comma", sp.isUsuallyFollowedBySpace(','));
+ assertFalse("Minus", sp.isUsuallyFollowedBySpace('-'));
+ assertTrue("Period", sp.isUsuallyFollowedBySpace('.'));
+ assertFalse("Slash", sp.isUsuallyFollowedBySpace('/'));
+ assertFalse("Colon", sp.isUsuallyFollowedBySpace(':'));
+ assertFalse("Semicolon", sp.isUsuallyFollowedBySpace(';'));
+ assertFalse("L Angle", sp.isUsuallyFollowedBySpace('<'));
+ assertFalse("Equal", sp.isUsuallyFollowedBySpace('='));
+ assertFalse("R Angle", sp.isUsuallyFollowedBySpace('>'));
+ assertFalse("Question", sp.isUsuallyFollowedBySpace('?'));
+ assertFalse("Atmark", sp.isUsuallyFollowedBySpace('@'));
+ assertFalse("L S Bracket", sp.isUsuallyFollowedBySpace('['));
+ assertFalse("B Slash", sp.isUsuallyFollowedBySpace('\\'));
+ assertFalse("R S Bracket", sp.isUsuallyFollowedBySpace(']'));
+ assertFalse("Circumflex", sp.isUsuallyFollowedBySpace('^'));
+ assertFalse("Underscore", sp.isUsuallyFollowedBySpace('_'));
+ assertFalse("Grave", sp.isUsuallyFollowedBySpace('`'));
+ assertFalse("L C Brace", sp.isUsuallyFollowedBySpace('{'));
+ assertFalse("V Line", sp.isUsuallyFollowedBySpace('|'));
+ assertFalse("R C Brace", sp.isUsuallyFollowedBySpace('}'));
+ assertFalse("Tilde", sp.isUsuallyFollowedBySpace('~'));
+ }
+
+ public void isSentenceSeparator() {
+ testingStandardSentenceSeparator(ENGLISH);
+ try {
+ testingStandardSentenceSeparator(ARMENIA_ARMENIAN);
+ fail("Armenian Sentence Separator");
+ } catch (final AssertionFailedError e) {
+ assertEquals("Period", e.getMessage());
+ }
+ assertTrue(ARMENIA_ARMENIAN.isSentenceSeparator(ARMENIAN_FULL_STOP));
+ assertFalse(ARMENIA_ARMENIAN.isSentenceSeparator(ARMENIAN_COMMA));
+ }
+
+ public void testLanguageHasSpace() {
+ assertTrue(ENGLISH.mCurrentLanguageHasSpaces);
+ assertTrue(FRENCH.mCurrentLanguageHasSpaces);
+ assertTrue(GERMAN.mCurrentLanguageHasSpaces);
+ assertFalse(THAI.mCurrentLanguageHasSpaces);
+ assertFalse(CAMBODIA_KHMER.mCurrentLanguageHasSpaces);
+ assertFalse(LAOS_LAO.mCurrentLanguageHasSpaces);
+ // TODO: We should fix these.
+ assertTrue(KHMER.mCurrentLanguageHasSpaces);
+ assertTrue(LAO.mCurrentLanguageHasSpaces);
+ }
+
+ public void testUsesAmericanTypography() {
+ assertTrue(ENGLISH.mUsesAmericanTypography);
+ assertTrue(UNITED_STATES.mUsesAmericanTypography);
+ assertTrue(UNITED_KINGDOM.mUsesAmericanTypography);
+ assertTrue(INDIA_ENGLISH.mUsesAmericanTypography);
+ assertFalse(FRENCH.mUsesAmericanTypography);
+ assertFalse(GERMAN.mUsesAmericanTypography);
+ assertFalse(SWISS_GERMAN.mUsesAmericanTypography);
+ }
+
+ public void testUsesGermanRules() {
+ assertFalse(ENGLISH.mUsesGermanRules);
+ assertFalse(FRENCH.mUsesGermanRules);
+ assertTrue(GERMAN.mUsesGermanRules);
+ assertTrue(SWISS_GERMAN.mUsesGermanRules);
+ }
+
+ // Punctuations for phone.
+ private static final String[] PUNCTUATION_LABELS_PHONE = {
+ "!", "?", ",", ":", ";", "\"", "(", ")", "'", "-", "/", "@", "_"
+ };
+ private static final String[] PUNCTUATION_WORDS_PHONE_LTR = PUNCTUATION_LABELS_PHONE;
+ private static final String[] PUNCTUATION_WORDS_PHONE_HEBREW = {
+ "!", "?", ",", ":", ";", "\"", ")", "(", "'", "-", "/", "@", "_"
+ };
+ // U+061F: "؟" ARABIC QUESTION MARK
+ // U+060C: "،" ARABIC COMMA
+ // U+061B: "؛" ARABIC SEMICOLON
+ private static final String[] PUNCTUATION_LABELS_PHONE_ARABIC_PERSIAN = {
+ "!", "\u061F", "\u060C", ":", "\u061B", "\"", "(", ")", "'", "-", "/", "@", "_"
+ };
+ private static final String[] PUNCTUATION_WORDS_PHONE_ARABIC_PERSIAN = {
+ "!", "\u061F", "\u060C", ":", "\u061B", "\"", ")", "(", "'", "-", "/", "@", "_"
+ };
+
+ // Punctuations for tablet.
+ private static final String[] PUNCTUATION_LABELS_TABLET = {
+ ":", ";", "\"", "(", ")", "'", "-", "/", "@", "_"
+ };
+ private static final String[] PUNCTUATION_WORDS_TABLET_LTR = PUNCTUATION_LABELS_TABLET;
+ private static final String[] PUNCTUATION_WORDS_TABLET_HEBREW = {
+ ":", ";", "\"", ")", "(", "'", "-", "/", "@", "_"
+ };
+ private static final String[] PUNCTUATION_LABELS_TABLET_ARABIC_PERSIAN = {
+ "!", "\u061F", ":", "\u061B", "\"", "'", "(", ")", "-", "/", "@", "_"
+ };
+ private static final String[] PUNCTUATION_WORDS_TABLET_ARABIC_PERSIAN = {
+ "!", "\u061F", ":", "\u061B", "\"", "'", ")", "(", "-", "/", "@", "_"
+ };
+
+ private static void testingStandardPunctuationSuggestions(final SpacingAndPunctuations sp,
+ final String[] punctuationLabels, final String[] punctuationWords) {
+ final SuggestedWords suggestedWords = sp.mSuggestPuncList;
+ assertFalse("typedWordValid", suggestedWords.mTypedWordValid);
+ assertFalse("willAutoCorrect", suggestedWords.mWillAutoCorrect);
+ assertTrue("isPunctuationSuggestions", suggestedWords.isPunctuationSuggestions());
+ assertFalse("isObsoleteSuggestions", suggestedWords.mIsObsoleteSuggestions);
+ assertFalse("isPrediction", suggestedWords.mIsPrediction);
+ assertEquals("size", punctuationLabels.length, suggestedWords.size());
+ for (int index = 0; index < suggestedWords.size(); index++) {
+ assertEquals("punctuation label at " + index,
+ punctuationLabels[index], suggestedWords.getLabel(index));
+ assertEquals("punctuation word at " + index,
+ punctuationWords[index], suggestedWords.getWord(index));
+ }
+ }
+
+ public void testPhonePunctuationSuggestions() {
+ if (!isPhone()) {
+ return;
+ }
+ testingStandardPunctuationSuggestions(ENGLISH,
+ PUNCTUATION_LABELS_PHONE, PUNCTUATION_WORDS_PHONE_LTR);
+ testingStandardPunctuationSuggestions(FRENCH,
+ PUNCTUATION_LABELS_PHONE, PUNCTUATION_WORDS_PHONE_LTR);
+ testingStandardPunctuationSuggestions(GERMAN,
+ PUNCTUATION_LABELS_PHONE, PUNCTUATION_WORDS_PHONE_LTR);
+ testingStandardPunctuationSuggestions(ARABIC,
+ PUNCTUATION_LABELS_PHONE_ARABIC_PERSIAN, PUNCTUATION_WORDS_PHONE_ARABIC_PERSIAN);
+ testingStandardPunctuationSuggestions(PERSIAN,
+ PUNCTUATION_LABELS_PHONE_ARABIC_PERSIAN, PUNCTUATION_WORDS_PHONE_ARABIC_PERSIAN);
+ testingStandardPunctuationSuggestions(HEBREW,
+ PUNCTUATION_LABELS_PHONE, PUNCTUATION_WORDS_PHONE_HEBREW);
+ }
+
+ public void testTabletPunctuationSuggestions() {
+ if (!isTablet()) {
+ return;
+ }
+ testingStandardPunctuationSuggestions(ENGLISH,
+ PUNCTUATION_LABELS_TABLET, PUNCTUATION_WORDS_TABLET_LTR);
+ testingStandardPunctuationSuggestions(FRENCH,
+ PUNCTUATION_LABELS_TABLET, PUNCTUATION_WORDS_TABLET_LTR);
+ testingStandardPunctuationSuggestions(GERMAN,
+ PUNCTUATION_LABELS_TABLET, PUNCTUATION_WORDS_TABLET_LTR);
+ testingStandardPunctuationSuggestions(ARABIC,
+ PUNCTUATION_LABELS_TABLET_ARABIC_PERSIAN, PUNCTUATION_WORDS_TABLET_ARABIC_PERSIAN);
+ testingStandardPunctuationSuggestions(PERSIAN,
+ PUNCTUATION_LABELS_TABLET_ARABIC_PERSIAN, PUNCTUATION_WORDS_TABLET_ARABIC_PERSIAN);
+ testingStandardPunctuationSuggestions(HEBREW,
+ PUNCTUATION_LABELS_TABLET, PUNCTUATION_WORDS_TABLET_HEBREW);
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java
index 1fd5c989a..020d63299 100644
--- a/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java
@@ -16,75 +16,98 @@
package com.android.inputmethod.latin.utils;
-import com.android.inputmethod.latin.settings.SettingsValues;
-
+import android.content.res.Resources;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.TextUtils;
+import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
+
import java.util.Locale;
@SmallTest
public class CapsModeUtilsTests extends AndroidTestCase {
private static void onePathForCaps(final CharSequence cs, final int expectedResult,
- final int mask, final SettingsValues sv, final boolean hasSpaceBefore) {
- int oneTimeResult = expectedResult & mask;
+ final int mask, final SpacingAndPunctuations sp, final boolean hasSpaceBefore) {
+ final int oneTimeResult = expectedResult & mask;
assertEquals("After >" + cs + "<", oneTimeResult,
- CapsModeUtils.getCapsMode(cs, mask, sv, hasSpaceBefore));
+ CapsModeUtils.getCapsMode(cs, mask, sp, hasSpaceBefore));
}
private static void allPathsForCaps(final CharSequence cs, final int expectedResult,
- final SettingsValues sv, final boolean hasSpaceBefore) {
+ final SpacingAndPunctuations sp, final boolean hasSpaceBefore) {
final int c = TextUtils.CAP_MODE_CHARACTERS;
final int w = TextUtils.CAP_MODE_WORDS;
final int s = TextUtils.CAP_MODE_SENTENCES;
- onePathForCaps(cs, expectedResult, c | w | s, sv, hasSpaceBefore);
- onePathForCaps(cs, expectedResult, w | s, sv, hasSpaceBefore);
- onePathForCaps(cs, expectedResult, c | s, sv, hasSpaceBefore);
- onePathForCaps(cs, expectedResult, c | w, sv, hasSpaceBefore);
- onePathForCaps(cs, expectedResult, c, sv, hasSpaceBefore);
- onePathForCaps(cs, expectedResult, w, sv, hasSpaceBefore);
- onePathForCaps(cs, expectedResult, s, sv, hasSpaceBefore);
+ onePathForCaps(cs, expectedResult, c | w | s, sp, hasSpaceBefore);
+ onePathForCaps(cs, expectedResult, w | s, sp, hasSpaceBefore);
+ onePathForCaps(cs, expectedResult, c | s, sp, hasSpaceBefore);
+ onePathForCaps(cs, expectedResult, c | w, sp, hasSpaceBefore);
+ onePathForCaps(cs, expectedResult, c, sp, hasSpaceBefore);
+ onePathForCaps(cs, expectedResult, w, sp, hasSpaceBefore);
+ onePathForCaps(cs, expectedResult, s, sp, hasSpaceBefore);
}
public void testGetCapsMode() {
final int c = TextUtils.CAP_MODE_CHARACTERS;
final int w = TextUtils.CAP_MODE_WORDS;
final int s = TextUtils.CAP_MODE_SENTENCES;
- SettingsValues sv = SettingsValues.makeDummySettingsValuesForTest(Locale.ENGLISH);
- allPathsForCaps("", c | w | s, sv, false);
- allPathsForCaps("Word", c, sv, false);
- allPathsForCaps("Word.", c, sv, false);
- allPathsForCaps("Word ", c | w, sv, false);
- allPathsForCaps("Word. ", c | w | s, sv, false);
- allPathsForCaps("Word..", c, sv, false);
- allPathsForCaps("Word.. ", c | w | s, sv, false);
- allPathsForCaps("Word... ", c | w | s, sv, false);
- allPathsForCaps("Word ... ", c | w | s, sv, false);
- allPathsForCaps("Word . ", c | w, sv, false);
- allPathsForCaps("In the U.S ", c | w, sv, false);
- allPathsForCaps("In the U.S. ", c | w, sv, false);
- allPathsForCaps("Some stuff (e.g. ", c | w, sv, false);
- allPathsForCaps("In the U.S.. ", c | w | s, sv, false);
- allPathsForCaps("\"Word.\" ", c | w | s, sv, false);
- allPathsForCaps("\"Word\". ", c | w | s, sv, false);
- allPathsForCaps("\"Word\" ", c | w, sv, false);
+ final RunInLocale<SpacingAndPunctuations> job = new RunInLocale<SpacingAndPunctuations>() {
+ @Override
+ protected SpacingAndPunctuations job(final Resources res) {
+ return new SpacingAndPunctuations(res);
+ }
+ };
+ final Resources res = getContext().getResources();
+ SpacingAndPunctuations sp = job.runInLocale(res, Locale.ENGLISH);
+ allPathsForCaps("", c | w | s, sp, false);
+ allPathsForCaps("Word", c, sp, false);
+ allPathsForCaps("Word.", c, sp, false);
+ allPathsForCaps("Word ", c | w, sp, false);
+ allPathsForCaps("Word. ", c | w | s, sp, false);
+ allPathsForCaps("Word..", c, sp, false);
+ allPathsForCaps("Word.. ", c | w | s, sp, false);
+ allPathsForCaps("Word... ", c | w | s, sp, false);
+ allPathsForCaps("Word ... ", c | w | s, sp, false);
+ allPathsForCaps("Word . ", c | w, sp, false);
+ allPathsForCaps("In the U.S ", c | w, sp, false);
+ allPathsForCaps("In the U.S. ", c | w, sp, false);
+ allPathsForCaps("Some stuff (e.g. ", c | w, sp, false);
+ allPathsForCaps("In the U.S.. ", c | w | s, sp, false);
+ allPathsForCaps("\"Word.\" ", c | w | s, sp, false);
+ allPathsForCaps("\"Word\". ", c | w | s, sp, false);
+ allPathsForCaps("\"Word\" ", c | w, sp, false);
// Test for phantom space
- allPathsForCaps("Word", c | w, sv, true);
- allPathsForCaps("Word.", c | w | s, sv, true);
+ allPathsForCaps("Word", c | w, sp, true);
+ allPathsForCaps("Word.", c | w | s, sp, true);
// Tests after some whitespace
- allPathsForCaps("Word\n", c | w | s, sv, false);
- allPathsForCaps("Word\n", c | w | s, sv, true);
- allPathsForCaps("Word\n ", c | w | s, sv, true);
- allPathsForCaps("Word.\n", c | w | s, sv, false);
- allPathsForCaps("Word.\n", c | w | s, sv, true);
- allPathsForCaps("Word.\n ", c | w | s, sv, true);
+ allPathsForCaps("Word\n", c | w | s, sp, false);
+ allPathsForCaps("Word\n", c | w | s, sp, true);
+ allPathsForCaps("Word\n ", c | w | s, sp, true);
+ allPathsForCaps("Word.\n", c | w | s, sp, false);
+ allPathsForCaps("Word.\n", c | w | s, sp, true);
+ allPathsForCaps("Word.\n ", c | w | s, sp, true);
+
+ sp = job.runInLocale(res, Locale.FRENCH);
+ allPathsForCaps("\"Word.\" ", c | w, sp, false);
+ allPathsForCaps("\"Word\". ", c | w | s, sp, false);
+ allPathsForCaps("\"Word\" ", c | w, sp, false);
- sv = SettingsValues.makeDummySettingsValuesForTest(Locale.FRENCH);
- allPathsForCaps("\"Word.\" ", c | w, sv, false);
- allPathsForCaps("\"Word\". ", c | w | s, sv, false);
- allPathsForCaps("\"Word\" ", c | w, sv, false);
+ // Test special case for German. German does not capitalize at the start of a
+ // line when the previous line starts with a comma. It does in other cases.
+ sp = job.runInLocale(res, Locale.GERMAN);
+ allPathsForCaps("Liebe Sara,\n", c | w, sp, false);
+ allPathsForCaps("Liebe Sara,\n", c | w, sp, true);
+ allPathsForCaps("Liebe Sara, \n ", c | w, sp, false);
+ allPathsForCaps("Liebe Sara \n ", c | w | s, sp, false);
+ allPathsForCaps("Liebe Sara.\n ", c | w | s, sp, false);
+ sp = job.runInLocale(res, Locale.ENGLISH);
+ allPathsForCaps("Liebe Sara,\n", c | w | s, sp, false);
+ allPathsForCaps("Liebe Sara,\n", c | w | s, sp, true);
+ allPathsForCaps("Liebe Sara, \n ", c | w | s, sp, false);
+ allPathsForCaps("Liebe Sara \n ", c | w | s, sp, false);
+ allPathsForCaps("Liebe Sara.\n ", c | w | s, sp, false);
}
}
diff --git a/tests/src/com/android/inputmethod/latin/utils/DictionaryInfoUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/DictionaryInfoUtilsTests.java
new file mode 100644
index 000000000..6e716074c
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/utils/DictionaryInfoUtilsTests.java
@@ -0,0 +1,47 @@
+/*
+ * 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.latin.utils;
+
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
+
+import java.util.Locale;
+
+@SmallTest
+public class DictionaryInfoUtilsTests extends AndroidTestCase {
+ public void testLooksValidForDictionaryInsertion() {
+ final RunInLocale<SpacingAndPunctuations> job = new RunInLocale<SpacingAndPunctuations>() {
+ @Override
+ protected SpacingAndPunctuations job(final Resources res) {
+ return new SpacingAndPunctuations(res);
+ }
+ };
+ final Resources res = getContext().getResources();
+ final SpacingAndPunctuations sp = job.runInLocale(res, Locale.ENGLISH);
+ assertTrue(DictionaryInfoUtils.looksValidForDictionaryInsertion("aochaueo", sp));
+ assertFalse(DictionaryInfoUtils.looksValidForDictionaryInsertion("", sp));
+ assertTrue(DictionaryInfoUtils.looksValidForDictionaryInsertion("ao-ch'aueo", sp));
+ assertFalse(DictionaryInfoUtils.looksValidForDictionaryInsertion("2908743256", sp));
+ assertTrue(DictionaryInfoUtils.looksValidForDictionaryInsertion("31aochaueo", sp));
+ assertFalse(DictionaryInfoUtils.looksValidForDictionaryInsertion("akeo raeoch oerch .",
+ sp));
+ assertFalse(DictionaryInfoUtils.looksValidForDictionaryInsertion("!!!", sp));
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/utils/ForgettingCurveTests.java b/tests/src/com/android/inputmethod/latin/utils/ForgettingCurveTests.java
deleted file mode 100644
index 823bd5d7d..000000000
--- a/tests/src/com/android/inputmethod/latin/utils/ForgettingCurveTests.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2012 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.latin.utils;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-@SmallTest
-public class ForgettingCurveTests extends AndroidTestCase {
- public void testFcToFreq() {
- for (int i = 0; i < Byte.MAX_VALUE; ++i) {
- final byte fc = (byte)i;
- final int e = UserHistoryForgettingCurveUtils.fcToElapsedTime(fc);
- final int c = UserHistoryForgettingCurveUtils.fcToCount(fc);
- final int l = UserHistoryForgettingCurveUtils.fcToLevel(fc);
- final byte fc2 = UserHistoryForgettingCurveUtils.calcFc(e, c, l);
- assertEquals(fc, fc2);
- }
- byte fc = 0;
- int l;
- for (int i = 0; i < 4; ++i) {
- for (int j = 0; j < (UserHistoryForgettingCurveUtils.COUNT_MAX + 1); ++j) {
- fc = UserHistoryForgettingCurveUtils.pushCount(fc, true);
- }
- l = UserHistoryForgettingCurveUtils.fcToLevel(fc);
- assertEquals(l, Math.max(1, Math.min(i + 1, 3)));
- }
- fc = 0;
- for (int i = 0; i < 4; ++i) {
- for (int j = 0; j < (UserHistoryForgettingCurveUtils.COUNT_MAX + 1); ++j) {
- fc = UserHistoryForgettingCurveUtils.pushCount(fc, false);
- }
- l = UserHistoryForgettingCurveUtils.fcToLevel(fc);
- assertEquals(l, Math.min(i + 1, 3));
- }
- for (int i = 0; i < 4; ++i) {
- for (int j = 0; j < (UserHistoryForgettingCurveUtils.ELAPSED_TIME_MAX + 1); ++j) {
- fc = UserHistoryForgettingCurveUtils.pushElapsedTime(fc);
- }
- l = UserHistoryForgettingCurveUtils.fcToLevel(fc);
- assertEquals(l, Math.max(0, 2 - i));
- }
- }
-}
diff --git a/tests/src/com/android/inputmethod/latin/utils/RecapitalizeStatusTests.java b/tests/src/com/android/inputmethod/latin/utils/RecapitalizeStatusTests.java
index a52041264..ada80c3fa 100644
--- a/tests/src/com/android/inputmethod/latin/utils/RecapitalizeStatusTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/RecapitalizeStatusTests.java
@@ -19,31 +19,35 @@ package com.android.inputmethod.latin.utils;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.inputmethod.latin.Constants;
+
import java.util.Locale;
@SmallTest
public class RecapitalizeStatusTests extends AndroidTestCase {
+ private static final int[] SPACE = { Constants.CODE_SPACE };
+
public void testTrim() {
final RecapitalizeStatus status = new RecapitalizeStatus();
- status.initialize(30, 40, "abcdefghij", Locale.ENGLISH, " ");
+ status.initialize(30, 40, "abcdefghij", Locale.ENGLISH, SPACE);
status.trim();
assertEquals("abcdefghij", status.getRecapitalizedString());
assertEquals(30, status.getNewCursorStart());
assertEquals(40, status.getNewCursorEnd());
- status.initialize(30, 44, " abcdefghij", Locale.ENGLISH, " ");
+ status.initialize(30, 44, " abcdefghij", Locale.ENGLISH, SPACE);
status.trim();
assertEquals("abcdefghij", status.getRecapitalizedString());
assertEquals(34, status.getNewCursorStart());
assertEquals(44, status.getNewCursorEnd());
- status.initialize(30, 40, "abcdefgh ", Locale.ENGLISH, " ");
+ status.initialize(30, 40, "abcdefgh ", Locale.ENGLISH, SPACE);
status.trim();
assertEquals("abcdefgh", status.getRecapitalizedString());
assertEquals(30, status.getNewCursorStart());
assertEquals(38, status.getNewCursorEnd());
- status.initialize(30, 45, " abcdefghij ", Locale.ENGLISH, " ");
+ status.initialize(30, 45, " abcdefghij ", Locale.ENGLISH, SPACE);
status.trim();
assertEquals("abcdefghij", status.getRecapitalizedString());
assertEquals(33, status.getNewCursorStart());
@@ -52,7 +56,7 @@ public class RecapitalizeStatusTests extends AndroidTestCase {
public void testRotate() {
final RecapitalizeStatus status = new RecapitalizeStatus();
- status.initialize(29, 40, "abcd efghij", Locale.ENGLISH, " ");
+ status.initialize(29, 40, "abcd efghij", Locale.ENGLISH, SPACE);
status.rotate();
assertEquals("Abcd Efghij", status.getRecapitalizedString());
assertEquals(29, status.getNewCursorStart());
@@ -64,7 +68,7 @@ public class RecapitalizeStatusTests extends AndroidTestCase {
status.rotate();
assertEquals("Abcd Efghij", status.getRecapitalizedString());
- status.initialize(29, 40, "Abcd Efghij", Locale.ENGLISH, " ");
+ status.initialize(29, 40, "Abcd Efghij", Locale.ENGLISH, SPACE);
status.rotate();
assertEquals("ABCD EFGHIJ", status.getRecapitalizedString());
assertEquals(29, status.getNewCursorStart());
@@ -76,7 +80,7 @@ public class RecapitalizeStatusTests extends AndroidTestCase {
status.rotate();
assertEquals("ABCD EFGHIJ", status.getRecapitalizedString());
- status.initialize(29, 40, "ABCD EFGHIJ", Locale.ENGLISH, " ");
+ status.initialize(29, 40, "ABCD EFGHIJ", Locale.ENGLISH, SPACE);
status.rotate();
assertEquals("abcd efghij", status.getRecapitalizedString());
assertEquals(29, status.getNewCursorStart());
@@ -88,7 +92,7 @@ public class RecapitalizeStatusTests extends AndroidTestCase {
status.rotate();
assertEquals("abcd efghij", status.getRecapitalizedString());
- status.initialize(29, 39, "AbCDefghij", Locale.ENGLISH, " ");
+ status.initialize(29, 39, "AbCDefghij", Locale.ENGLISH, SPACE);
status.rotate();
assertEquals("abcdefghij", status.getRecapitalizedString());
assertEquals(29, status.getNewCursorStart());
@@ -102,7 +106,7 @@ public class RecapitalizeStatusTests extends AndroidTestCase {
status.rotate();
assertEquals("abcdefghij", status.getRecapitalizedString());
- status.initialize(29, 40, "Abcd efghij", Locale.ENGLISH, " ");
+ status.initialize(29, 40, "Abcd efghij", Locale.ENGLISH, SPACE);
status.rotate();
assertEquals("abcd efghij", status.getRecapitalizedString());
assertEquals(29, status.getNewCursorStart());
@@ -116,7 +120,8 @@ public class RecapitalizeStatusTests extends AndroidTestCase {
status.rotate();
assertEquals("abcd efghij", status.getRecapitalizedString());
- status.initialize(30, 34, "grüß", Locale.GERMAN, " "); status.rotate();
+ status.initialize(30, 34, "grüß", Locale.GERMAN, SPACE);
+ status.rotate();
assertEquals("Grüß", status.getRecapitalizedString());
assertEquals(30, status.getNewCursorStart());
assertEquals(34, status.getNewCursorEnd());
@@ -133,7 +138,8 @@ public class RecapitalizeStatusTests extends AndroidTestCase {
assertEquals(30, status.getNewCursorStart());
assertEquals(34, status.getNewCursorEnd());
- status.initialize(30, 33, "œuf", Locale.FRENCH, " "); status.rotate();
+ status.initialize(30, 33, "œuf", Locale.FRENCH, SPACE);
+ status.rotate();
assertEquals("Œuf", status.getRecapitalizedString());
assertEquals(30, status.getNewCursorStart());
assertEquals(33, status.getNewCursorEnd());
@@ -150,7 +156,8 @@ public class RecapitalizeStatusTests extends AndroidTestCase {
assertEquals(30, status.getNewCursorStart());
assertEquals(33, status.getNewCursorEnd());
- status.initialize(30, 33, "œUf", Locale.FRENCH, " "); status.rotate();
+ status.initialize(30, 33, "œUf", Locale.FRENCH, SPACE);
+ status.rotate();
assertEquals("œuf", status.getRecapitalizedString());
assertEquals(30, status.getNewCursorStart());
assertEquals(33, status.getNewCursorEnd());
@@ -171,7 +178,8 @@ public class RecapitalizeStatusTests extends AndroidTestCase {
assertEquals(30, status.getNewCursorStart());
assertEquals(33, status.getNewCursorEnd());
- status.initialize(30, 35, "école", Locale.FRENCH, " "); status.rotate();
+ status.initialize(30, 35, "école", Locale.FRENCH, SPACE);
+ status.rotate();
assertEquals("École", status.getRecapitalizedString());
assertEquals(30, status.getNewCursorStart());
assertEquals(35, status.getNewCursorEnd());
diff --git a/tests/src/com/android/inputmethod/latin/utils/ResizableIntArrayTests.java b/tests/src/com/android/inputmethod/latin/utils/ResizableIntArrayTests.java
index cad80d5ce..8f58e6873 100644
--- a/tests/src/com/android/inputmethod/latin/utils/ResizableIntArrayTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/ResizableIntArrayTests.java
@@ -39,7 +39,8 @@ public class ResizableIntArrayTests extends AndroidTestCase {
int[] array2 = null, array3 = null;
final int limit = DEFAULT_CAPACITY * 2 + 10;
for (int i = 0; i < limit; i++) {
- src.add(i);
+ final int value = i;
+ src.add(value);
assertEquals("length after add " + i, i + 1, src.getLength());
if (i == DEFAULT_CAPACITY) {
array2 = src.getPrimitiveArray();
@@ -56,7 +57,8 @@ public class ResizableIntArrayTests extends AndroidTestCase {
}
}
for (int i = 0; i < limit; i++) {
- assertEquals("value at " + i, i, src.get(i));
+ final int value = i;
+ assertEquals("value at " + i, value, src.get(i));
}
}
@@ -64,11 +66,13 @@ public class ResizableIntArrayTests extends AndroidTestCase {
final ResizableIntArray src = new ResizableIntArray(DEFAULT_CAPACITY);
final int limit = DEFAULT_CAPACITY * 10, step = DEFAULT_CAPACITY * 2;
for (int i = 0; i < limit; i += step) {
- src.add(i, i);
+ final int value = i;
+ src.addAt(i, value);
assertEquals("length after add at " + i, i + 1, src.getLength());
}
for (int i = 0; i < limit; i += step) {
- assertEquals("value at " + i, i, src.get(i));
+ final int value = i;
+ assertEquals("value at " + i, value, src.get(i));
}
}
@@ -88,9 +92,10 @@ public class ResizableIntArrayTests extends AndroidTestCase {
}
final int index = DEFAULT_CAPACITY / 2;
- src.add(index, 100);
+ final int valueAddAt = 100;
+ src.addAt(index, valueAddAt);
assertEquals("legth after add at " + index, index + 1, src.getLength());
- assertEquals("value after add at " + index, 100, src.get(index));
+ assertEquals("value after add at " + index, valueAddAt, src.get(index));
assertEquals("value after add at 0", 0, src.get(0));
try {
final int value = src.get(src.getLength());
@@ -104,7 +109,8 @@ public class ResizableIntArrayTests extends AndroidTestCase {
final ResizableIntArray src = new ResizableIntArray(DEFAULT_CAPACITY);
final int[] array = src.getPrimitiveArray();
for (int i = 0; i < DEFAULT_CAPACITY; i++) {
- src.add(i);
+ final int value = i;
+ src.add(value);
assertEquals("length after add " + i, i + 1, src.getLength());
}
@@ -116,7 +122,8 @@ public class ResizableIntArrayTests extends AndroidTestCase {
int[] array3 = null;
for (int i = 0; i < DEFAULT_CAPACITY; i++) {
- src.add(i);
+ final int value = i;
+ src.add(value);
assertEquals("length after add " + i, i + 1, src.getLength());
if (i == smallerLength) {
array3 = src.getPrimitiveArray();
@@ -133,7 +140,8 @@ public class ResizableIntArrayTests extends AndroidTestCase {
final ResizableIntArray src = new ResizableIntArray(DEFAULT_CAPACITY);
final int[] array = src.getPrimitiveArray();
for (int i = 0; i < DEFAULT_CAPACITY; i++) {
- src.add(i);
+ final int value = i;
+ src.add(value);
assertEquals("length after add " + i, i + 1, src.getLength());
}
@@ -144,11 +152,11 @@ public class ResizableIntArrayTests extends AndroidTestCase {
assertNotSame("array after larger setLength", array, array2);
assertEquals("array length after larger setLength", largerLength, array2.length);
for (int i = 0; i < largerLength; i++) {
- final int v = src.get(i);
+ final int value = i;
if (i < DEFAULT_CAPACITY) {
- assertEquals("value at " + i, i, v);
+ assertEquals("value at " + i, value, src.get(i));
} else {
- assertEquals("value at " + i, 0, v);
+ assertEquals("value at " + i, 0, src.get(i));
}
}
@@ -159,7 +167,8 @@ public class ResizableIntArrayTests extends AndroidTestCase {
assertSame("array after smaller setLength", array2, array3);
assertEquals("array length after smaller setLength", largerLength, array3.length);
for (int i = 0; i < smallerLength; i++) {
- assertEquals("value at " + i, i, src.get(i));
+ final int value = i;
+ assertEquals("value at " + i, value, src.get(i));
}
}
@@ -167,7 +176,8 @@ public class ResizableIntArrayTests extends AndroidTestCase {
final ResizableIntArray src = new ResizableIntArray(DEFAULT_CAPACITY);
final int limit = DEFAULT_CAPACITY * 2 + 10;
for (int i = 0; i < limit; i++) {
- src.add(i);
+ final int value = i;
+ src.add(value);
}
final ResizableIntArray dst = new ResizableIntArray(DEFAULT_CAPACITY);
@@ -179,7 +189,8 @@ public class ResizableIntArrayTests extends AndroidTestCase {
public void testCopy() {
final ResizableIntArray src = new ResizableIntArray(DEFAULT_CAPACITY);
for (int i = 0; i < DEFAULT_CAPACITY; i++) {
- src.add(i);
+ final int value = i;
+ src.add(value);
}
final ResizableIntArray dst = new ResizableIntArray(DEFAULT_CAPACITY);
@@ -204,119 +215,126 @@ public class ResizableIntArrayTests extends AndroidTestCase {
}
public void testAppend() {
- final int srcLen = DEFAULT_CAPACITY;
- final ResizableIntArray src = new ResizableIntArray(srcLen);
- for (int i = 0; i < srcLen; i++) {
- src.add(i);
+ final int srcLength = DEFAULT_CAPACITY;
+ final ResizableIntArray src = new ResizableIntArray(srcLength);
+ for (int i = 0; i < srcLength; i++) {
+ final int value = i;
+ src.add(value);
}
final ResizableIntArray dst = new ResizableIntArray(DEFAULT_CAPACITY * 2);
final int[] array = dst.getPrimitiveArray();
- final int dstLen = DEFAULT_CAPACITY / 2;
- for (int i = 0; i < dstLen; i++) {
+ final int dstLength = DEFAULT_CAPACITY / 2;
+ for (int i = 0; i < dstLength; i++) {
final int value = -i - 1;
dst.add(value);
}
final ResizableIntArray dstCopy = new ResizableIntArray(dst.getLength());
dstCopy.copy(dst);
- dst.append(src, 0, 0);
- assertEquals("length after append zero", dstLen, dst.getLength());
+ final int startPos = 0;
+ dst.append(src, startPos, 0 /* length */);
+ assertEquals("length after append zero", dstLength, dst.getLength());
assertSame("array after append zero", array, dst.getPrimitiveArray());
- assertIntArrayEquals("values after append zero",
- dstCopy.getPrimitiveArray(), 0, dst.getPrimitiveArray(), 0, dstLen);
+ assertIntArrayEquals("values after append zero", dstCopy.getPrimitiveArray(), startPos,
+ dst.getPrimitiveArray(), startPos, dstLength);
- dst.append(src, 0, srcLen);
- assertEquals("length after append", dstLen + srcLen, dst.getLength());
+ dst.append(src, startPos, srcLength);
+ assertEquals("length after append", dstLength + srcLength, dst.getLength());
assertSame("array after append", array, dst.getPrimitiveArray());
assertTrue("primitive length after append",
- dst.getPrimitiveArray().length >= dstLen + srcLen);
- assertIntArrayEquals("original values after append",
- dstCopy.getPrimitiveArray(), 0, dst.getPrimitiveArray(), 0, dstLen);
- assertIntArrayEquals("appended values after append",
- src.getPrimitiveArray(), 0, dst.getPrimitiveArray(), dstLen, srcLen);
+ dst.getPrimitiveArray().length >= dstLength + srcLength);
+ assertIntArrayEquals("original values after append", dstCopy.getPrimitiveArray(), startPos,
+ dst.getPrimitiveArray(), startPos, dstLength);
+ assertIntArrayEquals("appended values after append", src.getPrimitiveArray(), startPos,
+ dst.getPrimitiveArray(), dstLength, srcLength);
- dst.append(src, 0, srcLen);
- assertEquals("length after 2nd append", dstLen + srcLen * 2, dst.getLength());
+ dst.append(src, startPos, srcLength);
+ assertEquals("length after 2nd append", dstLength + srcLength * 2, dst.getLength());
assertNotSame("array after 2nd append", array, dst.getPrimitiveArray());
assertTrue("primitive length after 2nd append",
- dst.getPrimitiveArray().length >= dstLen + srcLen * 2);
+ dst.getPrimitiveArray().length >= dstLength + srcLength * 2);
assertIntArrayEquals("original values after 2nd append",
- dstCopy.getPrimitiveArray(), 0, dst.getPrimitiveArray(), 0, dstLen);
+ dstCopy.getPrimitiveArray(), startPos, dst.getPrimitiveArray(), startPos,
+ dstLength);
assertIntArrayEquals("appended values after 2nd append",
- src.getPrimitiveArray(), 0, dst.getPrimitiveArray(), dstLen, srcLen);
+ src.getPrimitiveArray(), startPos, dst.getPrimitiveArray(), dstLength,
+ srcLength);
assertIntArrayEquals("appended values after 2nd append",
- src.getPrimitiveArray(), 0, dst.getPrimitiveArray(), dstLen + srcLen, srcLen);
+ src.getPrimitiveArray(), startPos, dst.getPrimitiveArray(), dstLength + srcLength,
+ srcLength);
}
public void testFill() {
- final int srcLen = DEFAULT_CAPACITY;
- final ResizableIntArray src = new ResizableIntArray(srcLen);
- for (int i = 0; i < srcLen; i++) {
- src.add(i);
+ final int srcLength = DEFAULT_CAPACITY;
+ final ResizableIntArray src = new ResizableIntArray(srcLength);
+ for (int i = 0; i < srcLength; i++) {
+ final int value = i;
+ src.add(value);
}
final int[] array = src.getPrimitiveArray();
- final int startPos = srcLen / 3;
- final int length = srcLen / 3;
+ final int startPos = srcLength / 3;
+ final int length = srcLength / 3;
final int endPos = startPos + length;
assertTrue(startPos >= 1);
- final int value = 123;
+ final int fillValue = 123;
try {
- src.fill(value, -1, length);
+ src.fill(fillValue, -1 /* startPos */, length);
fail("fill from -1 shouldn't succeed");
} catch (IllegalArgumentException e) {
// success
}
try {
- src.fill(value, startPos, -1);
+ src.fill(fillValue, startPos, -1 /* length */);
fail("fill negative length shouldn't succeed");
} catch (IllegalArgumentException e) {
// success
}
- src.fill(value, startPos, length);
- assertEquals("length after fill", srcLen, src.getLength());
+ src.fill(fillValue, startPos, length);
+ assertEquals("length after fill", srcLength, src.getLength());
assertSame("array after fill", array, src.getPrimitiveArray());
- for (int i = 0; i < srcLen; i++) {
- final int v = src.get(i);
+ for (int i = 0; i < srcLength; i++) {
+ final int value = i;
if (i >= startPos && i < endPos) {
- assertEquals("new values after fill at " + i, value, v);
+ assertEquals("new values after fill at " + i, fillValue, src.get(i));
} else {
- assertEquals("unmodified values after fill at " + i, i, v);
+ assertEquals("unmodified values after fill at " + i, value, src.get(i));
}
}
- final int length2 = srcLen * 2 - startPos;
+ final int length2 = srcLength * 2 - startPos;
final int largeEnd = startPos + length2;
- assertTrue(largeEnd > srcLen);
- final int value2 = 456;
- src.fill(value2, startPos, length2);
+ assertTrue(largeEnd > srcLength);
+ final int fillValue2 = 456;
+ src.fill(fillValue2, startPos, length2);
assertEquals("length after large fill", largeEnd, src.getLength());
assertNotSame("array after large fill", array, src.getPrimitiveArray());
for (int i = 0; i < largeEnd; i++) {
- final int v = src.get(i);
+ final int value = i;
if (i >= startPos && i < largeEnd) {
- assertEquals("new values after large fill at " + i, value2, v);
+ assertEquals("new values after large fill at " + i, fillValue2, src.get(i));
} else {
- assertEquals("unmodified values after large fill at " + i, i, v);
+ assertEquals("unmodified values after large fill at " + i, value, src.get(i));
}
}
final int startPos2 = largeEnd + length2;
final int endPos2 = startPos2 + length2;
- final int value3 = 789;
- src.fill(value3, startPos2, length2);
+ final int fillValue3 = 789;
+ src.fill(fillValue3, startPos2, length2);
assertEquals("length after disjoint fill", endPos2, src.getLength());
for (int i = 0; i < endPos2; i++) {
- final int v = src.get(i);
+ final int value = i;
if (i >= startPos2 && i < endPos2) {
- assertEquals("new values after disjoint fill at " + i, value3, v);
+ assertEquals("new values after disjoint fill at " + i, fillValue3, src.get(i));
} else if (i >= startPos && i < largeEnd) {
- assertEquals("unmodified values after disjoint fill at " + i, value2, v);
+ assertEquals("unmodified values after disjoint fill at " + i,
+ fillValue2, src.get(i));
} else if (i < startPos) {
- assertEquals("unmodified values after disjoint fill at " + i, i, v);
+ assertEquals("unmodified values after disjoint fill at " + i, value, src.get(i));
} else {
- assertEquals("gap values after disjoint fill at " + i, 0, v);
+ assertEquals("gap values after disjoint fill at " + i, 0, src.get(i));
}
}
}
@@ -346,12 +364,14 @@ public class ResizableIntArrayTests extends AndroidTestCase {
final int limit = DEFAULT_CAPACITY * 10;
final int shiftAmount = 20;
for (int i = 0; i < limit; ++i) {
- src.add(i, i);
+ final int value = i;
+ src.addAt(i, value);
assertEquals("length after add at " + i, i + 1, src.getLength());
}
src.shift(shiftAmount);
for (int i = 0; i < limit - shiftAmount; ++i) {
- assertEquals("value at " + i, i + shiftAmount, src.get(i));
+ final int oldValue = i + shiftAmount;
+ assertEquals("value at " + i, oldValue, src.get(i));
}
}
}
diff --git a/tests/src/com/android/inputmethod/latin/utils/ResourceUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/ResourceUtilsTests.java
index 1ae22e307..3eb704093 100644
--- a/tests/src/com/android/inputmethod/latin/utils/ResourceUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/ResourceUtilsTests.java
@@ -19,43 +19,10 @@ package com.android.inputmethod.latin.utils;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
-import com.android.inputmethod.latin.utils.ResourceUtils.DeviceOverridePatternSyntaxError;
-
import java.util.HashMap;
@SmallTest
public class ResourceUtilsTests extends AndroidTestCase {
- public void testFindDefaultConstant() {
- final String[] nullArray = null;
- final String[] emptyArray = {};
- final String[] array = {
- "HARDWARE=grouper,0.3",
- "HARDWARE=mako,0.4",
- ",defaultValue1",
- "HARDWARE=manta,0.2",
- ",defaultValue2",
- };
-
- try {
- assertNull(ResourceUtils.findDefaultConstant(nullArray));
- assertNull(ResourceUtils.findDefaultConstant(emptyArray));
- assertEquals(ResourceUtils.findDefaultConstant(array), "defaultValue1");
- } catch (final DeviceOverridePatternSyntaxError e) {
- fail(e.getMessage());
- }
-
- final String[] errorArray = {
- "HARDWARE=grouper,0.3",
- "no_comma"
- };
- try {
- final String defaultValue = ResourceUtils.findDefaultConstant(errorArray);
- fail("exception should be thrown: defaultValue=" + defaultValue);
- } catch (final DeviceOverridePatternSyntaxError e) {
- assertEquals("Array element has no comma: no_comma", e.getMessage());
- }
- }
-
public void testFindConstantForKeyValuePairsSimple() {
final HashMap<String,String> anyKeyValue = CollectionUtils.newHashMap();
anyKeyValue.put("anyKey", "anyValue");
diff --git a/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/StringAndJsonUtilsTests.java
index 4e396a1cf..e55c32bd0 100644
--- a/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/StringAndJsonUtilsTests.java
@@ -16,17 +16,17 @@
package com.android.inputmethod.latin.utils;
-import com.android.inputmethod.latin.settings.SettingsValues;
-
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.inputmethod.latin.Constants;
+
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
@SmallTest
-public class StringUtilsTests extends AndroidTestCase {
+public class StringAndJsonUtilsTests extends AndroidTestCase {
public void testContainsInArray() {
assertFalse("empty array", StringUtils.containsInArray("key", new String[0]));
assertFalse("not in 1 element", StringUtils.containsInArray("key", new String[] {
@@ -44,7 +44,7 @@ public class StringUtilsTests extends AndroidTestCase {
}));
}
- public void testContainsInExtraValues() {
+ public void testContainsInCommaSplittableText() {
assertFalse("null", StringUtils.containsInCommaSplittableText("key", null));
assertFalse("empty", StringUtils.containsInCommaSplittableText("key", ""));
assertFalse("not in 1 element",
@@ -56,7 +56,28 @@ public class StringUtilsTests extends AndroidTestCase {
assertTrue("in 2 elements", StringUtils.containsInCommaSplittableText("key", "key1,key"));
}
- public void testAppendToExtraValuesIfNotExists() {
+ public void testJoinCommaSplittableText() {
+ assertEquals("2 nulls", "",
+ StringUtils.joinCommaSplittableText(null, null));
+ assertEquals("null and empty", "",
+ StringUtils.joinCommaSplittableText(null, ""));
+ assertEquals("empty and null", "",
+ StringUtils.joinCommaSplittableText("", null));
+ assertEquals("2 empties", "",
+ StringUtils.joinCommaSplittableText("", ""));
+ assertEquals("text and null", "text",
+ StringUtils.joinCommaSplittableText("text", null));
+ assertEquals("text and empty", "text",
+ StringUtils.joinCommaSplittableText("text", ""));
+ assertEquals("null and text", "text",
+ StringUtils.joinCommaSplittableText(null, "text"));
+ assertEquals("empty and text", "text",
+ StringUtils.joinCommaSplittableText("", "text"));
+ assertEquals("2 texts", "text1,text2",
+ StringUtils.joinCommaSplittableText("text1", "text2"));
+ }
+
+ public void testAppendToCommaSplittableTextIfNotExists() {
assertEquals("null", "key",
StringUtils.appendToCommaSplittableTextIfNotExists("key", null));
assertEquals("empty", "key",
@@ -77,7 +98,7 @@ public class StringUtilsTests extends AndroidTestCase {
StringUtils.appendToCommaSplittableTextIfNotExists("key", "key1,key,key3"));
}
- public void testRemoveFromExtraValuesIfExists() {
+ public void testRemoveFromCommaSplittableTextIfExists() {
assertEquals("null", "", StringUtils.removeFromCommaSplittableTextIfExists("key", null));
assertEquals("empty", "", StringUtils.removeFromCommaSplittableTextIfExists("key", ""));
@@ -187,54 +208,47 @@ public class StringUtilsTests extends AndroidTestCase {
assertTrue(StringUtils.isIdenticalAfterDowncase(""));
}
- public void testLooksValidForDictionaryInsertion() {
- final SettingsValues settings =
- SettingsValues.makeDummySettingsValuesForTest(Locale.ENGLISH);
- assertTrue(StringUtils.looksValidForDictionaryInsertion("aochaueo", settings));
- assertFalse(StringUtils.looksValidForDictionaryInsertion("", settings));
- assertTrue(StringUtils.looksValidForDictionaryInsertion("ao-ch'aueo", settings));
- assertFalse(StringUtils.looksValidForDictionaryInsertion("2908743256", settings));
- assertTrue(StringUtils.looksValidForDictionaryInsertion("31aochaueo", settings));
- assertFalse(StringUtils.looksValidForDictionaryInsertion("akeo raeoch oerch .", settings));
- assertFalse(StringUtils.looksValidForDictionaryInsertion("!!!", settings));
- }
-
- private static void checkCapitalize(final String src, final String dst, final String separators,
- final Locale locale) {
- assertEquals(dst, StringUtils.capitalizeEachWord(src, separators, locale));
+ private static void checkCapitalize(final String src, final String dst,
+ final int[] sortedSeparators, final Locale locale) {
+ assertEquals(dst, StringUtils.capitalizeEachWord(src, sortedSeparators, locale));
assert(src.equals(dst)
- == StringUtils.isIdenticalAfterCapitalizeEachWord(src, separators));
+ == StringUtils.isIdenticalAfterCapitalizeEachWord(src, sortedSeparators));
}
+ private static final int[] SPACE = { Constants.CODE_SPACE };
+ private static final int[] SPACE_PERIOD = StringUtils.toSortedCodePointArray(" .");
+ private static final int[] SENTENCE_SEPARATORS =
+ StringUtils.toSortedCodePointArray(" \n.!?*()&");
+ private static final int[] WORD_SEPARATORS = StringUtils.toSortedCodePointArray(" \n.!?*,();&");
+
public void testCapitalizeEachWord() {
- checkCapitalize("", "", " ", Locale.ENGLISH);
- checkCapitalize("test", "Test", " ", Locale.ENGLISH);
- checkCapitalize(" test", " Test", " ", Locale.ENGLISH);
- checkCapitalize("Test", "Test", " ", Locale.ENGLISH);
- checkCapitalize(" Test", " Test", " ", Locale.ENGLISH);
- checkCapitalize(".Test", ".test", " ", Locale.ENGLISH);
- checkCapitalize(".Test", ".Test", " .", Locale.ENGLISH);
- checkCapitalize(".Test", ".Test", ". ", Locale.ENGLISH);
- checkCapitalize("test and retest", "Test And Retest", " .", Locale.ENGLISH);
- checkCapitalize("Test and retest", "Test And Retest", " .", Locale.ENGLISH);
- checkCapitalize("Test And Retest", "Test And Retest", " .", Locale.ENGLISH);
- checkCapitalize("Test And.Retest ", "Test And.Retest ", " .", Locale.ENGLISH);
- checkCapitalize("Test And.retest ", "Test And.Retest ", " .", Locale.ENGLISH);
- checkCapitalize("Test And.retest ", "Test And.retest ", " ", Locale.ENGLISH);
- checkCapitalize("Test And.Retest ", "Test And.retest ", " ", Locale.ENGLISH);
- checkCapitalize("test and ietest", "Test And İetest", " .", new Locale("tr"));
- checkCapitalize("test and ietest", "Test And Ietest", " .", Locale.ENGLISH);
- checkCapitalize("Test&Retest", "Test&Retest", " \n.!?*()&", Locale.ENGLISH);
- checkCapitalize("Test&retest", "Test&Retest", " \n.!?*()&", Locale.ENGLISH);
- checkCapitalize("test&Retest", "Test&Retest", " \n.!?*()&", Locale.ENGLISH);
+ checkCapitalize("", "", SPACE, Locale.ENGLISH);
+ checkCapitalize("test", "Test", SPACE, Locale.ENGLISH);
+ checkCapitalize(" test", " Test", SPACE, Locale.ENGLISH);
+ checkCapitalize("Test", "Test", SPACE, Locale.ENGLISH);
+ checkCapitalize(" Test", " Test", SPACE, Locale.ENGLISH);
+ checkCapitalize(".Test", ".test", SPACE, Locale.ENGLISH);
+ checkCapitalize(".Test", ".Test", SPACE_PERIOD, Locale.ENGLISH);
+ checkCapitalize("test and retest", "Test And Retest", SPACE_PERIOD, Locale.ENGLISH);
+ checkCapitalize("Test and retest", "Test And Retest", SPACE_PERIOD, Locale.ENGLISH);
+ checkCapitalize("Test And Retest", "Test And Retest", SPACE_PERIOD, Locale.ENGLISH);
+ checkCapitalize("Test And.Retest ", "Test And.Retest ", SPACE_PERIOD, Locale.ENGLISH);
+ checkCapitalize("Test And.retest ", "Test And.Retest ", SPACE_PERIOD, Locale.ENGLISH);
+ checkCapitalize("Test And.retest ", "Test And.retest ", SPACE, Locale.ENGLISH);
+ checkCapitalize("Test And.Retest ", "Test And.retest ", SPACE, Locale.ENGLISH);
+ checkCapitalize("test and ietest", "Test And İetest", SPACE_PERIOD, new Locale("tr"));
+ checkCapitalize("test and ietest", "Test And Ietest", SPACE_PERIOD, Locale.ENGLISH);
+ checkCapitalize("Test&Retest", "Test&Retest", SENTENCE_SEPARATORS, Locale.ENGLISH);
+ checkCapitalize("Test&retest", "Test&Retest", SENTENCE_SEPARATORS, Locale.ENGLISH);
+ checkCapitalize("test&Retest", "Test&Retest", SENTENCE_SEPARATORS, Locale.ENGLISH);
checkCapitalize("rest\nrecreation! And in the end...",
- "Rest\nRecreation! And In The End...", " \n.!?*,();&", Locale.ENGLISH);
+ "Rest\nRecreation! And In The End...", WORD_SEPARATORS, Locale.ENGLISH);
checkCapitalize("lorem ipsum dolor sit amet", "Lorem Ipsum Dolor Sit Amet",
- " \n.,!?*()&;", Locale.ENGLISH);
+ WORD_SEPARATORS, Locale.ENGLISH);
checkCapitalize("Lorem!Ipsum (Dolor) Sit * Amet", "Lorem!Ipsum (Dolor) Sit * Amet",
- " \n,.;!?*()&", Locale.ENGLISH);
+ WORD_SEPARATORS, Locale.ENGLISH);
checkCapitalize("Lorem!Ipsum (dolor) Sit * Amet", "Lorem!Ipsum (Dolor) Sit * Amet",
- " \n,.;!?*()&", Locale.ENGLISH);
+ WORD_SEPARATORS, Locale.ENGLISH);
}
public void testLooksLikeURL() {
@@ -271,11 +285,25 @@ public class StringUtilsTests extends AndroidTestCase {
assertTrue(bytesStr.equals(bytesStr2));
}
- public void testJsonStringUtils() {
+ public void testContainsOnlyWhitespace() {
+ assertTrue(StringUtils.containsOnlyWhitespace(" "));
+ assertTrue(StringUtils.containsOnlyWhitespace(""));
+ assertTrue(StringUtils.containsOnlyWhitespace(" \n\t\t"));
+ // U+2002 : EN SPACE
+ // U+2003 : EM SPACE
+ // U+3000 : IDEOGRAPHIC SPACE (commonly "double-width space")
+ assertTrue(StringUtils.containsOnlyWhitespace("\u2002\u2003\u3000"));
+ assertFalse(StringUtils.containsOnlyWhitespace(" a "));
+ assertFalse(StringUtils.containsOnlyWhitespace(". "));
+ assertFalse(StringUtils.containsOnlyWhitespace("."));
+ assertTrue(StringUtils.containsOnlyWhitespace(""));
+ }
+
+ public void testJsonUtils() {
final Object[] objs = new Object[] { 1, "aaa", "bbb", 3 };
final List<Object> objArray = Arrays.asList(objs);
- final String str = StringUtils.listToJsonStr(objArray);
- final List<Object> newObjArray = StringUtils.jsonStrToList(str);
+ final String str = JsonUtils.listToJsonStr(objArray);
+ final List<Object> newObjArray = JsonUtils.jsonStrToList(str);
for (int i = 0; i < objs.length; ++i) {
assertEquals(objs[i], newObjArray.get(i));
}
diff --git a/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java
index 856b2dbda..25f57eba6 100644
--- a/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java
@@ -20,9 +20,9 @@ import android.content.Context;
import android.content.res.Resources;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;
-import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.RichInputMethodManager;
import java.util.ArrayList;
@@ -30,7 +30,7 @@ import java.util.Locale;
@SmallTest
public class SubtypeLocaleUtilsTests extends AndroidTestCase {
- // Locale to subtypes list.
+ // All input method subtypes of LatinIME.
private final ArrayList<InputMethodSubtype> mSubtypesList = CollectionUtils.newArrayList();
private RichInputMethodManager mRichImm;
@@ -41,7 +41,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
InputMethodSubtype ES_US;
InputMethodSubtype FR;
InputMethodSubtype FR_CA;
+ InputMethodSubtype FR_CH;
InputMethodSubtype DE;
+ InputMethodSubtype DE_CH;
InputMethodSubtype ZZ;
InputMethodSubtype DE_QWERTY;
InputMethodSubtype FR_QWERTZ;
@@ -60,6 +62,13 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
mRes = context.getResources();
SubtypeLocaleUtils.init(context);
+ final InputMethodInfo imi = mRichImm.getInputMethodInfoOfThisIme();
+ final int subtypeCount = imi.getSubtypeCount();
+ for (int index = 0; index < subtypeCount; index++) {
+ final InputMethodSubtype subtype = imi.getSubtypeAt(index);
+ mSubtypesList.add(subtype);
+ }
+
EN_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
Locale.US.toString(), "qwerty");
EN_GB = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
@@ -70,8 +79,12 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
Locale.FRENCH.toString(), "azerty");
FR_CA = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
Locale.CANADA_FRENCH.toString(), "qwerty");
+ FR_CH = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ "fr_CH", "swiss");
DE = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
Locale.GERMAN.toString(), "qwertz");
+ DE_CH = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ "de_CH", "swiss");
ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
SubtypeLocaleUtils.NO_LANGUAGE, "qwerty");
DE_QWERTY = AdditionalSubtypeUtils.createAdditionalSubtype(
@@ -88,19 +101,19 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
SubtypeLocaleUtils.NO_LANGUAGE, "azerty", null);
ZZ_PC = AdditionalSubtypeUtils.createAdditionalSubtype(
SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty", null);
-
}
public void testAllFullDisplayName() {
for (final InputMethodSubtype subtype : mSubtypesList) {
- final String subtypeName =
- SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype);
+ final String subtypeName = SubtypeLocaleUtils
+ .getSubtypeDisplayNameInSystemLocale(subtype);
if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
- final String noLanguage = mRes.getString(R.string.subtype_no_language);
- assertTrue(subtypeName, subtypeName.contains(noLanguage));
+ final String layoutName = SubtypeLocaleUtils
+ .getKeyboardLayoutSetDisplayName(subtype);
+ assertTrue(subtypeName, subtypeName.contains(layoutName));
} else {
- final String languageName =
- SubtypeLocaleUtils.getSubtypeLocaleDisplayName(subtype.getLocale());
+ final String languageName = SubtypeLocaleUtils
+ .getSubtypeLocaleDisplayNameInSystemLocale(subtype.getLocale());
assertTrue(subtypeName, subtypeName.contains(languageName));
}
}
@@ -112,7 +125,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
assertEquals("es_US", "spanish", SubtypeLocaleUtils.getKeyboardLayoutSetName(ES_US));
assertEquals("fr ", "azerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR));
assertEquals("fr_CA", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR_CA));
+ assertEquals("fr_CH", "swiss", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR_CH));
assertEquals("de ", "qwertz", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE));
+ assertEquals("de_CH", "swiss", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE_CH));
assertEquals("zz ", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(ZZ));
}
@@ -125,7 +140,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
// es_US spanish F Spanish (US) exception
// fr azerty F French
// fr_CA qwerty F French (Canada)
+ // fr_CH swiss F French (Switzerland)
// de qwertz F German
+ // de_CH swiss F German (Switzerland)
// zz qwerty F Alphabet (QWERTY)
// fr qwertz T French (QWERTZ)
// de qwerty T German (QWERTY)
@@ -148,8 +165,12 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR));
assertEquals("fr_CA", "French (Canada)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CA));
+ assertEquals("fr_CH", "French (Switzerland)",
+ SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CH));
assertEquals("de ", "German",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE));
+ assertEquals("de_CH", "German (Switzerland)",
+ SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_CH));
assertEquals("zz ", "Alphabet (QWERTY)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ));
return null;
@@ -189,7 +210,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
// es_US spanish F Espagnol (États-Unis) exception
// fr azerty F Français
// fr_CA qwerty F Français (Canada)
+ // fr_CH swiss F Français (Suisse)
// de qwertz F Allemand
+ // de_CH swiss F Allemand (Suisse)
// zz qwerty F Aucune langue (QWERTY)
// fr qwertz T Français (QWERTZ)
// de qwerty T Allemand (QWERTY)
@@ -212,8 +235,12 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR));
assertEquals("fr_CA", "Français (Canada)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CA));
+ assertEquals("fr_CH", "Français (Suisse)",
+ SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CH));
assertEquals("de ", "Allemand",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE));
+ assertEquals("de_CH", "Allemand (Suisse)",
+ SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_CH));
assertEquals("zz ", "Alphabet latin (QWERTY)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ));
return null;
@@ -246,11 +273,11 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
public void testAllFullDisplayNameForSpacebar() {
for (final InputMethodSubtype subtype : mSubtypesList) {
- final String subtypeName =
- SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype);
+ final String subtypeName = SubtypeLocaleUtils
+ .getSubtypeDisplayNameInSystemLocale(subtype);
final String spacebarText = SubtypeLocaleUtils.getFullDisplayName(subtype);
- final String languageName =
- SubtypeLocaleUtils.getSubtypeLocaleDisplayName(subtype.getLocale());
+ final String languageName = SubtypeLocaleUtils
+ .getSubtypeLocaleDisplayName(subtype.getLocale());
if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
assertFalse(subtypeName, spacebarText.contains(languageName));
} else {
@@ -261,15 +288,16 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
public void testAllMiddleDisplayNameForSpacebar() {
for (final InputMethodSubtype subtype : mSubtypesList) {
- final String subtypeName =
- SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype);
+ final String subtypeName = SubtypeLocaleUtils
+ .getSubtypeDisplayNameInSystemLocale(subtype);
final String spacebarText = SubtypeLocaleUtils.getMiddleDisplayName(subtype);
if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
assertEquals(subtypeName,
- SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype), spacebarText);
+ SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype), spacebarText);
} else {
+ final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
assertEquals(subtypeName,
- SubtypeLocaleUtils.getSubtypeLocaleDisplayName(subtype.getLocale()),
+ SubtypeLocaleUtils.getSubtypeLocaleDisplayName(locale.getLanguage()),
spacebarText);
}
}
@@ -277,8 +305,8 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
public void testAllShortDisplayNameForSpacebar() {
for (final InputMethodSubtype subtype : mSubtypesList) {
- final String subtypeName =
- SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype);
+ final String subtypeName = SubtypeLocaleUtils
+ .getSubtypeDisplayNameInSystemLocale(subtype);
final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
final String spacebarText = SubtypeLocaleUtils.getShortDisplayName(subtype);
final String languageCode = StringUtils.capitalizeFirstCodePoint(
@@ -300,7 +328,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
// es_US spanish F Es Español Español (EE.UU.) exception
// fr azerty F Fr Français Français
// fr_CA qwerty F Fr Français Français (Canada)
+ // fr_CH swiss F Fr Français Français (Suisse)
// de qwertz F De Deutsch Deutsch
+ // de_CH swiss F De Deutsch Deutsch (Schweiz)
// zz qwerty F QWERTY QWERTY
// fr qwertz T Fr Français Français
// de qwerty T De Deutsch Deutsch
@@ -317,7 +347,11 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
assertEquals("fr ", "Français", SubtypeLocaleUtils.getFullDisplayName(FR));
assertEquals("fr_CA", "Français (Canada)",
SubtypeLocaleUtils.getFullDisplayName(FR_CA));
+ assertEquals("fr_CH", "Français (Suisse)",
+ SubtypeLocaleUtils.getFullDisplayName(FR_CH));
assertEquals("de ", "Deutsch", SubtypeLocaleUtils.getFullDisplayName(DE));
+ assertEquals("de_CH", "Deutsch (Schweiz)",
+ SubtypeLocaleUtils.getFullDisplayName(DE_CH));
assertEquals("zz ", "QWERTY", SubtypeLocaleUtils.getFullDisplayName(ZZ));
assertEquals("en_US", "English", SubtypeLocaleUtils.getMiddleDisplayName(EN_US));
@@ -325,7 +359,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
assertEquals("es_US", "Español", SubtypeLocaleUtils.getMiddleDisplayName(ES_US));
assertEquals("fr ", "Français", SubtypeLocaleUtils.getMiddleDisplayName(FR));
assertEquals("fr_CA", "Français", SubtypeLocaleUtils.getMiddleDisplayName(FR_CA));
+ assertEquals("fr_CH", "Français", SubtypeLocaleUtils.getMiddleDisplayName(FR_CH));
assertEquals("de ", "Deutsch", SubtypeLocaleUtils.getMiddleDisplayName(DE));
+ assertEquals("de_CH", "Deutsch", SubtypeLocaleUtils.getMiddleDisplayName(DE_CH));
assertEquals("zz ", "QWERTY", SubtypeLocaleUtils.getMiddleDisplayName(ZZ));
assertEquals("en_US", "En", SubtypeLocaleUtils.getShortDisplayName(EN_US));
@@ -333,7 +369,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
assertEquals("es_US", "Es", SubtypeLocaleUtils.getShortDisplayName(ES_US));
assertEquals("fr ", "Fr", SubtypeLocaleUtils.getShortDisplayName(FR));
assertEquals("fr_CA", "Fr", SubtypeLocaleUtils.getShortDisplayName(FR_CA));
+ assertEquals("fr_CH", "Fr", SubtypeLocaleUtils.getShortDisplayName(FR_CH));
assertEquals("de ", "De", SubtypeLocaleUtils.getShortDisplayName(DE));
+ assertEquals("de_CH", "De", SubtypeLocaleUtils.getShortDisplayName(DE_CH));
assertEquals("zz ", "", SubtypeLocaleUtils.getShortDisplayName(ZZ));
return null;
}
@@ -384,4 +422,27 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
public void testAdditionalSubtypeForSpacebarInFrench() {
testsAdditionalSubtypesForSpacebar.runInLocale(mRes, Locale.FRENCH);
}
+
+ public void testIsRtlLanguage() {
+ // Known Right-to-Left language subtypes.
+ final InputMethodSubtype ARABIC = mRichImm
+ .findSubtypeByLocaleAndKeyboardLayoutSet("ar", "arabic");
+ assertNotNull("Arabic", ARABIC);
+ final InputMethodSubtype FARSI = mRichImm
+ .findSubtypeByLocaleAndKeyboardLayoutSet("fa", "farsi");
+ assertNotNull("Farsi", FARSI);
+ final InputMethodSubtype HEBREW = mRichImm
+ .findSubtypeByLocaleAndKeyboardLayoutSet("iw", "hebrew");
+ assertNotNull("Hebrew", HEBREW);
+
+ for (final InputMethodSubtype subtype : mSubtypesList) {
+ final String subtypeName = SubtypeLocaleUtils
+ .getSubtypeDisplayNameInSystemLocale(subtype);
+ if (subtype.equals(ARABIC) || subtype.equals(FARSI) || subtype.equals(HEBREW)) {
+ assertTrue(subtypeName, SubtypeLocaleUtils.isRtlLanguage(subtype));
+ } else {
+ assertFalse(subtypeName, SubtypeLocaleUtils.isRtlLanguage(subtype));
+ }
+ }
+ }
}
diff --git a/tests/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtilsTests.java
deleted file mode 100644
index 1944fd332..000000000
--- a/tests/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtilsTests.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2012 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.latin.utils;
-
-import android.content.Context;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-
-import com.android.inputmethod.latin.makedict.DictDecoder;
-import com.android.inputmethod.latin.makedict.DictEncoder;
-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.Ver3DictDecoder;
-import com.android.inputmethod.latin.makedict.Ver3DictEncoder;
-import com.android.inputmethod.latin.personalization.UserHistoryDictionaryBigramList;
-import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils.BigramDictionaryInterface;
-import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils.OnAddWordListener;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-
-/**
- * Unit tests for UserHistoryDictIOUtils
- */
-@LargeTest
-public class UserHistoryDictIOUtilsTests extends AndroidTestCase
- implements BigramDictionaryInterface {
-
- private static final String TAG = UserHistoryDictIOUtilsTests.class.getSimpleName();
- private static final int UNIGRAM_FREQUENCY = 50;
- private static final int BIGRAM_FREQUENCY = 100;
- private static final ArrayList<String> NOT_HAVE_BIGRAM = new ArrayList<String>();
- private static final FormatSpec.FormatOptions FORMAT_OPTIONS = new FormatSpec.FormatOptions(2);
- private static final String TEST_DICT_FILE_EXTENSION = ".testDict";
-
- /**
- * Return same frequency for all words and bigrams
- */
- @Override
- public int getFrequency(String word1, String word2) {
- if (word1 == null) return UNIGRAM_FREQUENCY;
- return BIGRAM_FREQUENCY;
- }
-
- // Utilities for Testing
-
- private void addWord(final String word,
- final HashMap<String, ArrayList<String> > addedWords) {
- if (!addedWords.containsKey(word)) {
- addedWords.put(word, new ArrayList<String>());
- }
- }
-
- private void addBigram(final String word1, final String word2,
- final HashMap<String, ArrayList<String> > addedWords) {
- addWord(word1, addedWords);
- addWord(word2, addedWords);
- addedWords.get(word1).add(word2);
- }
-
- private void addBigramToBigramList(final String word1, final String word2,
- final HashMap<String, ArrayList<String> > addedWords,
- final UserHistoryDictionaryBigramList bigramList) {
- bigramList.addBigram(null, word1);
- bigramList.addBigram(word1, word2);
-
- addBigram(word1, word2, addedWords);
- }
-
- private void checkWordInFusionDict(final FusionDictionary dict, final String word,
- final ArrayList<String> expectedBigrams) {
- final PtNode ptNode = FusionDictionary.findWordInTree(dict.mRootNodeArray, word);
- assertNotNull(ptNode);
- assertTrue(ptNode.isTerminal());
-
- for (final String bigram : expectedBigrams) {
- assertNotNull(ptNode.getBigram(bigram));
- }
- }
-
- private void checkWordsInFusionDict(final FusionDictionary dict,
- final HashMap<String, ArrayList<String> > bigrams) {
- for (final String word : bigrams.keySet()) {
- if (bigrams.containsKey(word)) {
- checkWordInFusionDict(dict, word, bigrams.get(word));
- } else {
- checkWordInFusionDict(dict, word, NOT_HAVE_BIGRAM);
- }
- }
- }
-
- private void checkWordInBigramList(
- final UserHistoryDictionaryBigramList bigramList, final String word,
- final ArrayList<String> expectedBigrams) {
- // check unigram
- final HashMap<String,Byte> unigramMap = bigramList.getBigrams(null);
- assertTrue(unigramMap.containsKey(word));
-
- // check bigrams
- final ArrayList<String> actualBigrams = new ArrayList<String>(
- bigramList.getBigrams(word).keySet());
-
- Collections.sort(expectedBigrams);
- Collections.sort(actualBigrams);
- assertEquals(expectedBigrams, actualBigrams);
- }
-
- private void checkWordsInBigramList(final UserHistoryDictionaryBigramList bigramList,
- final HashMap<String, ArrayList<String> > addedWords) {
- for (final String word : addedWords.keySet()) {
- if (addedWords.containsKey(word)) {
- checkWordInBigramList(bigramList, word, addedWords.get(word));
- } else {
- checkWordInBigramList(bigramList, word, NOT_HAVE_BIGRAM);
- }
- }
- }
-
- private void writeDictToFile(final File file,
- final UserHistoryDictionaryBigramList bigramList) {
- final DictEncoder dictEncoder = new Ver3DictEncoder(file);
- UserHistoryDictIOUtils.writeDictionary(dictEncoder, this, bigramList, FORMAT_OPTIONS);
- }
-
- private void readDictFromFile(final File file, final OnAddWordListener listener) {
- final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, DictDecoder.USE_BYTEARRAY);
- try {
- dictDecoder.openDictBuffer();
- } catch (FileNotFoundException e) {
- Log.e(TAG, "file not found", e);
- } catch (IOException e) {
- Log.e(TAG, "IOException", e);
- }
- UserHistoryDictIOUtils.readDictionaryBinary(dictDecoder, listener);
- }
-
- public void testGenerateFusionDictionary() {
- final UserHistoryDictionaryBigramList originalList = new UserHistoryDictionaryBigramList();
-
- final HashMap<String, ArrayList<String> > addedWords =
- new HashMap<String, ArrayList<String>>();
- addBigramToBigramList("this", "is", addedWords, originalList);
- addBigramToBigramList("this", "was", addedWords, originalList);
- addBigramToBigramList("hello", "world", addedWords, originalList);
-
- final FusionDictionary fusionDict =
- UserHistoryDictIOUtils.constructFusionDictionary(this, originalList);
-
- checkWordsInFusionDict(fusionDict, addedWords);
- }
-
- public void testReadAndWrite() {
- final Context context = getContext();
-
- File file = null;
- try {
- file = File.createTempFile("testReadAndWrite", TEST_DICT_FILE_EXTENSION,
- getContext().getCacheDir());
- } catch (IOException e) {
- Log.d(TAG, "IOException while creating a temporary file", e);
- }
- assertNotNull(file);
-
- // make original dictionary
- final UserHistoryDictionaryBigramList originalList = new UserHistoryDictionaryBigramList();
- final HashMap<String, ArrayList<String>> addedWords = CollectionUtils.newHashMap();
- addBigramToBigramList("this" , "is" , addedWords, originalList);
- addBigramToBigramList("this" , "was" , addedWords, originalList);
- addBigramToBigramList("is" , "not" , addedWords, originalList);
- addBigramToBigramList("hello", "world", addedWords, originalList);
-
- // write to file
- writeDictToFile(file, originalList);
-
- // make result dict.
- final UserHistoryDictionaryBigramList resultList = new UserHistoryDictionaryBigramList();
- final OnAddWordListener listener = new OnAddWordListener() {
- @Override
- public void setUnigram(final String word, final String shortcutTarget,
- final int frequency, final int shortcutFreq) {
- Log.d(TAG, "in: setUnigram: " + word + "," + frequency);
- resultList.addBigram(null, word, (byte)frequency);
- }
- @Override
- public void setBigram(final String word1, final String word2, final int frequency) {
- Log.d(TAG, "in: setBigram: " + word1 + "," + word2 + "," + frequency);
- resultList.addBigram(word1, word2, (byte)frequency);
- }
- };
-
- // load from file
- readDictFromFile(file, listener);
- checkWordsInBigramList(resultList, addedWords);
-
- // add new bigram
- addBigramToBigramList("hello", "java", addedWords, resultList);
-
- // rewrite
- writeDictToFile(file, resultList);
- final UserHistoryDictionaryBigramList resultList2 = new UserHistoryDictionaryBigramList();
- final OnAddWordListener listener2 = new OnAddWordListener() {
- @Override
- public void setUnigram(final String word, final String shortcutTarget,
- final int frequency, final int shortcutFreq) {
- Log.d(TAG, "in: setUnigram: " + word + "," + frequency);
- resultList2.addBigram(null, word, (byte)frequency);
- }
- @Override
- public void setBigram(final String word1, final String word2, final int frequency) {
- Log.d(TAG, "in: setBigram: " + word1 + "," + word2 + "," + frequency);
- resultList2.addBigram(word1, word2, (byte)frequency);
- }
- };
-
- // load from file
- readDictFromFile(file, listener2);
- checkWordsInBigramList(resultList2, addedWords);
- }
-}