diff options
Diffstat (limited to 'tests/src')
287 files changed, 9826 insertions, 8441 deletions
diff --git a/tests/src/com/android/inputmethod/compat/LocaleSpanCompatUtilsTests.java b/tests/src/com/android/inputmethod/compat/LocaleSpanCompatUtilsTests.java index 319302c71..67e76464b 100644 --- a/tests/src/com/android/inputmethod/compat/LocaleSpanCompatUtilsTests.java +++ b/tests/src/com/android/inputmethod/compat/LocaleSpanCompatUtilsTests.java @@ -20,7 +20,6 @@ import android.graphics.Typeface; import android.os.Build; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; -import android.text.Spannable; import android.text.SpannableString; import android.text.Spanned; import android.text.style.StyleSpan; @@ -72,141 +71,141 @@ public class LocaleSpanCompatUtilsTests extends AndroidTestCase { final SpannableString text = new SpannableString("0123456789"); LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 5, Locale.JAPANESE); assertSpanCount(1, text); - assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } // Test if only LocaleSpans are updated. { final SpannableString text = new SpannableString("0123456789"); final StyleSpan styleSpan = new StyleSpan(Typeface.BOLD); - text.setSpan(styleSpan, 0, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + text.setSpan(styleSpan, 0, 7, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 5, Locale.JAPANESE); assertSpanCount(2, text); assertSpanEquals(styleSpan, text, 0); - assertLocaleSpan(text, 1, 1, 5, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 1, 1, 5, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } // Test if two jointed spans are merged into one span. { final SpannableString text = new SpannableString("0123456789"); text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 3, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 5, Locale.JAPANESE); assertSpanCount(1, text); - assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } // Test if two overlapped spans are merged into one span. { final SpannableString text = new SpannableString("0123456789"); text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 4, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 5, Locale.JAPANESE); assertSpanCount(1, text); - assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } // Test if three overlapped spans are merged into one span. { final SpannableString text = new SpannableString("0123456789"); text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 4, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 5, 6, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); LocaleSpanCompatUtils.updateLocaleSpan(text, 2, 8, Locale.JAPANESE); assertSpanCount(1, text); - assertLocaleSpan(text, 0, 1, 8, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 0, 1, 8, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } // Test if disjoint spans remain disjoint. { final SpannableString text = new SpannableString("0123456789"); text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 3, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 5, 6, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); LocaleSpanCompatUtils.updateLocaleSpan(text, 8, 9, Locale.JAPANESE); assertSpanCount(3, text); - assertLocaleSpan(text, 0, 1, 3, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - assertLocaleSpan(text, 1, 5, 6, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - assertLocaleSpan(text, 2, 8, 9, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 0, 1, 3, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 1, 5, 6, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 2, 8, 9, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } // Test if existing span flags are preserved during merge. { final SpannableString text = new SpannableString("0123456789"); text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 5, - Spannable.SPAN_INCLUSIVE_INCLUSIVE | Spannable.SPAN_INTERMEDIATE); + Spanned.SPAN_INCLUSIVE_INCLUSIVE | Spanned.SPAN_INTERMEDIATE); LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 4, Locale.JAPANESE); assertSpanCount(1, text); assertLocaleSpan(text, 0, 1, 5, Locale.JAPANESE, - Spannable.SPAN_INCLUSIVE_INCLUSIVE | Spannable.SPAN_INTERMEDIATE); + Spanned.SPAN_INCLUSIVE_INCLUSIVE | Spanned.SPAN_INTERMEDIATE); } // Test if existing span flags are preserved even when partially overlapped (leading edge). { final SpannableString text = new SpannableString("0123456789"); text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 1, 5, - Spannable.SPAN_INCLUSIVE_INCLUSIVE | Spannable.SPAN_INTERMEDIATE); + Spanned.SPAN_INCLUSIVE_INCLUSIVE | Spanned.SPAN_INTERMEDIATE); LocaleSpanCompatUtils.updateLocaleSpan(text, 3, 7, Locale.JAPANESE); assertSpanCount(1, text); assertLocaleSpan(text, 0, 1, 7, Locale.JAPANESE, - Spannable.SPAN_INCLUSIVE_EXCLUSIVE | Spannable.SPAN_INTERMEDIATE); + Spanned.SPAN_INCLUSIVE_EXCLUSIVE | Spanned.SPAN_INTERMEDIATE); } // Test if existing span flags are preserved even when partially overlapped (trailing edge). { final SpannableString text = new SpannableString("0123456789"); text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.JAPANESE), 3, 7, - Spannable.SPAN_INCLUSIVE_INCLUSIVE | Spannable.SPAN_INTERMEDIATE); + Spanned.SPAN_INCLUSIVE_INCLUSIVE | Spanned.SPAN_INTERMEDIATE); LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 5, Locale.JAPANESE); assertSpanCount(1, text); assertLocaleSpan(text, 0, 1, 7, Locale.JAPANESE, - Spannable.SPAN_EXCLUSIVE_INCLUSIVE | Spannable.SPAN_INTERMEDIATE); + Spanned.SPAN_EXCLUSIVE_INCLUSIVE | Spanned.SPAN_INTERMEDIATE); } // Test if existing locale span will be removed when the locale doesn't match. { final SpannableString text = new SpannableString("0123456789"); text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 5, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); LocaleSpanCompatUtils.updateLocaleSpan(text, 1, 7, Locale.JAPANESE); assertSpanCount(1, text); - assertLocaleSpan(text, 0, 1, 7, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 0, 1, 7, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } // Test if existing locale span will be removed when the locale doesn't match. (case 2) { final SpannableString text = new SpannableString("0123456789"); text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 7, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); LocaleSpanCompatUtils.updateLocaleSpan(text, 5, 6, Locale.JAPANESE); assertSpanCount(3, text); - assertLocaleSpan(text, 0, 3, 5, Locale.ENGLISH, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - assertLocaleSpan(text, 1, 6, 7, Locale.ENGLISH, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - assertLocaleSpan(text, 2, 5, 6, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 0, 3, 5, Locale.ENGLISH, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 1, 6, 7, Locale.ENGLISH, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 2, 5, 6, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } // Test if existing locale span will be removed when the locale doesn't match. (case 3) { final SpannableString text = new SpannableString("0123456789"); text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 7, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); LocaleSpanCompatUtils.updateLocaleSpan(text, 2, 5, Locale.JAPANESE); assertSpanCount(2, text); - assertLocaleSpan(text, 0, 5, 7, Locale.ENGLISH, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - assertLocaleSpan(text, 1, 2, 5, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 0, 5, 7, Locale.ENGLISH, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 1, 2, 5, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } // Test if existing locale span will be removed when the locale doesn't match. (case 3) { final SpannableString text = new SpannableString("0123456789"); text.setSpan(LocaleSpanCompatUtils.newLocaleSpan(Locale.ENGLISH), 3, 7, - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); LocaleSpanCompatUtils.updateLocaleSpan(text, 5, 8, Locale.JAPANESE); assertSpanCount(2, text); - assertLocaleSpan(text, 0, 3, 5, Locale.ENGLISH, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - assertLocaleSpan(text, 1, 5, 8, Locale.JAPANESE, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 0, 3, 5, Locale.ENGLISH, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + assertLocaleSpan(text, 1, 5, 8, Locale.JAPANESE, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } } diff --git a/tests/src/com/android/inputmethod/compat/SuggestionSpanUtilsTest.java b/tests/src/com/android/inputmethod/compat/SuggestionSpanUtilsTest.java new file mode 100644 index 000000000..daf412cc3 --- /dev/null +++ b/tests/src/com/android/inputmethod/compat/SuggestionSpanUtilsTest.java @@ -0,0 +1,212 @@ +/* + * 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.compat; + +import android.annotation.TargetApi; +import android.os.Build; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; +import android.text.Spanned; +import android.text.TextUtils; +import android.text.style.SuggestionSpan; + +import com.android.inputmethod.latin.SuggestedWords; +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Locale; + +@SmallTest +public class SuggestionSpanUtilsTest extends AndroidTestCase { + + /** + * Helper method to create a dummy {@link SuggestedWordInfo}. + * + * @param kindAndFlags the kind and flags to be used to create {@link SuggestedWordInfo}. + * @param word the word to be used to create {@link SuggestedWordInfo}. + * @return a new instance of {@link SuggestedWordInfo}. + */ + private static SuggestedWordInfo createWordInfo(final String word, final int kindAndFlags) { + return new SuggestedWordInfo(word, "" /* prevWordsContext */, 1 /* score */, kindAndFlags, + null /* sourceDict */, + SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, + SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */); + } + + private static void assertNotSuggestionSpan(final String expectedText, + final CharSequence actualText) { + assertTrue(TextUtils.equals(expectedText, actualText)); + if (!(actualText instanceof Spanned)) { + return; + } + final Spanned spanned = (Spanned)actualText; + final SuggestionSpan[] suggestionSpans = spanned.getSpans(0, spanned.length(), + SuggestionSpan.class); + assertEquals(0, suggestionSpans.length); + } + + private static void assertSuggestionSpan(final String expectedText, + final int reuiredSuggestionSpanFlags, final int requiredSpanFlags, + final String[] expectedSuggestions, + final CharSequence actualText) { + assertTrue(TextUtils.equals(expectedText, actualText)); + assertTrue(actualText instanceof Spanned); + final Spanned spanned = (Spanned)actualText; + final SuggestionSpan[] suggestionSpans = spanned.getSpans(0, spanned.length(), + SuggestionSpan.class); + assertEquals(1, suggestionSpans.length); + final SuggestionSpan suggestionSpan = suggestionSpans[0]; + if (reuiredSuggestionSpanFlags != 0) { + assertTrue((suggestionSpan.getFlags() & reuiredSuggestionSpanFlags) != 0); + } + if (requiredSpanFlags != 0) { + assertTrue((spanned.getSpanFlags(suggestionSpan) & requiredSpanFlags) != 0); + } + if (expectedSuggestions != null) { + final String[] actualSuggestions = suggestionSpan.getSuggestions(); + assertEquals(expectedSuggestions.length, actualSuggestions.length); + for (int i = 0; i < expectedSuggestions.length; ++i) { + assertEquals(expectedSuggestions[i], actualSuggestions[i]); + } + } + } + + @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) + public void testGetTextWithAutoCorrectionIndicatorUnderline() { + final String ORIGINAL_TEXT = "Hey!"; + final CharSequence text = SuggestionSpanUtils.getTextWithAutoCorrectionIndicatorUnderline( + getContext(), ORIGINAL_TEXT); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { + assertNotSuggestionSpan(ORIGINAL_TEXT, text); + return; + } + + assertSuggestionSpan(ORIGINAL_TEXT, + SuggestionSpan.FLAG_AUTO_CORRECTION /* reuiredSuggestionSpanFlags */, + Spanned.SPAN_COMPOSING | Spanned.SPAN_EXCLUSIVE_EXCLUSIVE /* requiredSpanFlags */, + new String[]{}, text); + } + + public void testGetTextWithSuggestionSpan() { + final SuggestedWordInfo prediction1 = + createWordInfo("Quality", SuggestedWordInfo.KIND_PREDICTION); + final SuggestedWordInfo prediction2 = + createWordInfo("Speed", SuggestedWordInfo.KIND_PREDICTION); + final SuggestedWordInfo prediction3 = + createWordInfo("Price", SuggestedWordInfo.KIND_PREDICTION); + + final SuggestedWordInfo typed = + createWordInfo("Hey", SuggestedWordInfo.KIND_TYPED); + + final SuggestedWordInfo[] corrections = + new SuggestedWordInfo[SuggestionSpan.SUGGESTIONS_MAX_SIZE * 2]; + for (int i = 0; i < corrections.length; ++i) { + corrections[i] = createWordInfo("correction" + i, SuggestedWordInfo.KIND_CORRECTION); + } + + // SuggestionSpan will not be attached when {@link SuggestedWords#INPUT_STYLE_PREDICTION} + // is specified. + { + final SuggestedWords predictedWords = new SuggestedWords( + new ArrayList<>(Arrays.asList(prediction1, prediction2, prediction3)), + null /* rawSuggestions */, + null /* typedWord */, + false /* typedWordValid */, + false /* willAutoCorrect */, + false /* isObsoleteSuggestions */, + SuggestedWords.INPUT_STYLE_PREDICTION, + SuggestedWords.NOT_A_SEQUENCE_NUMBER); + final String PICKED_WORD = prediction2.mWord; + assertNotSuggestionSpan( + PICKED_WORD, + SuggestionSpanUtils.getTextWithSuggestionSpan(getContext(), PICKED_WORD, + predictedWords)); + } + + final ArrayList<SuggestedWordInfo> suggestedWordList = new ArrayList<>(); + suggestedWordList.add(typed); + suggestedWordList.add(prediction1); + suggestedWordList.add(prediction2); + suggestedWordList.add(prediction3); + suggestedWordList.addAll(Arrays.asList(corrections)); + final SuggestedWords typedAndCollectedWords = new SuggestedWords( + suggestedWordList, + null /* rawSuggestions */, + null /* typedWord */, + false /* typedWordValid */, + false /* willAutoCorrect */, + false /* isObsoleteSuggestions */, + SuggestedWords.INPUT_STYLE_TYPING, + SuggestedWords.NOT_A_SEQUENCE_NUMBER); + + for (final SuggestedWordInfo pickedWord : suggestedWordList) { + final String PICKED_WORD = pickedWord.mWord; + + final ArrayList<String> expectedSuggestions = new ArrayList<>(); + for (SuggestedWordInfo suggestedWordInfo : suggestedWordList) { + if (expectedSuggestions.size() >= SuggestionSpan.SUGGESTIONS_MAX_SIZE) { + break; + } + if (suggestedWordInfo.isKindOf(SuggestedWordInfo.KIND_PREDICTION)) { + // Currently predictions are not filled into SuggestionSpan. + continue; + } + final String suggestedWord = suggestedWordInfo.mWord; + if (TextUtils.equals(PICKED_WORD, suggestedWord)) { + // Typed word itself is not added to SuggestionSpan. + continue; + } + expectedSuggestions.add(suggestedWord); + } + + assertSuggestionSpan( + PICKED_WORD, + 0 /* reuiredSuggestionSpanFlags */, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE /* requiredSpanFlags */, + expectedSuggestions.toArray(new String[expectedSuggestions.size()]), + SuggestionSpanUtils.getTextWithSuggestionSpan(getContext(), PICKED_WORD, + typedAndCollectedWords)); + } + } + + public void testFindFirstLocaleFromSuggestionSpans() { + final String[] suggestions = new String[] {"Quality", "Speed", "Price"}; + final SuggestionSpan nullLocaleSpan = new SuggestionSpan((Locale)null, suggestions, 0); + final SuggestionSpan emptyLocaleSpan = new SuggestionSpan(new Locale(""), suggestions, 0); + final SuggestionSpan enUsLocaleSpan = new SuggestionSpan(Locale.US, suggestions, 0); + final SuggestionSpan jaJpLocaleSpan = new SuggestionSpan(Locale.JAPAN, suggestions, 0); + + assertEquals(null, SuggestionSpanUtils.findFirstLocaleFromSuggestionSpans( + new SuggestionSpan[] {})); + + assertEquals(null, SuggestionSpanUtils.findFirstLocaleFromSuggestionSpans( + new SuggestionSpan[] {emptyLocaleSpan})); + + assertEquals(Locale.US, SuggestionSpanUtils.findFirstLocaleFromSuggestionSpans( + new SuggestionSpan[] {enUsLocaleSpan})); + + assertEquals(Locale.US, SuggestionSpanUtils.findFirstLocaleFromSuggestionSpans( + new SuggestionSpan[] {nullLocaleSpan, enUsLocaleSpan})); + + assertEquals(Locale.US, SuggestionSpanUtils.findFirstLocaleFromSuggestionSpans( + new SuggestionSpan[] {nullLocaleSpan, emptyLocaleSpan, enUsLocaleSpan})); + + assertEquals(Locale.JAPAN, SuggestionSpanUtils.findFirstLocaleFromSuggestionSpans( + new SuggestionSpan[] {nullLocaleSpan, jaJpLocaleSpan, enUsLocaleSpan})); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelBase.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelBase.java deleted file mode 100644 index a25d6d6e7..000000000 --- a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelBase.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * 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; - -import android.content.res.Resources; -import android.text.InputType; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodSubtype; - -import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; -import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.utils.RunInLocale; -import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; - -import java.util.Locale; - -abstract class KeyboardLayoutSetActionLabelBase extends KeyboardLayoutSetTestsBase { - public void testActionUnspecified() { - for (final InputMethodSubtype subtype : getAllSubtypesList()) { - final String tag = "unspecifiled " - + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); - doTestActionKeyIcon(tag, subtype, EditorInfo.IME_ACTION_UNSPECIFIED, - KeyboardIconsSet.NAME_ENTER_KEY); - } - } - - public void testActionNone() { - for (final InputMethodSubtype subtype : getAllSubtypesList()) { - final String tag = "none " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); - doTestActionKeyIcon(tag, subtype, EditorInfo.IME_ACTION_NONE, - KeyboardIconsSet.NAME_ENTER_KEY); - } - } - - public void testActionSearch() { - for (final InputMethodSubtype subtype : getAllSubtypesList()) { - final String tag = "search " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); - doTestActionKeyIcon(tag, subtype, EditorInfo.IME_ACTION_SEARCH, - KeyboardIconsSet.NAME_SEARCH_KEY); - } - } - - public abstract void testActionGo(); - public abstract void testActionSend(); - public abstract void testActionNext(); - public abstract void testActionDone(); - public abstract void testActionPrevious(); - - public void testActionCustom() { - for (final InputMethodSubtype subtype : getAllSubtypesList()) { - final String tag = "custom " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); - final CharSequence customLabel = "customLabel"; - final EditorInfo editorInfo = new EditorInfo(); - editorInfo.imeOptions = EditorInfo.IME_ACTION_UNSPECIFIED; - editorInfo.actionLabel = customLabel; - doTestActionKeyLabel(tag, subtype, editorInfo, customLabel); - } - } - - private static void doTestActionKey(final String tag, final KeyboardLayoutSet layoutSet, - final int elementId, final CharSequence label, final int iconId) { - final Keyboard keyboard = layoutSet.getKeyboard(elementId); - final Key enterKey = keyboard.getKey(Constants.CODE_ENTER); - assertNotNull(tag + " enter key on " + keyboard.mId, enterKey); - assertEquals(tag + " enter label " + enterKey, label, enterKey.getLabel()); - assertEquals(tag + " enter icon " + enterKey, iconId, enterKey.getIconId()); - } - - protected void doTestActionKeyLabelResId(final String tag, final InputMethodSubtype subtype, - final int actionId, final int labelResId) { - final Locale labelLocale = subtype.getLocale().equals(SubtypeLocaleUtils.NO_LANGUAGE) - ? null : SubtypeLocaleUtils.getSubtypeLocale(subtype); - doTestActionKeyLabelResIdInLocale(tag, subtype, actionId, labelLocale, labelResId); - } - - protected void doTestActionKeyLabelResIdInLocale(final String tag, - final InputMethodSubtype subtype, final int actionId, final Locale labelLocale, - final int labelResId) { - final EditorInfo editorInfo = new EditorInfo(); - editorInfo.imeOptions = actionId; - final RunInLocale<String> job = new RunInLocale<String>() { - @Override - protected String job(final Resources res) { - return res.getString(labelResId); - } - }; - final String label = job.runInLocale(getContext().getResources(), labelLocale); - doTestActionKeyLabel(tag, subtype, editorInfo, label); - } - - protected void doTestActionKeyLabel(final String tag, final InputMethodSubtype subtype, - final EditorInfo editorInfo, final CharSequence label) { - // Test text layouts. - editorInfo.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL; - final KeyboardLayoutSet layoutSet = createKeyboardLayoutSet(subtype, editorInfo); - doTestActionKey(tag, layoutSet, KeyboardId.ELEMENT_ALPHABET, - label, KeyboardIconsSet.ICON_UNDEFINED); - doTestActionKey(tag, layoutSet, KeyboardId.ELEMENT_SYMBOLS, - label, KeyboardIconsSet.ICON_UNDEFINED); - doTestActionKey(tag, layoutSet, KeyboardId.ELEMENT_SYMBOLS_SHIFTED, - label, KeyboardIconsSet.ICON_UNDEFINED); - // Test phone number layouts. - doTestActionKey(tag, layoutSet, KeyboardId.ELEMENT_PHONE, - label, KeyboardIconsSet.ICON_UNDEFINED); - doTestActionKey(tag, layoutSet, KeyboardId.ELEMENT_PHONE_SYMBOLS, - label, KeyboardIconsSet.ICON_UNDEFINED); - // Test normal number layout. - doTestActionKey(tag, layoutSet, KeyboardId.ELEMENT_NUMBER, - label, KeyboardIconsSet.ICON_UNDEFINED); - // Test number password layouts. - editorInfo.inputType = - InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD; - final KeyboardLayoutSet passwordSet = createKeyboardLayoutSet(subtype, editorInfo); - doTestActionKey(tag, passwordSet, KeyboardId.ELEMENT_NUMBER, - label, KeyboardIconsSet.ICON_UNDEFINED); - } - - protected void doTestActionKeyIcon(final String tag, final InputMethodSubtype subtype, - final int actionId, final String iconName) { - final int iconId = KeyboardIconsSet.getIconId(iconName); - final EditorInfo editorInfo = new EditorInfo(); - editorInfo.imeOptions = actionId; - // Test text layouts. - editorInfo.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL; - final KeyboardLayoutSet layoutSet = createKeyboardLayoutSet(subtype, editorInfo); - doTestActionKey(tag, layoutSet, KeyboardId.ELEMENT_ALPHABET, null /* label */, iconId); - doTestActionKey(tag, layoutSet, KeyboardId.ELEMENT_SYMBOLS, null /* label */, iconId); - doTestActionKey( - tag, layoutSet, KeyboardId.ELEMENT_SYMBOLS_SHIFTED, null /* label */, iconId); - // Test phone number layouts. - doTestActionKey(tag, layoutSet, KeyboardId.ELEMENT_PHONE, null /* label */, iconId); - doTestActionKey( - tag, layoutSet, KeyboardId.ELEMENT_PHONE_SYMBOLS, null /* label */, iconId); - // Test normal number layout. - doTestActionKey(tag, layoutSet, KeyboardId.ELEMENT_NUMBER, null /* label */, iconId); - // Test number password layout. - editorInfo.inputType = - InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD; - final KeyboardLayoutSet passwordSet = createKeyboardLayoutSet(subtype, editorInfo); - doTestActionKey(tag, passwordSet, KeyboardId.ELEMENT_NUMBER, null /* label */, iconId); - } -} diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelKlpTests.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelKlpTests.java deleted file mode 100644 index 322a344ff..000000000 --- a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelKlpTests.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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; - -import android.content.res.Resources; -import android.test.suitebuilder.annotation.MediumTest; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodSubtype; - -import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; -import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.RichInputMethodManager; -import com.android.inputmethod.latin.utils.RunInLocale; -import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; - -import java.util.Locale; - -@MediumTest -public class KeyboardLayoutSetActionLabelKlpTests extends KeyboardLayoutSetActionLabelBase { - @Override - protected int getKeyboardThemeForTests() { - return KeyboardTheme.THEME_ID_KLP; - } - - @Override - public void testActionGo() { - for (final InputMethodSubtype subtype : getAllSubtypesList()) { - final String tag = "go " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); - doTestActionKeyLabelResId(tag, subtype, EditorInfo.IME_ACTION_GO, - R.string.label_go_key); - } - } - - @Override - public void testActionSend() { - for (final InputMethodSubtype subtype : getAllSubtypesList()) { - final String tag = "send " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); - doTestActionKeyLabelResId(tag, subtype, EditorInfo.IME_ACTION_SEND, - R.string.label_send_key); - } - } - - @Override - public void testActionNext() { - for (final InputMethodSubtype subtype : getAllSubtypesList()) { - final String tag = "next " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); - doTestActionKeyLabelResId(tag, subtype, EditorInfo.IME_ACTION_NEXT, - R.string.label_next_key); - } - } - - @Override - public void testActionDone() { - for (final InputMethodSubtype subtype : getAllSubtypesList()) { - final String tag = "done " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); - doTestActionKeyLabelResId(tag, subtype, EditorInfo.IME_ACTION_DONE, - R.string.label_done_key); - } - } - - @Override - public void testActionPrevious() { - for (final InputMethodSubtype subtype : getAllSubtypesList()) { - final String tag = "previous " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); - doTestActionKeyLabelResId(tag, subtype, EditorInfo.IME_ACTION_PREVIOUS, - R.string.label_previous_key); - } - } - - // Working variable to simulate system locale changing. - private Locale mSystemLocale = Locale.getDefault(); - - private void doTestActionLabelInLocale(final InputMethodSubtype subtype, - final Locale labelLocale, final Locale systemLocale) { - // Simulate system locale changing, see {@link SystemBroadcastReceiver}. - if (!systemLocale.equals(mSystemLocale)) { - KeyboardLayoutSet.onSystemLocaleChanged(); - mSystemLocale = systemLocale; - } - final String tag = "label=" + labelLocale + " system=" + systemLocale - + " " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); - final RunInLocale<Void> job = new RunInLocale<Void>() { - @Override - public Void job(final Resources res) { - doTestActionKeyIcon(tag + " unspecified", subtype, - EditorInfo.IME_ACTION_UNSPECIFIED, KeyboardIconsSet.NAME_ENTER_KEY); - doTestActionKeyIcon(tag + " none", subtype, - EditorInfo.IME_ACTION_NONE, KeyboardIconsSet.NAME_ENTER_KEY); - doTestActionKeyLabelResIdInLocale(tag + " go", subtype, - EditorInfo.IME_ACTION_GO, labelLocale, R.string.label_go_key); - doTestActionKeyIcon(tag + " search", subtype, - EditorInfo.IME_ACTION_SEARCH, KeyboardIconsSet.NAME_SEARCH_KEY); - doTestActionKeyLabelResIdInLocale(tag + " send", subtype, - EditorInfo.IME_ACTION_SEND, labelLocale, R.string.label_send_key); - doTestActionKeyLabelResIdInLocale(tag + " next", subtype, - EditorInfo.IME_ACTION_NEXT, labelLocale, R.string.label_next_key); - doTestActionKeyLabelResIdInLocale(tag + " done", subtype, - EditorInfo.IME_ACTION_DONE, labelLocale, R.string.label_done_key); - doTestActionKeyLabelResIdInLocale(tag + " previous", subtype, - EditorInfo.IME_ACTION_PREVIOUS, labelLocale, R.string.label_previous_key); - return null; - } - }; - job.runInLocale(getContext().getResources(), systemLocale); - } - - public void testActionLabelInOtherLocale() { - final RichInputMethodManager richImm = RichInputMethodManager.getInstance(); - final InputMethodSubtype italian = richImm.findSubtypeByLocaleAndKeyboardLayoutSet( - Locale.ITALIAN.toString(), SubtypeLocaleUtils.QWERTY); - // An action label should be displayed in subtype's locale regardless of the system locale. - doTestActionLabelInLocale(italian, Locale.ITALIAN, Locale.US); - doTestActionLabelInLocale(italian, Locale.ITALIAN, Locale.FRENCH); - doTestActionLabelInLocale(italian, Locale.ITALIAN, Locale.ITALIAN); - doTestActionLabelInLocale(italian, Locale.ITALIAN, Locale.JAPANESE); - } - - public void testNoLanguageSubtypeActionLabel() { - final RichInputMethodManager richImm = RichInputMethodManager.getInstance(); - final InputMethodSubtype noLanguage = richImm.findSubtypeByLocaleAndKeyboardLayoutSet( - SubtypeLocaleUtils.NO_LANGUAGE, SubtypeLocaleUtils.QWERTY); - // An action label of no language keyboard should be displayed in the system locale. - doTestActionLabelInLocale(noLanguage, Locale.US, Locale.US); - doTestActionLabelInLocale(noLanguage, Locale.FRENCH, Locale.FRENCH); - doTestActionLabelInLocale(noLanguage, Locale.ITALIAN, Locale.ITALIAN); - doTestActionLabelInLocale(noLanguage, Locale.JAPANESE, Locale.JAPANESE); - } -} diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelLxxTests.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelLxxTests.java deleted file mode 100644 index 028b3e400..000000000 --- a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelLxxTests.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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; - -import android.test.suitebuilder.annotation.MediumTest; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodSubtype; - -import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; -import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; - -@MediumTest -public class KeyboardLayoutSetActionLabelLxxTests extends KeyboardLayoutSetActionLabelBase { - @Override - protected int getKeyboardThemeForTests() { - return KeyboardTheme.THEME_ID_LXX_LIGHT; - } - - @Override - public void testActionGo() { - for (final InputMethodSubtype subtype : getAllSubtypesList()) { - final String tag = "go " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); - doTestActionKeyIcon(tag, subtype, EditorInfo.IME_ACTION_GO, - KeyboardIconsSet.NAME_GO_KEY); - } - } - - @Override - public void testActionSend() { - for (final InputMethodSubtype subtype : getAllSubtypesList()) { - final String tag = "send " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); - doTestActionKeyIcon(tag, subtype, EditorInfo.IME_ACTION_SEND, - KeyboardIconsSet.NAME_SEND_KEY); - } - } - - @Override - public void testActionNext() { - for (final InputMethodSubtype subtype : getAllSubtypesList()) { - final String tag = "next " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); - doTestActionKeyIcon(tag, subtype, EditorInfo.IME_ACTION_NEXT, - KeyboardIconsSet.NAME_NEXT_KEY); - } - } - - @Override - public void testActionDone() { - for (final InputMethodSubtype subtype : getAllSubtypesList()) { - final String tag = "done " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); - doTestActionKeyIcon(tag, subtype, EditorInfo.IME_ACTION_DONE, - KeyboardIconsSet.NAME_DONE_KEY); - } - } - - @Override - public void testActionPrevious() { - for (final InputMethodSubtype subtype : getAllSubtypesList()) { - final String tag = "previous " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); - doTestActionKeyIcon(tag, subtype, EditorInfo.IME_ACTION_PREVIOUS, - KeyboardIconsSet.NAME_PREVIOUS_KEY); - } - } -} diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetNavigateMoreKeysBase.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetNavigateMoreKeysBase.java index 8a55455d0..21333b0a0 100644 --- a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetNavigateMoreKeysBase.java +++ b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetNavigateMoreKeysBase.java @@ -22,9 +22,9 @@ import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; import com.android.inputmethod.keyboard.internal.MoreKeySpec; -import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.RichInputMethodManager; +import com.android.inputmethod.latin.common.Constants; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import java.util.Arrays; diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetTestsBase.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetTestsBase.java index a002bbe48..29787acc9 100644 --- a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetTestsBase.java +++ b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetTestsBase.java @@ -26,9 +26,11 @@ import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils; import com.android.inputmethod.keyboard.KeyboardLayoutSet.Builder; -import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.RichInputMethodManager; +import com.android.inputmethod.latin.RichInputMethodSubtype; +import com.android.inputmethod.latin.common.Constants; +import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; import com.android.inputmethod.latin.utils.ResourceUtils; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; @@ -39,9 +41,27 @@ import java.util.Locale; public abstract class KeyboardLayoutSetTestsBase extends AndroidTestCase { // All input method subtypes of LatinIME. private final ArrayList<InputMethodSubtype> mAllSubtypesList = new ArrayList<>(); - private final ArrayList<InputMethodSubtype> mAsciiCapableSubtypesList = new ArrayList<>(); - private final ArrayList<InputMethodSubtype> mAdditionalSubtypesList = new ArrayList<>(); + public interface SubtypeFilter { + public boolean accept(final InputMethodSubtype subtype); + } + + public static final SubtypeFilter FILTER_IS_ASCII_CAPABLE = new SubtypeFilter() { + @Override + public boolean accept(InputMethodSubtype subtype) { + return InputMethodSubtypeCompatUtils.isAsciiCapable(subtype); + } + }; + + public static final SubtypeFilter FILTER_IS_ADDITIONAL_SUBTYPE = new SubtypeFilter() { + @Override + public boolean accept(InputMethodSubtype subtype) { + return AdditionalSubtypeUtils.isAdditionalSubtype(subtype); + } + }; + + private RichInputMethodManager mRichImm; + private InputMethodSubtype[] mSavedAdditionalSubtypes; private int mScreenMetrics; protected abstract int getKeyboardThemeForTests(); @@ -49,46 +69,57 @@ public abstract class KeyboardLayoutSetTestsBase extends AndroidTestCase { @Override protected void setUp() throws Exception { super.setUp(); + final Context context = getContext(); + final Resources res = context.getResources(); + RichInputMethodManager.init(context); + mRichImm = RichInputMethodManager.getInstance(); + + // Save and reset additional subtypes preference. + mSavedAdditionalSubtypes = mRichImm.getAdditionalSubtypes(); + final InputMethodSubtype[] predefinedAdditionalSubtypes = + AdditionalSubtypeUtils.createAdditionalSubtypesArray( + AdditionalSubtypeUtils.createPrefSubtypes( + res.getStringArray(R.array.predefined_subtypes))); + mRichImm.setAdditionalInputMethodSubtypes(predefinedAdditionalSubtypes); + final KeyboardTheme keyboardTheme = KeyboardTheme.searchKeyboardThemeById( - getKeyboardThemeForTests()); + getKeyboardThemeForTests(), KeyboardTheme.KEYBOARD_THEMES); setContext(new ContextThemeWrapper(getContext(), keyboardTheme.mStyleId)); KeyboardLayoutSet.onKeyboardThemeChanged(); - final Context context = getContext(); - mScreenMetrics = context.getResources().getInteger(R.integer.config_screen_metrics); - RichInputMethodManager.init(context); - final RichInputMethodManager richImm = RichInputMethodManager.getInstance(); + mScreenMetrics = Settings.readScreenMetrics(res); - final InputMethodInfo imi = richImm.getInputMethodInfoOfThisIme(); + final InputMethodInfo imi = mRichImm.getInputMethodInfoOfThisIme(); final int subtypeCount = imi.getSubtypeCount(); for (int index = 0; index < subtypeCount; index++) { - final InputMethodSubtype subtype = imi.getSubtypeAt(index); - if (AdditionalSubtypeUtils.isAdditionalSubtype(subtype)) { - mAdditionalSubtypesList.add(subtype); - continue; - } - mAllSubtypesList.add(subtype); - if (InputMethodSubtypeCompatUtils.isAsciiCapable(subtype)) { - mAsciiCapableSubtypesList.add(subtype); - } + mAllSubtypesList.add(imi.getSubtypeAt(index)); } } - protected final ArrayList<InputMethodSubtype> getAllSubtypesList() { - return mAllSubtypesList; + @Override + protected void tearDown() throws Exception { + // Restore additional subtypes preference. + mRichImm.setAdditionalInputMethodSubtypes(mSavedAdditionalSubtypes); + super.tearDown(); } - protected final ArrayList<InputMethodSubtype> getAsciiCapableSubtypesList() { - return mAsciiCapableSubtypesList; + protected final ArrayList<InputMethodSubtype> getAllSubtypesList() { + return mAllSubtypesList; } - protected final ArrayList<InputMethodSubtype> getAdditionalSubtypesList() { - return mAdditionalSubtypesList; + protected final ArrayList<InputMethodSubtype> getSubtypesFilteredBy( + final SubtypeFilter filter) { + final ArrayList<InputMethodSubtype> list = new ArrayList<>(); + for (final InputMethodSubtype subtype : mAllSubtypesList) { + if (filter.accept(subtype)) { + list.add(subtype); + } + } + return list; } protected final boolean isPhone() { - return mScreenMetrics == Constants.SCREEN_METRICS_SMALL_PHONE - || mScreenMetrics == Constants.SCREEN_METRICS_LARGE_PHONE; + return Constants.isPhone(mScreenMetrics); } protected final InputMethodSubtype getSubtype(final Locale locale, @@ -101,7 +132,7 @@ public abstract class KeyboardLayoutSetTestsBase extends AndroidTestCase { return subtype; } } - for (final InputMethodSubtype subtype : mAsciiCapableSubtypesList) { + for (final InputMethodSubtype subtype : getSubtypesFilteredBy(FILTER_IS_ASCII_CAPABLE)) { final Locale subtypeLocale = SubtypeLocaleUtils.getSubtypeLocale(subtype); if (locale.equals(subtypeLocale)) { // Create additional subtype. @@ -116,21 +147,22 @@ public abstract class KeyboardLayoutSetTestsBase extends AndroidTestCase { protected KeyboardLayoutSet createKeyboardLayoutSet(final InputMethodSubtype subtype, final EditorInfo editorInfo) { return createKeyboardLayoutSet(subtype, editorInfo, false /* voiceInputKeyEnabled */, - false /* languageSwitchKeyEnabled */); + false /* languageSwitchKeyEnabled */, false /* splitLayoutEnabled */); } protected KeyboardLayoutSet createKeyboardLayoutSet(final InputMethodSubtype subtype, final EditorInfo editorInfo, final boolean voiceInputKeyEnabled, - final boolean languageSwitchKeyEnabled) { + final boolean languageSwitchKeyEnabled, final boolean splitLayoutEnabled) { final Context context = getContext(); final Resources res = context.getResources(); final int keyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res); final int keyboardHeight = ResourceUtils.getDefaultKeyboardHeight(res); final Builder builder = new Builder(context, editorInfo); builder.setKeyboardGeometry(keyboardWidth, keyboardHeight) - .setSubtype(subtype) + .setSubtype(RichInputMethodSubtype.getRichInputMethodSubtype(subtype)) .setVoiceInputKeyEnabled(voiceInputKeyEnabled) - .setLanguageSwitchKeyEnabled(languageSwitchKeyEnabled); + .setLanguageSwitchKeyEnabled(languageSwitchKeyEnabled) + .setSplitLayoutEnabledByUser(splitLayoutEnabled); return builder.build(); } } diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutTest.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutTest.java new file mode 100644 index 000000000..1e1f82fc0 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2015 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; + +import static org.junit.Assert.assertEquals; + +import android.test.suitebuilder.annotation.SmallTest; + +import java.util.ArrayList; + +import org.junit.Test; + +@SmallTest +public class KeyboardLayoutTest { + + @Test + public void testNewKeyboardLayout() { + KeyboardLayout keyboardLayout = KeyboardLayout + .newKeyboardLayout(new ArrayList<Key>(), 11, 12, 13, 14); + + assertEquals(11, keyboardLayout.mMostCommonKeyWidth); + assertEquals(12, keyboardLayout.mMostCommonKeyHeight); + assertEquals(13, keyboardLayout.mKeyboardWidth); + assertEquals(14, keyboardLayout.mKeyboardHeight); + + assertEquals(0, keyboardLayout.getKeyCodes().length); + assertEquals(0, keyboardLayout.getKeyWidths().length); + assertEquals(0, keyboardLayout.getKeyHeights().length); + assertEquals(0, keyboardLayout.getKeyXCoordinates().length); + assertEquals(0, keyboardLayout.getKeyYCoordinates().length); + + Key key1 = new Key("label1", 101, 102, "101", "101hint", 103, 104, 105, 106, 1100, 1101, + 10, 10); + Key key2 = new Key("label2", 201, 103, "201", "201hint", 203, 204, 205, 206, 2100, 2101, + 10, 10); + + ArrayList<Key> sortedKeys = new ArrayList<>(2); + sortedKeys.add(key1); + sortedKeys.add(key2); + keyboardLayout = KeyboardLayout.newKeyboardLayout(sortedKeys, 11, 12, 13, 14); + assertEquals(2, keyboardLayout.getKeyCodes().length); + assertEquals(2, keyboardLayout.getKeyWidths().length); + assertEquals(2, keyboardLayout.getKeyHeights().length); + assertEquals(2, keyboardLayout.getKeyXCoordinates().length); + assertEquals(2, keyboardLayout.getKeyYCoordinates().length); + + assertEquals(102, keyboardLayout.getKeyCodes()[0]); + // xCo + horizontalGap/2 + assertEquals(105 + 5, keyboardLayout.getKeyXCoordinates()[0]); + assertEquals(106, keyboardLayout.getKeyYCoordinates()[0]); + // width - horizontalGap + assertEquals(1100 - 10, keyboardLayout.getKeyWidths()[0]); + // height - verticalGap + assertEquals(1101 - 10, keyboardLayout.getKeyHeights()[0]); + + assertEquals(103, keyboardLayout.getKeyCodes()[1]); + // xCo + horizontalGap/2 + assertEquals(205 + 5, keyboardLayout.getKeyXCoordinates()[1]); + assertEquals(206, keyboardLayout.getKeyYCoordinates()[1]); + // width - horizontalGap + assertEquals(2100 - 10, keyboardLayout.getKeyWidths()[1]); + // height - verticalGap + assertEquals(2101 - 10, keyboardLayout.getKeyHeights()[1]); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardThemeTests.java b/tests/src/com/android/inputmethod/keyboard/KeyboardThemeTests.java index c20954f81..33e88c13b 100644 --- a/tests/src/com/android/inputmethod/keyboard/KeyboardThemeTests.java +++ b/tests/src/com/android/inputmethod/keyboard/KeyboardThemeTests.java @@ -16,18 +16,20 @@ package com.android.inputmethod.keyboard; -import static com.android.inputmethod.compat.BuildCompatUtils.VERSION_CODES_LXX; import static com.android.inputmethod.keyboard.KeyboardTheme.THEME_ID_ICS; import static com.android.inputmethod.keyboard.KeyboardTheme.THEME_ID_KLP; import static com.android.inputmethod.keyboard.KeyboardTheme.THEME_ID_LXX_DARK; import static com.android.inputmethod.keyboard.KeyboardTheme.THEME_ID_LXX_LIGHT; import android.content.SharedPreferences; +import android.os.Build; import android.os.Build.VERSION_CODES; import android.preference.PreferenceManager; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; +import java.util.Arrays; + @SmallTest public class KeyboardThemeTests extends AndroidTestCase { private SharedPreferences mPrefs; @@ -77,7 +79,9 @@ public class KeyboardThemeTests extends AndroidTestCase { } private void assertKeyboardTheme(final int sdkVersion, final int expectedThemeId) { - assertEquals(expectedThemeId, KeyboardTheme.getKeyboardTheme(mPrefs, sdkVersion).mThemeId); + final KeyboardTheme actualTheme = KeyboardTheme.getKeyboardTheme( + mPrefs, sdkVersion, KeyboardTheme.KEYBOARD_THEMES); + assertEquals(expectedThemeId, actualTheme.mThemeId); } /* @@ -127,7 +131,7 @@ public class KeyboardThemeTests extends AndroidTestCase { } public void testKeyboardThemePreferenceOnLxx() { - assertKeyboardThemePreferenceOnLxx(VERSION_CODES_LXX); + assertKeyboardThemePreferenceOnLxx(Build.VERSION_CODES.LOLLIPOP); } /* @@ -139,8 +143,8 @@ public class KeyboardThemeTests extends AndroidTestCase { final String oldPrefKey = KeyboardTheme.KLP_KEYBOARD_THEME_KEY; setKeyboardThemePreference(oldPrefKey, previousThemeId); - final KeyboardTheme defaultTheme = - KeyboardTheme.getDefaultKeyboardTheme(mPrefs, sdkVersion); + final KeyboardTheme defaultTheme = KeyboardTheme.getDefaultKeyboardTheme( + mPrefs, sdkVersion, KeyboardTheme.KEYBOARD_THEMES); assertNotNull(defaultTheme); assertEquals(expectedThemeId, defaultTheme.mThemeId); @@ -180,7 +184,7 @@ public class KeyboardThemeTests extends AndroidTestCase { } public void testDefaultKeyboardThemeOnLxx() { - assertDefaultKeyboardThemeOnLxx(VERSION_CODES_LXX); + assertDefaultKeyboardThemeOnLxx(Build.VERSION_CODES.LOLLIPOP); } /* @@ -194,7 +198,8 @@ public class KeyboardThemeTests extends AndroidTestCase { // Clean up new keyboard theme preference to simulate "upgrade to LXX keyboard". setKeyboardThemePreference(KeyboardTheme.LXX_KEYBOARD_THEME_KEY, THEME_ID_NULL); - final KeyboardTheme theme = KeyboardTheme.getKeyboardTheme(mPrefs, sdkVersion); + final KeyboardTheme theme = KeyboardTheme.getKeyboardTheme( + mPrefs, sdkVersion, KeyboardTheme.KEYBOARD_THEMES); assertNotNull(theme); assertEquals(expectedThemeId, theme.mThemeId); @@ -246,7 +251,7 @@ public class KeyboardThemeTests extends AndroidTestCase { // Upgrading keyboard on L. public void testUpgradeKeyboardToLxxOnLxx() { - assertUpgradeKeyboardToLxxOnLxx(VERSION_CODES_LXX); + assertUpgradeKeyboardToLxxOnLxx(Build.VERSION_CODES.LOLLIPOP); } /* @@ -299,7 +304,7 @@ public class KeyboardThemeTests extends AndroidTestCase { private void assertUpgradePlatformToLxxFrom(final int oldSdkVersion) { // Forced to switch to LXX theme. - final int newSdkVersion = VERSION_CODES_LXX; + final int newSdkVersion = Build.VERSION_CODES.LOLLIPOP; assertUpgradePlatformFromTo( oldSdkVersion, newSdkVersion, THEME_ID_NULL, THEME_ID_LXX_LIGHT); assertUpgradePlatformFromTo( @@ -324,8 +329,8 @@ public class KeyboardThemeTests extends AndroidTestCase { // Update platform from L to L. public void testUpgradePlatformToLxxFromLxx() { - final int oldSdkVersion = VERSION_CODES_LXX; - final int newSdkVersion = VERSION_CODES_LXX; + final int oldSdkVersion = Build.VERSION_CODES.LOLLIPOP; + final int newSdkVersion = Build.VERSION_CODES.LOLLIPOP; assertUpgradePlatformFromTo( oldSdkVersion, newSdkVersion, THEME_ID_NULL, THEME_ID_LXX_LIGHT); assertUpgradePlatformFromTo( @@ -341,4 +346,86 @@ public class KeyboardThemeTests extends AndroidTestCase { assertUpgradePlatformFromTo( oldSdkVersion, newSdkVersion, THEME_ID_ILLEGAL, THEME_ID_LXX_LIGHT); } + + /* + * Test that KeyboardTheme array should be sorted by descending order of + * {@link KeyboardTheme#mMinApiVersion}. + */ + private static void assertSortedKeyboardThemeArray(final KeyboardTheme[] array) { + assertNotNull(array); + final int length = array.length; + assertTrue("array length=" + length, length > 0); + for (int index = 0; index < length - 1; index++) { + final KeyboardTheme theme = array[index]; + final KeyboardTheme nextTheme = array[index + 1]; + assertTrue("sorted MinApiVersion: " + + theme.mThemeName + ": minApiVersion=" + theme.mMinApiVersion, + theme.mMinApiVersion >= nextTheme.mMinApiVersion); + } + } + + public void testSortedKeyboardTheme() { + assertSortedKeyboardThemeArray(KeyboardTheme.KEYBOARD_THEMES); + } + + public void testSortedAvailableKeyboardTheme() { + assertSortedKeyboardThemeArray(KeyboardTheme.getAvailableThemeArray(getContext())); + } + + /* + * Test for missing selected theme. + */ + private static KeyboardTheme[] LIMITED_THEMES = { + KeyboardTheme.searchKeyboardThemeById(THEME_ID_ICS, KeyboardTheme.KEYBOARD_THEMES), + KeyboardTheme.searchKeyboardThemeById(THEME_ID_KLP, KeyboardTheme.KEYBOARD_THEMES) + }; + static { + Arrays.sort(LIMITED_THEMES); + assertSortedKeyboardThemeArray(LIMITED_THEMES); + } + + public void testMissingSelectedThemeIcs() { + // Clean up preferences. + setKeyboardThemePreference(KeyboardTheme.KLP_KEYBOARD_THEME_KEY, THEME_ID_NULL); + setKeyboardThemePreference(KeyboardTheme.LXX_KEYBOARD_THEME_KEY, THEME_ID_NULL); + + final int sdkVersion = VERSION_CODES.ICE_CREAM_SANDWICH; + final String oldPrefKey = KeyboardTheme.getPreferenceKey(sdkVersion); + setKeyboardThemePreference(oldPrefKey, THEME_ID_LXX_LIGHT); + + final KeyboardTheme actualTheme = KeyboardTheme.getKeyboardTheme( + mPrefs, sdkVersion, LIMITED_THEMES); + // LXX_LIGHT is missing, fall-back to KLP. + assertEquals(THEME_ID_KLP, actualTheme.mThemeId); + } + + public void testMissingSelectedThemeKlp() { + // Clean up preferences. + setKeyboardThemePreference(KeyboardTheme.KLP_KEYBOARD_THEME_KEY, THEME_ID_NULL); + setKeyboardThemePreference(KeyboardTheme.LXX_KEYBOARD_THEME_KEY, THEME_ID_NULL); + + final int sdkVersion = VERSION_CODES.KITKAT; + final String oldPrefKey = KeyboardTheme.getPreferenceKey(sdkVersion); + setKeyboardThemePreference(oldPrefKey, THEME_ID_LXX_LIGHT); + + final KeyboardTheme actualTheme = KeyboardTheme.getKeyboardTheme( + mPrefs, sdkVersion, LIMITED_THEMES); + // LXX_LIGHT is missing, fall-back to KLP. + assertEquals(THEME_ID_KLP, actualTheme.mThemeId); + } + + public void testMissingSelectedThemeLxx() { + // Clean up preferences. + setKeyboardThemePreference(KeyboardTheme.KLP_KEYBOARD_THEME_KEY, THEME_ID_NULL); + setKeyboardThemePreference(KeyboardTheme.LXX_KEYBOARD_THEME_KEY, THEME_ID_NULL); + + final int sdkVersion = Build.VERSION_CODES.LOLLIPOP; + final String oldPrefKey = KeyboardTheme.getPreferenceKey(sdkVersion); + setKeyboardThemePreference(oldPrefKey, THEME_ID_LXX_DARK); + + final KeyboardTheme actualTheme = KeyboardTheme.getKeyboardTheme( + mPrefs, sdkVersion, LIMITED_THEMES); + // LXX_DARK is missing, fall-back to KLP. + assertEquals(THEME_ID_KLP, actualTheme.mThemeId); + } } diff --git a/tests/src/com/android/inputmethod/keyboard/action/ActionTestsBase.java b/tests/src/com/android/inputmethod/keyboard/action/ActionTestsBase.java new file mode 100644 index 000000000..1ea68e471 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/ActionTestsBase.java @@ -0,0 +1,115 @@ +/* + * 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.action; + +import android.content.Context; +import android.content.res.Resources; +import android.text.InputType; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.Key; +import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.KeyboardLayoutSet; +import com.android.inputmethod.keyboard.KeyboardLayoutSetTestsBase; +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyVisual; +import com.android.inputmethod.latin.common.Constants; +import com.android.inputmethod.latin.common.LocaleUtils; +import com.android.inputmethod.latin.utils.RunInLocale; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +import java.util.Locale; + +abstract class ActionTestsBase extends KeyboardLayoutSetTestsBase { + static class ExpectedActionKey { + static ExpectedActionKey newIconKey(final String iconName) { + final int iconId = KeyboardIconsSet.getIconId(iconName); + return new ExpectedActionKey(ExpectedKeyVisual.newInstance(iconId)); + } + + static ExpectedActionKey newLabelKey(final String label) { + return new ExpectedActionKey(ExpectedKeyVisual.newInstance(label)); + } + + static ExpectedActionKey newLabelKey(final int labelResId, + final Locale labelLocale, final Context context) { + final RunInLocale<String> getString = new RunInLocale<String>() { + @Override + protected String job(final Resources res) { + return res.getString(labelResId); + } + }; + return newLabelKey(getString.runInLocale(context.getResources(), labelLocale)); + } + + private final ExpectedKeyVisual mVisual; + + private ExpectedActionKey(final ExpectedKeyVisual visual) { + mVisual = visual; + } + + public int getIconId() { return mVisual.getIconId(); } + + public String getLabel() { return mVisual.getLabel(); } + } + + protected static Locale getLabelLocale(final InputMethodSubtype subtype) { + final String localeString = subtype.getLocale(); + if (localeString.equals(SubtypeLocaleUtils.NO_LANGUAGE)) { + return null; + } + return LocaleUtils.constructLocaleFromString(localeString); + } + + private static void assertActionKey(final String tag, final KeyboardLayoutSet layoutSet, + final int elementId, final ExpectedActionKey expectedKey) { + final Keyboard keyboard = layoutSet.getKeyboard(elementId); + final Key actualKey = keyboard.getKey(Constants.CODE_ENTER); + assertNotNull(tag + " enter key on " + keyboard.mId, actualKey); + assertEquals(tag + " label " + expectedKey, expectedKey.getLabel(), actualKey.getLabel()); + assertEquals(tag + " icon " + expectedKey, expectedKey.getIconId(), actualKey.getIconId()); + } + + protected void doTestActionKey(final String tag, final InputMethodSubtype subtype, + final int actionId, final ExpectedActionKey expectedKey) { + final EditorInfo editorInfo = new EditorInfo(); + editorInfo.imeOptions = actionId; + doTestActionKey(tag, subtype, editorInfo, expectedKey); + } + + protected void doTestActionKey(final String tag, final InputMethodSubtype subtype, + final EditorInfo editorInfo, final ExpectedActionKey expectedKey) { + // Test text layouts. + editorInfo.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL; + final KeyboardLayoutSet layoutSet = createKeyboardLayoutSet(subtype, editorInfo); + assertActionKey(tag, layoutSet, KeyboardId.ELEMENT_ALPHABET, expectedKey); + assertActionKey(tag, layoutSet, KeyboardId.ELEMENT_SYMBOLS, expectedKey); + assertActionKey(tag, layoutSet, KeyboardId.ELEMENT_SYMBOLS_SHIFTED, expectedKey); + // Test phone number layouts. + assertActionKey(tag, layoutSet, KeyboardId.ELEMENT_PHONE, expectedKey); + assertActionKey(tag, layoutSet, KeyboardId.ELEMENT_PHONE_SYMBOLS, expectedKey); + // Test normal number layout. + assertActionKey(tag, layoutSet, KeyboardId.ELEMENT_NUMBER, expectedKey); + // Test number password layout. + editorInfo.inputType = + InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD; + final KeyboardLayoutSet passwordSet = createKeyboardLayoutSet(subtype, editorInfo); + assertActionKey(tag, passwordSet, KeyboardId.ELEMENT_NUMBER, expectedKey); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/KlpActionCustomTests.java b/tests/src/com/android/inputmethod/keyboard/action/KlpActionCustomTests.java new file mode 100644 index 000000000..cb1c6ad1f --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/KlpActionCustomTests.java @@ -0,0 +1,37 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class KlpActionCustomTests extends KlpActionTestsBase { + public void testActionCustom() { + for (final InputMethodSubtype subtype : mSubtypesWhoseNameIsDisplayedInItsLocale) { + final String tag = "custom " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + final EditorInfo editorInfo = new EditorInfo(); + editorInfo.imeOptions = EditorInfo.IME_ACTION_UNSPECIFIED; + editorInfo.actionLabel = "customLabel"; + final ExpectedActionKey expectedKey = ExpectedActionKey.newLabelKey("customLabel"); + doTestActionKey(tag, subtype, editorInfo, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/KlpActionDoneTests.java b/tests/src/com/android/inputmethod/keyboard/action/KlpActionDoneTests.java new file mode 100644 index 000000000..e0a87a70d --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/KlpActionDoneTests.java @@ -0,0 +1,36 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class KlpActionDoneTests extends KlpActionTestsBase { + public void testActionDone() { + for (final InputMethodSubtype subtype : mSubtypesWhoseNameIsDisplayedInItsLocale) { + final String tag = "done " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + final ExpectedActionKey expectedKey = ExpectedActionKey.newLabelKey( + R.string.label_done_key, getLabelLocale(subtype), getContext()); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_DONE, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/KlpActionGoTests.java b/tests/src/com/android/inputmethod/keyboard/action/KlpActionGoTests.java new file mode 100644 index 000000000..865b598d6 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/KlpActionGoTests.java @@ -0,0 +1,36 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class KlpActionGoTests extends KlpActionTestsBase { + public void testActionGo() { + for (final InputMethodSubtype subtype : mSubtypesWhoseNameIsDisplayedInItsLocale) { + final String tag = "go " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + final ExpectedActionKey expectedKey = ExpectedActionKey.newLabelKey( + R.string.label_go_key, getLabelLocale(subtype), getContext()); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_GO, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/KlpActionLabelTests.java b/tests/src/com/android/inputmethod/keyboard/action/KlpActionLabelTests.java new file mode 100644 index 000000000..07c604e59 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/KlpActionLabelTests.java @@ -0,0 +1,180 @@ +/* + * 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.action; + +import android.content.res.Resources; +import android.test.suitebuilder.annotation.MediumTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.KeyboardLayoutSet; +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.keyboard.internal.KeyboardTextsSet; +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.RichInputMethodManager; +import com.android.inputmethod.latin.utils.RunInLocale; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +import java.util.Locale; + +@MediumTest +public class KlpActionLabelTests extends KlpActionTestsBase { + void doTestActionKeys(final InputMethodSubtype subtype, final String tag, + final ExpectedActionKey unspecifiedKey, final ExpectedActionKey noneKey, + final ExpectedActionKey goKey, final ExpectedActionKey searchKey, + final ExpectedActionKey sendKey, final ExpectedActionKey nextKey, + final ExpectedActionKey doneKey, final ExpectedActionKey previousKey) { + doTestActionKey( + tag + " unspecified", subtype, EditorInfo.IME_ACTION_UNSPECIFIED, unspecifiedKey); + doTestActionKey(tag + " none", subtype, EditorInfo.IME_ACTION_NONE, noneKey); + doTestActionKey(tag + " go", subtype, EditorInfo.IME_ACTION_GO, goKey); + doTestActionKey(tag + " search", subtype, EditorInfo.IME_ACTION_SEARCH, searchKey); + doTestActionKey(tag + " send", subtype, EditorInfo.IME_ACTION_SEND, sendKey); + doTestActionKey(tag + " next", subtype, EditorInfo.IME_ACTION_NEXT, nextKey); + doTestActionKey(tag + " done", subtype, EditorInfo.IME_ACTION_DONE, doneKey); + doTestActionKey(tag + " previous", subtype, EditorInfo.IME_ACTION_PREVIOUS, previousKey); + } + + // Working variable to simulate system locale changing. + private Locale mSystemLocale = Locale.getDefault(); + + private void doTestActionKeysInLocaleWithStringResources(final InputMethodSubtype subtype, + final Locale labelLocale, final Locale systemLocale) { + // Simulate system locale changing, see {@link SystemBroadcastReceiver}. + if (!systemLocale.equals(mSystemLocale)) { + KeyboardLayoutSet.onSystemLocaleChanged(); + mSystemLocale = systemLocale; + } + final ExpectedActionKey enterKey = ExpectedActionKey.newIconKey( + KeyboardIconsSet.NAME_ENTER_KEY); + final ExpectedActionKey goKey = ExpectedActionKey.newLabelKey( + R.string.label_go_key, labelLocale, getContext()); + final ExpectedActionKey searchKey = ExpectedActionKey.newIconKey( + KeyboardIconsSet.NAME_SEARCH_KEY); + final ExpectedActionKey sendKey = ExpectedActionKey.newLabelKey( + R.string.label_send_key, labelLocale, getContext()); + final ExpectedActionKey nextKey = ExpectedActionKey.newLabelKey( + R.string.label_next_key, labelLocale, getContext()); + final ExpectedActionKey doneKey = ExpectedActionKey.newLabelKey( + R.string.label_done_key, labelLocale, getContext()); + final ExpectedActionKey previousKey = ExpectedActionKey.newLabelKey( + R.string.label_previous_key, labelLocale, getContext()); + final String tag = "label=" + labelLocale + " system=" + systemLocale + + " " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + final RunInLocale<Void> job = new RunInLocale<Void>() { + @Override + public Void job(final Resources res) { + doTestActionKeys(subtype, tag, enterKey, enterKey, goKey, searchKey, sendKey, + nextKey, doneKey, previousKey); + return null; + } + }; + job.runInLocale(getContext().getResources(), systemLocale); + } + + public void testActionLabelInOtherLocale() { + final RichInputMethodManager richImm = RichInputMethodManager.getInstance(); + final InputMethodSubtype italian = richImm.findSubtypeByLocaleAndKeyboardLayoutSet( + Locale.ITALIAN.toString(), SubtypeLocaleUtils.QWERTY); + // An action label should be displayed in subtype's locale regardless of the system locale. + doTestActionKeysInLocaleWithStringResources(italian, Locale.ITALIAN, Locale.US); + doTestActionKeysInLocaleWithStringResources(italian, Locale.ITALIAN, Locale.FRENCH); + doTestActionKeysInLocaleWithStringResources(italian, Locale.ITALIAN, Locale.ITALIAN); + doTestActionKeysInLocaleWithStringResources(italian, Locale.ITALIAN, Locale.JAPANESE); + } + + public void testNoLanguageSubtypeActionLabel() { + final RichInputMethodManager richImm = RichInputMethodManager.getInstance(); + final InputMethodSubtype noLanguage = richImm.findSubtypeByLocaleAndKeyboardLayoutSet( + SubtypeLocaleUtils.NO_LANGUAGE, SubtypeLocaleUtils.QWERTY); + // An action label of no language keyboard should be displayed in the system locale. + doTestActionKeysInLocaleWithStringResources(noLanguage, Locale.US, Locale.US); + doTestActionKeysInLocaleWithStringResources(noLanguage, Locale.FRENCH, Locale.FRENCH); + doTestActionKeysInLocaleWithStringResources(noLanguage, Locale.ITALIAN, Locale.ITALIAN); + doTestActionKeysInLocaleWithStringResources(noLanguage, Locale.JAPANESE, Locale.JAPANESE); + } + + private void doTestActionKeysInLocaleWithKeyboardTextsSet(final InputMethodSubtype subtype, + final Locale labelLocale, final Locale systemLocale) { + // Simulate system locale changing, see {@link SystemBroadcastReceiver}. + if (!systemLocale.equals(mSystemLocale)) { + KeyboardLayoutSet.onSystemLocaleChanged(); + mSystemLocale = systemLocale; + } + final KeyboardTextsSet textsSet = new KeyboardTextsSet(); + textsSet.setLocale(labelLocale, getContext()); + final ExpectedActionKey enterKey = ExpectedActionKey.newIconKey( + KeyboardIconsSet.NAME_ENTER_KEY); + final ExpectedActionKey goKey = ExpectedActionKey.newLabelKey( + textsSet.getText("label_go_key")); + final ExpectedActionKey searchKey = ExpectedActionKey.newIconKey( + KeyboardIconsSet.NAME_SEARCH_KEY); + final ExpectedActionKey sendKey = ExpectedActionKey.newLabelKey( + textsSet.getText("label_send_key")); + final ExpectedActionKey nextKey = ExpectedActionKey.newLabelKey( + textsSet.getText("label_next_key")); + final ExpectedActionKey doneKey = ExpectedActionKey.newLabelKey( + textsSet.getText("label_done_key")); + final ExpectedActionKey previousKey = ExpectedActionKey.newLabelKey( + textsSet.getText("label_previous_key")); + final String tag = "label=" + subtype.getLocale() + " system=" + systemLocale + + " " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + final RunInLocale<Void> job = new RunInLocale<Void>() { + @Override + public Void job(final Resources res) { + doTestActionKeys(subtype, tag, enterKey, enterKey, goKey, searchKey, sendKey, + nextKey, doneKey, previousKey); + return null; + } + }; + job.runInLocale(getContext().getResources(), systemLocale); + } + + public void testHinglishActionLabel() { + final RichInputMethodManager richImm = RichInputMethodManager.getInstance(); + final Locale hi_ZZ = new Locale("hi", "ZZ"); + final InputMethodSubtype hiLatn = richImm.findSubtypeByLocaleAndKeyboardLayoutSet( + hi_ZZ.toString(), SubtypeLocaleUtils.QWERTY); + // This is a preliminary subtype and may not exist. + if (hiLatn == null) { + return; + } + // An action label should be displayed in subtype's locale regardless of the system locale. + doTestActionKeysInLocaleWithKeyboardTextsSet(hiLatn, hi_ZZ, new Locale("hi")); + doTestActionKeysInLocaleWithKeyboardTextsSet(hiLatn, hi_ZZ, Locale.US); + doTestActionKeysInLocaleWithKeyboardTextsSet(hiLatn, hi_ZZ, Locale.FRENCH); + doTestActionKeysInLocaleWithKeyboardTextsSet(hiLatn, hi_ZZ, Locale.ITALIAN); + doTestActionKeysInLocaleWithKeyboardTextsSet(hiLatn, hi_ZZ, Locale.JAPANESE); + } + + public void testSerbianLatinActionLabel() { + final RichInputMethodManager richImm = RichInputMethodManager.getInstance(); + final Locale sr_ZZ = new Locale("sr", "ZZ"); + final InputMethodSubtype srLatn = richImm.findSubtypeByLocaleAndKeyboardLayoutSet( + sr_ZZ.toString(), "serbian_qwertz"); + // This is a preliminary subtype and may not exist. + if (srLatn == null) { + return; + } + // An action label should be displayed in subtype's locale regardless of the system locale. + doTestActionKeysInLocaleWithKeyboardTextsSet(srLatn, sr_ZZ, new Locale("sr")); + doTestActionKeysInLocaleWithKeyboardTextsSet(srLatn, sr_ZZ, Locale.US); + doTestActionKeysInLocaleWithKeyboardTextsSet(srLatn, sr_ZZ, Locale.FRENCH); + doTestActionKeysInLocaleWithKeyboardTextsSet(srLatn, sr_ZZ, Locale.ITALIAN); + doTestActionKeysInLocaleWithKeyboardTextsSet(srLatn, sr_ZZ, Locale.JAPANESE); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/KlpActionNextTests.java b/tests/src/com/android/inputmethod/keyboard/action/KlpActionNextTests.java new file mode 100644 index 000000000..c67740cac --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/KlpActionNextTests.java @@ -0,0 +1,36 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class KlpActionNextTests extends KlpActionTestsBase { + public void testActionNext() { + for (final InputMethodSubtype subtype : mSubtypesWhoseNameIsDisplayedInItsLocale) { + final String tag = "next " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + final ExpectedActionKey expectedKey = ExpectedActionKey.newLabelKey( + R.string.label_next_key, getLabelLocale(subtype), getContext()); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_NEXT, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/KlpActionNoneTests.java b/tests/src/com/android/inputmethod/keyboard/action/KlpActionNoneTests.java new file mode 100644 index 000000000..0be2ecb93 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/KlpActionNoneTests.java @@ -0,0 +1,36 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class KlpActionNoneTests extends KlpActionTestsBase { + public void testActionNone() { + final ExpectedActionKey expectedKey = ExpectedActionKey.newIconKey( + KeyboardIconsSet.NAME_ENTER_KEY); + for (final InputMethodSubtype subtype : mSubtypesWhoseNameIsDisplayedInItsLocale) { + final String tag = "none " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_NONE, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/KlpActionPreviousTests.java b/tests/src/com/android/inputmethod/keyboard/action/KlpActionPreviousTests.java new file mode 100644 index 000000000..af6a15400 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/KlpActionPreviousTests.java @@ -0,0 +1,36 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class KlpActionPreviousTests extends KlpActionTestsBase { + public void testActionPrevious() { + for (final InputMethodSubtype subtype : mSubtypesWhoseNameIsDisplayedInItsLocale) { + final String tag = "previous " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + final ExpectedActionKey expectedKey = ExpectedActionKey.newLabelKey( + R.string.label_previous_key, getLabelLocale(subtype), getContext()); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_PREVIOUS, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/KlpActionSearchTests.java b/tests/src/com/android/inputmethod/keyboard/action/KlpActionSearchTests.java new file mode 100644 index 000000000..adc3feee7 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/KlpActionSearchTests.java @@ -0,0 +1,36 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class KlpActionSearchTests extends KlpActionTestsBase { + public void testActionSearch() { + final ExpectedActionKey expectedKey = ExpectedActionKey.newIconKey( + KeyboardIconsSet.NAME_SEARCH_KEY); + for (final InputMethodSubtype subtype : mSubtypesWhoseNameIsDisplayedInItsLocale) { + final String tag = "search " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_SEARCH, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/KlpActionSendTests.java b/tests/src/com/android/inputmethod/keyboard/action/KlpActionSendTests.java new file mode 100644 index 000000000..82f97a2ae --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/KlpActionSendTests.java @@ -0,0 +1,36 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class KlpActionSendTests extends KlpActionTestsBase { + public void testActionSend() { + for (final InputMethodSubtype subtype : mSubtypesWhoseNameIsDisplayedInItsLocale) { + final String tag = "send " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + final ExpectedActionKey expectedKey = ExpectedActionKey.newLabelKey( + R.string.label_send_key, getLabelLocale(subtype), getContext()); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_SEND, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/KlpActionTestsBase.java b/tests/src/com/android/inputmethod/keyboard/action/KlpActionTestsBase.java new file mode 100644 index 000000000..511f9950b --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/KlpActionTestsBase.java @@ -0,0 +1,55 @@ +/* + * 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.action; + +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.KeyboardTheme; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +import java.util.ArrayList; +import java.util.Locale; + +abstract class KlpActionTestsBase extends ActionTestsBase { + // Filter a subtype whose name should be displayed using {@link Locale#ROOT}, such like + // Hinglish (hi_ZZ) and Serbian-Latn (sr_ZZ). + static final SubtypeFilter SUBTYPE_FILTER_NAME_IN_BASE_LOCALE = new SubtypeFilter() { + @Override + public boolean accept(final InputMethodSubtype subtype) { + return Locale.ROOT.equals( + SubtypeLocaleUtils.getDisplayLocaleOfSubtypeLocale(subtype.getLocale())); + } + }; + + protected ArrayList<InputMethodSubtype> mSubtypesWhoseNameIsDisplayedInItsLocale; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mSubtypesWhoseNameIsDisplayedInItsLocale = getSubtypesFilteredBy(new SubtypeFilter() { + @Override + public boolean accept(final InputMethodSubtype subtype) { + return !SUBTYPE_FILTER_NAME_IN_BASE_LOCALE.accept(subtype); + } + }); + } + + @Override + protected int getKeyboardThemeForTests() { + return KeyboardTheme.THEME_ID_KLP; + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/KlpActionUnspecifiedTests.java b/tests/src/com/android/inputmethod/keyboard/action/KlpActionUnspecifiedTests.java new file mode 100644 index 000000000..307e273e8 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/KlpActionUnspecifiedTests.java @@ -0,0 +1,37 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class KlpActionUnspecifiedTests extends KlpActionTestsBase { + public void testActionUnspecified() { + final ExpectedActionKey expectedKey = ExpectedActionKey.newIconKey( + KeyboardIconsSet.NAME_ENTER_KEY); + for (final InputMethodSubtype subtype : mSubtypesWhoseNameIsDisplayedInItsLocale) { + final String tag = "unspecifiled " + + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_UNSPECIFIED, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/LxxActionCustomTests.java b/tests/src/com/android/inputmethod/keyboard/action/LxxActionCustomTests.java new file mode 100644 index 000000000..d561f457d --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/LxxActionCustomTests.java @@ -0,0 +1,37 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class LxxActionCustomTests extends LxxActionTestsBase { + public void testActionCustom() { + for (final InputMethodSubtype subtype : getAllSubtypesList()) { + final String tag = "custom " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + final EditorInfo editorInfo = new EditorInfo(); + editorInfo.imeOptions = EditorInfo.IME_ACTION_UNSPECIFIED; + editorInfo.actionLabel = "customLabel"; + final ExpectedActionKey expectedKey = ExpectedActionKey.newLabelKey("customLabel"); + doTestActionKey(tag, subtype, editorInfo, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/LxxActionDoneTests.java b/tests/src/com/android/inputmethod/keyboard/action/LxxActionDoneTests.java new file mode 100644 index 000000000..b818bb1ce --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/LxxActionDoneTests.java @@ -0,0 +1,36 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class LxxActionDoneTests extends LxxActionTestsBase { + public void testActionDone() { + final ExpectedActionKey expectedKey = ExpectedActionKey.newIconKey( + KeyboardIconsSet.NAME_DONE_KEY); + for (final InputMethodSubtype subtype : getAllSubtypesList()) { + final String tag = "done " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_DONE, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/LxxActionGoTests.java b/tests/src/com/android/inputmethod/keyboard/action/LxxActionGoTests.java new file mode 100644 index 000000000..8001f7105 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/LxxActionGoTests.java @@ -0,0 +1,36 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class LxxActionGoTests extends LxxActionTestsBase { + public void testActionGo() { + final ExpectedActionKey expectedKey = ExpectedActionKey.newIconKey( + KeyboardIconsSet.NAME_GO_KEY); + for (final InputMethodSubtype subtype : getAllSubtypesList()) { + final String tag = "go " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_GO, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/LxxActionNextTests.java b/tests/src/com/android/inputmethod/keyboard/action/LxxActionNextTests.java new file mode 100644 index 000000000..09a8c87ec --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/LxxActionNextTests.java @@ -0,0 +1,36 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class LxxActionNextTests extends LxxActionTestsBase { + public void testActionNext() { + final ExpectedActionKey expectedKey = ExpectedActionKey.newIconKey( + KeyboardIconsSet.NAME_NEXT_KEY); + for (final InputMethodSubtype subtype : getAllSubtypesList()) { + final String tag = "next " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_NEXT, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/LxxActionNoneTests.java b/tests/src/com/android/inputmethod/keyboard/action/LxxActionNoneTests.java new file mode 100644 index 000000000..98595e976 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/LxxActionNoneTests.java @@ -0,0 +1,36 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class LxxActionNoneTests extends LxxActionTestsBase { + public void testActionNone() { + final ExpectedActionKey expectedKey = ExpectedActionKey.newIconKey( + KeyboardIconsSet.NAME_ENTER_KEY); + for (final InputMethodSubtype subtype : getAllSubtypesList()) { + final String tag = "none " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_NONE, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/LxxActionPreviousTests.java b/tests/src/com/android/inputmethod/keyboard/action/LxxActionPreviousTests.java new file mode 100644 index 000000000..2327889ae --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/LxxActionPreviousTests.java @@ -0,0 +1,36 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class LxxActionPreviousTests extends LxxActionTestsBase { + public void testActionPrevious() { + final ExpectedActionKey expectedKey = ExpectedActionKey.newIconKey( + KeyboardIconsSet.NAME_PREVIOUS_KEY); + for (final InputMethodSubtype subtype : getAllSubtypesList()) { + final String tag = "previous " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_PREVIOUS, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/LxxActionSearchTests.java b/tests/src/com/android/inputmethod/keyboard/action/LxxActionSearchTests.java new file mode 100644 index 000000000..7e1d86b2e --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/LxxActionSearchTests.java @@ -0,0 +1,36 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class LxxActionSearchTests extends LxxActionTestsBase { + public void testActionSearch() { + final ExpectedActionKey expectedKey = ExpectedActionKey.newIconKey( + KeyboardIconsSet.NAME_SEARCH_KEY); + for (final InputMethodSubtype subtype : getAllSubtypesList()) { + final String tag = "search " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_SEARCH, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/LxxActionSendTests.java b/tests/src/com/android/inputmethod/keyboard/action/LxxActionSendTests.java new file mode 100644 index 000000000..fa0134f0d --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/LxxActionSendTests.java @@ -0,0 +1,36 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class LxxActionSendTests extends LxxActionTestsBase { + public void testActionSend() { + final ExpectedActionKey expectedKey = ExpectedActionKey.newIconKey( + KeyboardIconsSet.NAME_SEND_KEY); + for (final InputMethodSubtype subtype : getAllSubtypesList()) { + final String tag = "send " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_SEND, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/LxxActionTestsBase.java b/tests/src/com/android/inputmethod/keyboard/action/LxxActionTestsBase.java new file mode 100644 index 000000000..70de9a6b8 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/LxxActionTestsBase.java @@ -0,0 +1,26 @@ +/* + * 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.action; + +import com.android.inputmethod.keyboard.KeyboardTheme; + +abstract class LxxActionTestsBase extends ActionTestsBase { + @Override + protected int getKeyboardThemeForTests() { + return KeyboardTheme.THEME_ID_LXX_LIGHT; + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/action/LxxActionUnspecifiedTests.java b/tests/src/com/android/inputmethod/keyboard/action/LxxActionUnspecifiedTests.java new file mode 100644 index 000000000..711ca2614 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/action/LxxActionUnspecifiedTests.java @@ -0,0 +1,37 @@ +/* + * 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.action; + +import android.test.suitebuilder.annotation.LargeTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +@LargeTest +public class LxxActionUnspecifiedTests extends LxxActionTestsBase { + public void testActionUnspecified() { + final ExpectedActionKey expectedKey = ExpectedActionKey.newIconKey( + KeyboardIconsSet.NAME_ENTER_KEY); + for (final InputMethodSubtype subtype : getAllSubtypesList()) { + final String tag = "unspecifiled " + + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype); + doTestActionKey(tag, subtype, EditorInfo.IME_ACTION_UNSPECIFIED, expectedKey); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java index 8e26e7fc7..1cdc78799 100644 --- a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java +++ b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java @@ -17,11 +17,11 @@ 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 static com.android.inputmethod.latin.common.Constants.CODE_UNSPECIFIED; import android.test.suitebuilder.annotation.SmallTest; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; @SmallTest public final class KeySpecParserTests extends KeySpecParserTestsBase { diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTestsBase.java b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTestsBase.java index b8cb11b6b..79cf10e84 100644 --- a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTestsBase.java +++ b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTestsBase.java @@ -19,8 +19,8 @@ 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 static com.android.inputmethod.latin.common.Constants.CODE_OUTPUT_TEXT; +import static com.android.inputmethod.latin.common.Constants.CODE_UNSPECIFIED; import android.test.AndroidTestCase; diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java index 3ffd0a96a..1474c8d27 100644 --- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java +++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java @@ -18,7 +18,7 @@ package com.android.inputmethod.keyboard.internal; import android.test.AndroidTestCase; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; public class KeyboardStateTestsBase extends AndroidTestCase implements MockKeyboardSwitcher.MockConstants { diff --git a/tests/src/com/android/inputmethod/keyboard/internal/LanguageOnSpacebarHelperTests.java b/tests/src/com/android/inputmethod/keyboard/internal/LanguageOnSpacebarHelperTests.java deleted file mode 100644 index 6ea27588e..000000000 --- a/tests/src/com/android/inputmethod/keyboard/internal/LanguageOnSpacebarHelperTests.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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.LanguageOnSpacebarHelper.FORMAT_TYPE_FULL_LOCALE; -import static com.android.inputmethod.keyboard.internal.LanguageOnSpacebarHelper.FORMAT_TYPE_LANGUAGE_ONLY; -import static com.android.inputmethod.keyboard.internal.LanguageOnSpacebarHelper.FORMAT_TYPE_NONE; - -import android.content.Context; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; -import android.view.inputmethod.InputMethodSubtype; - -import com.android.inputmethod.latin.RichInputMethodManager; -import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; -import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; - -import java.util.Arrays; -import java.util.List; -import java.util.Locale; - -@SmallTest -public class LanguageOnSpacebarHelperTests extends AndroidTestCase { - private final LanguageOnSpacebarHelper mLanguageOnSpacebarHelper = - new LanguageOnSpacebarHelper(); - - private RichInputMethodManager mRichImm; - - InputMethodSubtype EN_US_QWERTY; - InputMethodSubtype EN_GB_QWERTY; - InputMethodSubtype FR_AZERTY; - InputMethodSubtype FR_CA_QWERTY; - InputMethodSubtype FR_CH_SWISS; - InputMethodSubtype FR_CH_QWERTY; - InputMethodSubtype FR_CH_QWERTZ; - InputMethodSubtype ZZ_QWERTY; - - @Override - protected void setUp() throws Exception { - super.setUp(); - final Context context = getContext(); - RichInputMethodManager.init(context); - mRichImm = RichInputMethodManager.getInstance(); - SubtypeLocaleUtils.init(context); - - EN_US_QWERTY = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( - Locale.US.toString(), "qwerty"); - EN_GB_QWERTY = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( - Locale.UK.toString(), "qwerty"); - FR_AZERTY = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( - Locale.FRENCH.toString(), "azerty"); - FR_CA_QWERTY = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( - Locale.CANADA_FRENCH.toString(), "qwerty"); - FR_CH_SWISS = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( - "fr_CH", "swiss"); - FR_CH_QWERTZ = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( - "fr_CH", "qwertz"); - FR_CH_QWERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( - "fr_CH", "qwerty"); - ZZ_QWERTY = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( - SubtypeLocaleUtils.NO_LANGUAGE, "qwerty"); - } - - private static List<InputMethodSubtype> asList(final InputMethodSubtype ... subtypes) { - return Arrays.asList(subtypes); - } - - public void testOneSubtype() { - mLanguageOnSpacebarHelper.updateEnabledSubtypes(asList(EN_US_QWERTY)); - mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(true /* isSame */); - assertEquals("one same English (US)", FORMAT_TYPE_NONE, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(EN_US_QWERTY)); - assertEquals("one same NoLanguage", FORMAT_TYPE_FULL_LOCALE, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(ZZ_QWERTY)); - - mLanguageOnSpacebarHelper.updateEnabledSubtypes(asList(FR_AZERTY)); - mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(false /* isSame */); - assertEquals("one diff English (US)", FORMAT_TYPE_LANGUAGE_ONLY, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(EN_US_QWERTY)); - assertEquals("one diff NoLanguage", FORMAT_TYPE_FULL_LOCALE, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(ZZ_QWERTY)); - } - - public void testTwoSubtypes() { - mLanguageOnSpacebarHelper.updateEnabledSubtypes(asList(EN_US_QWERTY, FR_AZERTY)); - - mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(true /* isSame */); - assertEquals("two same English (US)", FORMAT_TYPE_LANGUAGE_ONLY, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(EN_US_QWERTY)); - assertEquals("two same French)", FORMAT_TYPE_LANGUAGE_ONLY, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(FR_AZERTY)); - assertEquals("two same NoLanguage", FORMAT_TYPE_FULL_LOCALE, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(ZZ_QWERTY)); - - mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(false /* isSame */); - assertEquals("two diff English (US)", FORMAT_TYPE_LANGUAGE_ONLY, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(EN_US_QWERTY)); - assertEquals("two diff French", FORMAT_TYPE_LANGUAGE_ONLY, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(FR_AZERTY)); - assertEquals("two diff NoLanguage", FORMAT_TYPE_FULL_LOCALE, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(ZZ_QWERTY)); - } - - public void testSameLanuageSubtypes() { - mLanguageOnSpacebarHelper.updateEnabledSubtypes( - asList(EN_US_QWERTY, EN_GB_QWERTY, FR_AZERTY, ZZ_QWERTY)); - - mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(true /* isSame */); - assertEquals("two same English (US)", FORMAT_TYPE_FULL_LOCALE, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(EN_US_QWERTY)); - assertEquals("two same English (UK)", FORMAT_TYPE_FULL_LOCALE, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(EN_GB_QWERTY)); - assertEquals("two same NoLanguage", FORMAT_TYPE_FULL_LOCALE, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(ZZ_QWERTY)); - - mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(false /* isSame */); - assertEquals("two diff English (US)", FORMAT_TYPE_FULL_LOCALE, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(EN_US_QWERTY)); - assertEquals("two diff English (UK)", FORMAT_TYPE_FULL_LOCALE, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(EN_GB_QWERTY)); - assertEquals("two diff NoLanguage", FORMAT_TYPE_FULL_LOCALE, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(ZZ_QWERTY)); - } - - public void testMultiSameLanuageSubtypes() { - mLanguageOnSpacebarHelper.updateEnabledSubtypes( - asList(FR_AZERTY, FR_CA_QWERTY, FR_CH_SWISS, FR_CH_QWERTY, FR_CH_QWERTZ)); - - mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(true /* isSame */); - assertEquals("multi same French", FORMAT_TYPE_LANGUAGE_ONLY, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(FR_AZERTY)); - assertEquals("multi same French (CA)", FORMAT_TYPE_FULL_LOCALE, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(FR_CA_QWERTY)); - assertEquals("multi same French (CH)", FORMAT_TYPE_LANGUAGE_ONLY, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(FR_CH_SWISS)); - assertEquals("multi same French (CH) (QWERTY)", FORMAT_TYPE_FULL_LOCALE, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(FR_CH_QWERTY)); - assertEquals("multi same French (CH) (QWERTZ)", FORMAT_TYPE_LANGUAGE_ONLY, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(FR_CH_QWERTZ)); - - mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(false /* isSame */); - assertEquals("multi diff French", FORMAT_TYPE_LANGUAGE_ONLY, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(FR_AZERTY)); - assertEquals("multi diff French (CA)", FORMAT_TYPE_FULL_LOCALE, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(FR_CA_QWERTY)); - assertEquals("multi diff French (CH)", FORMAT_TYPE_LANGUAGE_ONLY, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(FR_CH_SWISS)); - assertEquals("multi diff French (CH) (QWERTY)", FORMAT_TYPE_FULL_LOCALE, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(FR_CH_QWERTY)); - assertEquals("multi diff French (CH) (QWERTZ)", FORMAT_TYPE_LANGUAGE_ONLY, - mLanguageOnSpacebarHelper.getLanguageOnSpacebarFormatType(FR_CH_QWERTZ)); - } -} diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java index a353e5a35..4b2ec9588 100644 --- a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java +++ b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java @@ -18,7 +18,8 @@ package com.android.inputmethod.keyboard.internal; import android.text.TextUtils; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.event.Event; +import com.android.inputmethod.latin.common.Constants; import com.android.inputmethod.latin.utils.RecapitalizeStatus; public class MockKeyboardSwitcher implements KeyboardState.SwitchActions { @@ -26,7 +27,7 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions { // Argument for {@link KeyboardState#onPressKey} and {@link KeyboardState#onReleaseKey}. public static final boolean NOT_SLIDING = false; public static final boolean SLIDING = true; - // Argument for {@link KeyboardState#onCodeInput}. + // Argument for {@link KeyboardState#onEvent}. public static final boolean SINGLE = true; public static final boolean MULTI = false; public static final int CAP_MODE_OFF = Constants.TextUtils.CAP_MODE_OFF; @@ -183,7 +184,11 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions { } else { mAutoCapsState = mAutoCapsMode; } - mState.onCodeInput(code, mAutoCapsState, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE); + final Event event = + Event.createSoftwareKeypressEvent(code /* codePoint */, code /* keyCode */, + Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, + false /* isKeyRepeat */); + mState.onEvent(event, mAutoCapsState, RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE); } public void onFinishSlidingInput() { diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java index 922d2a8c8..8f4648c52 100644 --- a/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java +++ b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java @@ -16,52 +16,33 @@ package com.android.inputmethod.keyboard.internal; -import android.app.Instrumentation; import android.content.Context; import android.content.res.Resources; -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.MediumTest; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.inputmethod.latin.R; -import java.lang.reflect.Field; -import java.util.ArrayList; import java.util.Arrays; import java.util.Locale; -@MediumTest -public class MoreKeySpecSplitTests extends InstrumentationTestCase { +@SmallTest +public class MoreKeySpecSplitTests extends AndroidTestCase { private static final Locale TEST_LOCALE = Locale.ENGLISH; - final KeyboardTextsSet mTextsSet = new KeyboardTextsSet(); + private final KeyboardTextsSet mTextsSet = new KeyboardTextsSet(); @Override protected void setUp() throws Exception { super.setUp(); - final Instrumentation instrumentation = getInstrumentation(); - final Context targetContext = instrumentation.getTargetContext(); - mTextsSet.setLocale(TEST_LOCALE, targetContext); - final String[] testResourceNames = getAllResourceIdNames( - com.android.inputmethod.latin.tests.R.string.class); - final Context testContext = instrumentation.getContext(); - final Resources testRes = testContext.getResources(); - final String testResPackageName = testRes.getResourcePackageName( - // This dummy raw resource is needed to be able to load string resources from a test - // APK successfully. - com.android.inputmethod.latin.tests.R.raw.dummy_resource_for_testing); - mTextsSet.loadStringResourcesInternal(testRes, testResourceNames, testResPackageName); - } - - private static String[] getAllResourceIdNames(final Class<?> resourceIdClass) { - final ArrayList<String> names = new ArrayList<>(); - for (final Field field : resourceIdClass.getFields()) { - if (field.getType() == int.class) { - names.add(field.getName()); - } - } - return names.toArray(new String[names.size()]); + final Context targetContext = getContext(); + final Resources targetRes = targetContext.getResources(); + final String targetPackageName = targetRes.getResourcePackageName( + R.string.english_ime_name); + mTextsSet.setLocale(TEST_LOCALE, targetRes, targetPackageName); } - private static <T> void assertArrayEquals(final String message, final T[] expected, - final T[] actual) { + static <T> void assertArrayEquals(final String message, final T[] expected, final T[] actual) { if (expected == actual) { return; } @@ -109,14 +90,6 @@ public class MoreKeySpecSplitTests 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", ","); @@ -224,132 +197,14 @@ public class MoreKeySpecSplitTests extends InstrumentationTestCase { "\\!", "\\!TEXT/EMPTY_STRING"); } - public void testSplitResourceError() { - assertError("Incomplete resource name", "!text/", "!text/"); - assertError("Non existing resource", "!text/non_existing"); - } - - public void testSplitResourceZero() { - assertTextArray("Empty string", - "!text/empty_string"); - } - - public void testSplitResourceSingle() { - assertTextArray("Single char", - "!text/single_char", "a"); - assertTextArray("Space", - "!text/space", " "); - assertTextArray("Single label", - "!text/single_label", "abc"); - assertTextArray("Spaces", - "!text/spaces", " "); - assertTextArray("Spaces in label", - "!text/spaces_in_label", "a b c"); - assertTextArray("Spaces at beginning of label", - "!text/spaces_at_beginning_of_label", " abc"); - assertTextArray("Spaces at end of label", - "!text/spaces_at_end_of_label", "abc "); - assertTextArray("label surrounded by spaces", - "!text/label_surrounded_by_spaces", " abc "); - - assertTextArray("Escape and single char", - "\\\\!text/single_char", "\\\\a"); - } - - public void testSplitResourceSingleEscaped() { - assertTextArray("Escaped char", - "!text/escaped_char", "\\a"); - assertTextArray("Escaped comma", - "!text/escaped_comma", "\\,"); - assertTextArray("Escaped comma escape", - "!text/escaped_comma_escape", "a\\,\\"); - assertTextArray("Escaped escape", - "!text/escaped_escape", "\\\\"); - assertTextArray("Escaped label", - "!text/escaped_label", "a\\bc"); - assertTextArray("Escaped label at beginning", - "!text/escaped_label_at_beginning", "\\abc"); - assertTextArray("Escaped label at end", - "!text/escaped_label_at_end", "abc\\"); - assertTextArray("Escaped label with comma", - "!text/escaped_label_with_comma", "a\\,c"); - assertTextArray("Escaped label with comma at beginning", - "!text/escaped_label_with_comma_at_beginning", "\\,bc"); - assertTextArray("Escaped label with comma at end", - "!text/escaped_label_with_comma_at_end", "ab\\,"); - assertTextArray("Escaped label with successive", - "!text/escaped_label_with_successive", "\\,\\\\bc"); - assertTextArray("Escaped label with escape", - "!text/escaped_label_with_escape", "a\\\\c"); + public void testSplitTextReferenceError() { + assertError("Incomplete text name", "!text/", "!text/"); + assertError("Non existing text", "!text/non_existing"); } - public void testSplitResourceMulti() { - assertTextArray("Multiple chars", - "!text/multiple_chars", "a", "b", "c"); - assertTextArray("Multiple chars surrounded by spaces", - "!text/multiple_chars_surrounded_by_spaces", - " a ", " b ", " c "); - assertTextArray("Multiple labels", - "!text/multiple_labels", "abc", "def", "ghi"); - assertTextArray("Multiple labels surrounded by spaces", - "!text/multiple_labels_surrounded_by_spaces", " abc ", " def ", " ghi "); - } - - public void testSplitResourcetMultiEscaped() { - assertTextArray("Multiple chars with comma", - "!text/multiple_chars_with_comma", - "a", "\\,", "c"); - assertTextArray("Multiple chars with comma surrounded by spaces", - "!text/multiple_chars_with_comma_surrounded_by_spaces", - " a ", " \\, ", " c "); - assertTextArray("Multiple labels with escape", - "!text/multiple_labels_with_escape", - "\\abc", "d\\ef", "gh\\i"); - assertTextArray("Multiple labels with escape surrounded by spaces", - "!text/multiple_labels_with_escape_surrounded_by_spaces", - " \\abc ", " d\\ef ", " gh\\i "); - assertTextArray("Multiple labels with comma and escape", - "!text/multiple_labels_with_comma_and_escape", - "ab\\\\", "d\\\\\\,", "g\\,i"); - assertTextArray("Multiple labels with comma and escape surrounded by spaces", - "!text/multiple_labels_with_comma_and_escape_surrounded_by_spaces", - " ab\\\\ ", " d\\\\\\, ", " g\\,i "); - } - - public void testSplitMultipleResources() { - assertTextArray("Literals and resources", - "1,!text/multiple_chars,z", "1", "a", "b", "c", "z"); - assertTextArray("Literals and resources and escape at end", - "\\1,!text/multiple_chars,z\\", "\\1", "a", "b", "c", "z\\"); - assertTextArray("Multiple single resource chars and labels", - "!text/single_char,!text/single_label,!text/escaped_comma", - "a", "abc", "\\,"); - assertTextArray("Multiple single resource chars and labels 2", - "!text/single_char,!text/single_label,!text/escaped_comma_escape", - "a", "abc", "a\\,\\"); - assertTextArray("Multiple multiple resource chars and labels", - "!text/multiple_chars,!text/multiple_labels,!text/multiple_chars_with_comma", - "a", "b", "c", "abc", "def", "ghi", "a", "\\,", "c"); - assertTextArray("Concatenated resources", - "!text/multiple_chars!text/multiple_labels!text/multiple_chars_with_comma", - "a", "b", "cabc", "def", "ghia", "\\,", "c"); - assertTextArray("Concatenated resource and literal", - "abc!text/multiple_labels", - "abcabc", "def", "ghi"); - } - - public void testSplitIndirectReference() { - assertTextArray("Indirect", - "!text/indirect_string", "a", "b", "c"); - assertTextArray("Indirect with literal", - "1,!text/indirect_string_with_literal,2", "1", "x", "a", "b", "c", "y", "2"); - assertTextArray("Indirect2", - "!text/indirect2_string", "a", "b", "c"); - } - - public void testSplitInfiniteIndirectReference() { - assertError("Infinite indirection", - "1,!text/infinite_indirection,2", "1", "infinite", "<infinite>", "loop", "2"); + public void testSplitEmptyTextReference() { + // Note that morekeys_q of English locale is empty. + assertTextArray("Empty string", "!text/morekeys_q"); } public void testLabelReferece() { @@ -360,12 +215,6 @@ public class MoreKeySpecSplitTests extends InstrumentationTestCase { assertTextArray("Settings as more key", "!text/keyspec_settings", "!icon/settings_key|!code/key_settings"); - - assertTextArray("Indirect naviagte actions as more key", - "!text/keyspec_indirect_navigate_actions", - "!fixedColumnOrder!2", - "!hasLabels!", "Prev|!code/key_action_previous", - "!hasLabels!", "Next|!code/key_action_next"); } public void testUselessUpperCaseSpecifier() { @@ -394,14 +243,6 @@ public class MoreKeySpecSplitTests extends InstrumentationTestCase { assertTextArray("INDIRECT2", "!TEXT/INDIRECT2_STRING", "!TEXT/INDIRECT2_STRING"); - assertTextArray("Upper indirect", - "!text/upper_indirect_string", "!TEXT/MULTIPLE_CHARS"); - assertTextArray("Upper indirect with literal", - "1,!text/upper_indirect_string_with_literal,2", - "1", "x", "!TEXT/MULTIPLE_CHARS", "y", "2"); - assertTextArray("Upper indirect2", - "!text/upper_indirect2_string", "!TEXT/UPPER_INDIRECT_STRING"); - assertTextArray("UPPER INDIRECT", "!TEXT/upper_INDIRECT_STRING", "!TEXT/upper_INDIRECT_STRING"); assertTextArray("Upper INDIRECT with literal", @@ -413,9 +254,6 @@ public class MoreKeySpecSplitTests extends InstrumentationTestCase { assertTextArray("INFINITE INDIRECTION", "1,!TEXT/INFINITE_INDIRECTION,2", "1", "!TEXT/INFINITE_INDIRECTION", "2"); - assertTextArray("Upper infinite indirection", - "1,!text/upper_infinite_indirection,2", - "1", "infinite", "!TEXT/INFINITE_INDIRECTION", "loop", "2"); assertTextArray("Upper INFINITE INDIRECTION", "1,!TEXT/UPPER_INFINITE_INDIRECTION,2", "1", "!TEXT/UPPER_INFINITE_INDIRECTION", "2"); diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecStringReferenceTests.java b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecStringReferenceTests.java new file mode 100644 index 000000000..e06ecaedf --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecStringReferenceTests.java @@ -0,0 +1,284 @@ +/* + * 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 android.app.Instrumentation; +import android.content.Context; +import android.content.res.Resources; +import android.test.InstrumentationTestCase; +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.inputmethod.latin.tests.R; + +import java.util.Locale; + +@SmallTest +public class MoreKeySpecStringReferenceTests extends InstrumentationTestCase { + private static final Locale TEST_LOCALE = Locale.ENGLISH; + private final KeyboardTextsSet mTextsSet = new KeyboardTextsSet(); + + @Override + protected void setUp() throws Exception { + super.setUp(); + + final Instrumentation instrumentation = getInstrumentation(); + final Context testContext = instrumentation.getContext(); + final Resources testRes = testContext.getResources(); + final String testPackageName = testRes.getResourcePackageName(R.string.empty_string); + mTextsSet.setLocale(TEST_LOCALE, testRes, testPackageName); + } + + private void assertTextArray(final String message, final String value, + final String ... expectedArray) { + final String resolvedActual = mTextsSet.resolveTextReference(value); + final String[] actual = MoreKeySpec.splitKeySpecs(resolvedActual); + final String[] expected = (expectedArray.length == 0) ? null : expectedArray; + MoreKeySpecSplitTests.assertArrayEquals(message, expected, actual); + } + + private void assertError(final String message, final String value, final String ... expected) { + try { + assertTextArray(message, value, expected); + fail(message); + } catch (Exception pcpe) { + // success. + } + } + + public void testResolveNullText() { + assertEquals("resolve null", + mTextsSet.resolveTextReference(null), null); + } + + public void testResolveEmptyText() { + assertEquals("resolve empty text", + mTextsSet.resolveTextReference("!string/empty_string"), null); + } + + public void testSplitSingleEscaped() { + assertTextArray("Escaped !string", "\\!string", + "\\!string"); + assertTextArray("Escaped !string/", "\\!string/", + "\\!string/"); + assertTextArray("Escaped !STRING/", "\\!STRING/", + "\\!STRING/"); + assertTextArray("Escaped !string/name", "\\!string/empty_string", + "\\!string/empty_string"); + assertTextArray("Escaped !STRING/NAME", "\\!STRING/EMPTY_STRING", + "\\!STRING/EMPTY_STRING"); + } + + public void testSplitMultiEscaped() { + assertTextArray("Multiple escaped !string", "\\!,\\!string/empty_string", + "\\!", "\\!string/empty_string"); + assertTextArray("Multiple escaped !STRING", "\\!,\\!STRING/EMPTY_STRING", + "\\!", "\\!STRING/EMPTY_STRING"); + } + + public void testSplitStringReferenceError() { + assertError("Incomplete resource name", "!string/", "!string/"); + assertError("Non existing resource", "!string/non_existing"); + } + + public void testSplitEmptyStringReference() { + assertTextArray("Empty string", "!string/empty_string"); + } + + public void testSplitResourceSingle() { + assertTextArray("Single char", "!string/single_char", + "a"); + assertTextArray("Space", "!string/space", + " "); + assertTextArray("Single label", "!string/single_label", + "abc"); + assertTextArray("Spaces", "!string/spaces", + " "); + assertTextArray("Spaces in label", "!string/spaces_in_label", + "a b c"); + assertTextArray("Spaces at beginning of label", "!string/spaces_at_beginning_of_label", + " abc"); + assertTextArray("Spaces at end of label", "!string/spaces_at_end_of_label", + "abc "); + assertTextArray("label surrounded by spaces", "!string/label_surrounded_by_spaces", + " abc "); + assertTextArray("Escape and single char", "\\\\!string/single_char", + "\\\\a"); + } + + public void testSplitResourceSingleEscaped() { + assertTextArray("Escaped char", + "!string/escaped_char", "\\a"); + assertTextArray("Escaped comma", + "!string/escaped_comma", "\\,"); + assertTextArray("Escaped comma escape", + "!string/escaped_comma_escape", "a\\,\\"); + assertTextArray("Escaped escape", + "!string/escaped_escape", "\\\\"); + assertTextArray("Escaped label", + "!string/escaped_label", "a\\bc"); + assertTextArray("Escaped label at beginning", + "!string/escaped_label_at_beginning", "\\abc"); + assertTextArray("Escaped label at end", + "!string/escaped_label_at_end", "abc\\"); + assertTextArray("Escaped label with comma", + "!string/escaped_label_with_comma", "a\\,c"); + assertTextArray("Escaped label with comma at beginning", + "!string/escaped_label_with_comma_at_beginning", "\\,bc"); + assertTextArray("Escaped label with comma at end", + "!string/escaped_label_with_comma_at_end", "ab\\,"); + assertTextArray("Escaped label with successive", + "!string/escaped_label_with_successive", "\\,\\\\bc"); + assertTextArray("Escaped label with escape", + "!string/escaped_label_with_escape", "a\\\\c"); + } + + public void testSplitResourceMulti() { + assertTextArray("Multiple chars", + "!string/multiple_chars", "a", "b", "c"); + assertTextArray("Multiple chars surrounded by spaces", + "!string/multiple_chars_surrounded_by_spaces", + " a ", " b ", " c "); + assertTextArray("Multiple labels", + "!string/multiple_labels", "abc", "def", "ghi"); + assertTextArray("Multiple labels surrounded by spaces", + "!string/multiple_labels_surrounded_by_spaces", " abc ", " def ", " ghi "); + } + + public void testSplitResourcetMultiEscaped() { + assertTextArray("Multiple chars with comma", + "!string/multiple_chars_with_comma", + "a", "\\,", "c"); + assertTextArray("Multiple chars with comma surrounded by spaces", + "!string/multiple_chars_with_comma_surrounded_by_spaces", + " a ", " \\, ", " c "); + assertTextArray("Multiple labels with escape", + "!string/multiple_labels_with_escape", + "\\abc", "d\\ef", "gh\\i"); + assertTextArray("Multiple labels with escape surrounded by spaces", + "!string/multiple_labels_with_escape_surrounded_by_spaces", + " \\abc ", " d\\ef ", " gh\\i "); + assertTextArray("Multiple labels with comma and escape", + "!string/multiple_labels_with_comma_and_escape", + "ab\\\\", "d\\\\\\,", "g\\,i"); + assertTextArray("Multiple labels with comma and escape surrounded by spaces", + "!string/multiple_labels_with_comma_and_escape_surrounded_by_spaces", + " ab\\\\ ", " d\\\\\\, ", " g\\,i "); + } + + public void testSplitMultipleResources() { + assertTextArray("Literals and resources", + "1,!string/multiple_chars,z", + "1", "a", "b", "c", "z"); + assertTextArray("Literals and resources and escape at end", + "\\1,!string/multiple_chars,z\\", + "\\1", "a", "b", "c", "z\\"); + assertTextArray("Multiple single resource chars and labels", + "!string/single_char,!string/single_label,!string/escaped_comma", + "a", "abc", "\\,"); + assertTextArray("Multiple single resource chars and labels 2", + "!string/single_char,!string/single_label,!string/escaped_comma_escape", + "a", "abc", "a\\,\\"); + assertTextArray("Multiple multiple resource chars and labels", + "!string/multiple_chars,!string/multiple_labels,!string/multiple_chars_with_comma", + "a", "b", "c", "abc", "def", "ghi", "a", "\\,", "c"); + assertTextArray("Concatenated resources", + "!string/multiple_chars!string/multiple_labels!string/multiple_chars_with_comma", + "a", "b", "cabc", "def", "ghia", "\\,", "c"); + assertTextArray("Concatenated resource and literal", + "abc!string/multiple_labels", + "abcabc", "def", "ghi"); + } + + public void testSplitIndirectReference() { + assertTextArray("Indirect", + "!string/indirect_string", "a", "b", "c"); + assertTextArray("Indirect with literal", + "1,!string/indirect_string_with_literal,2", "1", "x", "a", "b", "c", "y", "2"); + assertTextArray("Indirect2", + "!string/indirect2_string", "a", "b", "c"); + } + + public void testSplitInfiniteIndirectReference() { + assertError("Infinite indirection", + "1,!string/infinite_indirection,2", "1", "infinite", "<infinite>", "loop", "2"); + } + + public void testLabelReferece() { + assertTextArray("Indirect naviagte actions as more key", + "!string/keyspec_indirect_navigate_actions", + "!fixedColumnOrder!2", + "!hasLabels!", "ActionPrevious|!code/key_action_previous", + "!hasLabels!", "ActionNext|!code/key_action_next"); + } + + public void testUselessUpperCaseSpecifier() { + assertTextArray("EMPTY STRING", + "!STRING/EMPTY_STRING", "!STRING/EMPTY_STRING"); + + assertTextArray("SINGLE CHAR", + "!STRING/SINGLE_CHAR", "!STRING/SINGLE_CHAR"); + assertTextArray("Escape and SINGLE CHAR", + "\\\\!STRING/SINGLE_CHAR", "\\\\!STRING/SINGLE_CHAR"); + + assertTextArray("MULTIPLE CHARS", + "!STRING/MULTIPLE_CHARS", "!STRING/MULTIPLE_CHARS"); + + assertTextArray("Literals and RESOURCES", + "1,!STRING/MULTIPLE_CHARS,z", "1", "!STRING/MULTIPLE_CHARS", "z"); + assertTextArray("Multiple single RESOURCE chars and LABELS 2", + "!STRING/SINGLE_CHAR,!STRING/SINGLE_LABEL,!STRING/ESCAPED_COMMA_ESCAPE", + "!STRING/SINGLE_CHAR", "!STRING/SINGLE_LABEL", "!STRING/ESCAPED_COMMA_ESCAPE"); + + assertTextArray("INDIRECT", + "!STRING/INDIRECT_STRING", "!STRING/INDIRECT_STRING"); + assertTextArray("INDIRECT with literal", + "1,!STRING/INDIRECT_STRING_WITH_LITERAL,2", + "1", "!STRING/INDIRECT_STRING_WITH_LITERAL", "2"); + assertTextArray("INDIRECT2", + "!STRING/INDIRECT2_STRING", "!STRING/INDIRECT2_STRING"); + + assertTextArray("Upper indirect", + "!string/upper_indirect_string", "!STRING/MULTIPLE_CHARS"); + assertTextArray("Upper indirect with literal", + "1,!string/upper_indirect_string_with_literal,2", + "1", "x", "!STRING/MULTIPLE_CHARS", "y", "2"); + assertTextArray("Upper indirect2", + "!string/upper_indirect2_string", "!STRING/UPPER_INDIRECT_STRING"); + + assertTextArray("UPPER INDIRECT", + "!STRING/upper_INDIRECT_STRING", "!STRING/upper_INDIRECT_STRING"); + assertTextArray("Upper INDIRECT with literal", + "1,!STRING/upper_INDIRECT_STRING_WITH_LITERAL,2", + "1", "!STRING/upper_INDIRECT_STRING_WITH_LITERAL", "2"); + assertTextArray("Upper INDIRECT2", + "!STRING/upper_INDIRECT2_STRING", "!STRING/upper_INDIRECT2_STRING"); + + assertTextArray("INFINITE INDIRECTION", + "1,!STRING/INFINITE_INDIRECTION,2", "1", "!STRING/INFINITE_INDIRECTION", "2"); + + assertTextArray("Upper infinite indirection", + "1,!string/upper_infinite_indirection,2", + "1", "infinite", "!STRING/INFINITE_INDIRECTION", "loop", "2"); + assertTextArray("Upper INFINITE INDIRECTION", + "1,!STRING/UPPER_INFINITE_INDIRECTION,2", + "1", "!STRING/UPPER_INFINITE_INDIRECTION", "2"); + + assertTextArray("INDIRECT NAVIGATE ACTIONS AS MORE KEY", + "!STRING/INDIRECT_NAVIGATE_ACTIONS_AS_MORE_KEY", + "!STRING/INDIRECT_NAVIGATE_ACTIONS_AS_MORE_KEY"); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecTests.java b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecTests.java index 6c0d74941..d9e5d1033 100644 --- a/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecTests.java +++ b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecTests.java @@ -17,11 +17,11 @@ 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 static com.android.inputmethod.latin.common.Constants.CODE_UNSPECIFIED; import android.test.suitebuilder.annotation.SmallTest; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; import java.util.Arrays; import java.util.Locale; @@ -78,6 +78,7 @@ public final class MoreKeySpecTests extends KeySpecParserTestsBase { assertArrayEquals(message, expected, actual); } + @SuppressWarnings("static-method") public void testEmptyEntry() { assertInsertAdditionalMoreKeys("null more keys and null additons", null, @@ -106,6 +107,7 @@ public final class MoreKeySpecTests extends KeySpecParserTestsBase { new String[] { "a", "A", "b", "B", "c", "d" }); } + @SuppressWarnings("static-method") public void testInsertAdditionalMoreKeys() { // Escaped marker. assertInsertAdditionalMoreKeys("escaped marker", @@ -306,6 +308,7 @@ public final class MoreKeySpecTests extends KeySpecParserTestsBase { assertArrayEquals(message, expected, actual); } + @SuppressWarnings("static-method") public void testGetBooleanValue() { assertGetBooleanValue("Has label", HAS_LABEL, new String[] { HAS_LABEL, "a", "b", "c" }, @@ -345,6 +348,7 @@ public final class MoreKeySpecTests extends KeySpecParserTestsBase { assertArrayEquals(message, expected, actual); } + @SuppressWarnings("static-method") public void testGetIntValue() { assertGetIntValue("Fixed column order 3", FIXED_COLUMN_ORDER, -1, new String[] { FIXED_COLUMN_ORDER + "3", "a", "b", "c" }, diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Arabic.java b/tests/src/com/android/inputmethod/keyboard/layout/Arabic.java index 3f85e4baa..ff05f92c2 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Arabic.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Arabic.java @@ -18,26 +18,25 @@ package com.android.inputmethod.keyboard.layout; import com.android.inputmethod.keyboard.layout.Symbols.RtlSymbols; import com.android.inputmethod.keyboard.layout.SymbolsShifted.RtlSymbolsShifted; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; import java.util.Locale; public final class Arabic extends LayoutBase { private static final String LAYOUT_NAME = "arabic"; - public Arabic(final LayoutCustomizer customizer) { - super(customizer, ArabicSymbols.class, ArabicSymbolsShifted.class); + public Arabic(final Locale locale) { + super(new ArabicCustomizer(locale), ArabicSymbols.class, ArabicSymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class ArabicCustomizer extends LayoutCustomizer { - public ArabicCustomizer(final Locale locale) { - super(locale); - } + private static class ArabicCustomizer extends LayoutCustomizer { + ArabicCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getAlphabetKey() { return ARABIC_ALPHABET_KEY; } @@ -141,12 +140,11 @@ public final class Arabic extends LayoutBase { ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) { if (isPhone) { return ALPHABET_COMMON; - } else { - final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON); - // U+0626: "ئ" ARABIC LETTER YEH WITH HAMZA ABOVE - builder.insertKeysAtRow(3, 2, "\u0626"); - return builder.build(); } + final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON); + // U+0626: "ئ" ARABIC LETTER YEH WITH HAMZA ABOVE + builder.insertKeysAtRow(3, 2, "\u0626"); + return builder.build(); } @Override diff --git a/tests/src/com/android/inputmethod/keyboard/layout/ArmenianPhonetic.java b/tests/src/com/android/inputmethod/keyboard/layout/ArmenianPhonetic.java index 2cecedceb..cbbeff4a7 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/ArmenianPhonetic.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/ArmenianPhonetic.java @@ -16,9 +16,10 @@ package com.android.inputmethod.keyboard.layout; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; import java.util.Locale; @@ -28,15 +29,16 @@ import java.util.Locale; public final class ArmenianPhonetic extends LayoutBase { private static final String LAYOUT_NAME = "armenian_phonetic"; - public ArmenianPhonetic(final LayoutCustomizer customizer) { - super(customizer, ArmenianSymbols.class, ArmenianSymbolsShifted.class); + public ArmenianPhonetic(final Locale locale) { + super(new ArmenianPhoneticCustomizer(locale), ArmenianSymbols.class, + ArmenianSymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class ArmenianPhoneticCustomizer extends LayoutCustomizer { - public ArmenianPhoneticCustomizer(final Locale locale) { super(locale); } + private static class ArmenianPhoneticCustomizer extends LayoutCustomizer { + ArmenianPhoneticCustomizer(final Locale locale) { super(locale); } @Override public int getNumberOfRows() { return 5; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Azerty.java b/tests/src/com/android/inputmethod/keyboard/layout/Azerty.java index a0949637b..f3176d09d 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Azerty.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Azerty.java @@ -17,6 +17,7 @@ package com.android.inputmethod.keyboard.layout; import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Bengali.java b/tests/src/com/android/inputmethod/keyboard/layout/Bengali.java index 2101ddf33..339cab444 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Bengali.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Bengali.java @@ -16,11 +16,9 @@ package com.android.inputmethod.keyboard.layout; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; - -import java.util.Locale; /** * The Bengali keyboard. @@ -35,32 +33,6 @@ public final class Bengali extends LayoutBase { @Override public String getName() { return LAYOUT_NAME; } - public static class BengaliCustomizer extends LayoutCustomizer { - public BengaliCustomizer(final Locale locale) { super(locale); } - - @Override - public ExpectedKey getAlphabetKey() { return BENGALI_ALPHABET_KEY; } - - @Override - public ExpectedKey[] getOtherCurrencyKeys() { - return SymbolsShifted.CURRENCIES_OTHER_GENERIC; - } - - @Override - public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) { return EMPTY_KEYS; } - - @Override - public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { - return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS; - } - - // U+0995: "क" BENGALI LETTER KA - // U+0996: "ख" BENGALI LETTER KHA - // U+0997: "ग" BENGALI LETTER GA - private static final ExpectedKey BENGALI_ALPHABET_KEY = key( - "\u0995\u0996\u0997", Constants.CODE_SWITCH_ALPHA_SYMBOL); - } - @Override ExpectedKey[][] getCommonAlphabetLayout(boolean isPhone) { return ALPHABET_COMMON; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/BengaliAkkhor.java b/tests/src/com/android/inputmethod/keyboard/layout/BengaliAkkhor.java new file mode 100644 index 000000000..bb1dc10fb --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/BengaliAkkhor.java @@ -0,0 +1,497 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout; + +import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +/** + * The Bengali Akkhor keyboard. + */ +public final class BengaliAkkhor extends LayoutBase { + private static final String LAYOUT_NAME = "bengali_akkhor"; + + public BengaliAkkhor(final LayoutCustomizer customizer) { + super(customizer, Symbols.class, SymbolsShifted.class); + } + + @Override + public String getName() { return LAYOUT_NAME; } + + @Override + ExpectedKey[][] getCommonAlphabetLayout(boolean isPhone) { return ALPHABET_COMMON; } + + @Override + ExpectedKey[][] getCommonAlphabetShiftLayout(boolean isPhone, final int elementId) { + if (elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) { + return getCommonAlphabetLayout(isPhone); + } + return ALPHABET_SHIFTED_COMMON; + } + + private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder() + .setKeysOfRow(1, + // U+09A7: "ধ" BENGALI LETTER DHA + // U+09E7: "১" BENGALI DIGIT ONE + // U+09A7/U+09CD/U+09AC: + // "ধ্ব্র" BENGALI LETTER DHA/BENGALI SIGN VIRAMA/BENGALI LETTER BA + // U+09A7/U+09CD/U+09AF: + // "ধ্য্র" BENGALI LETTER DHA/BENGALI SIGN VIRAMA/BENGALI LETTER YA + // U+09A7/U+09CD/U+09B0: + // "ধ্র" BENGALI LETTER DHA/BENGALI SIGN VIRAMA/BENGALI LETTER RA + key("\u09A7", joinMoreKeys("\u09E7", "\u09A7\u09CD\u09AC", "\u09A7\u09CD\u09AF", + "\u09A7\u09CD\u09B0")), + // U+09A5: "থ" BENGALI LETTER THA + // U+09E8: "২" BENGALI DIGIT TWO + // U+09A5/U+09CD/U+09AF: + // "থ্য" BENGALI LETTER THA/BENGALI SIGN VIRAMA/BENGALI LETTER YA + // U+09A5/U+09CD/U+09B0: + // "থ্র" BENGALI LETTER THA/BENGALI SIGN VIRAMA/BENGALI LETTER RA + key("\u09A5", joinMoreKeys("\u09E8", "\u09A5\u09CD\u09AF", + "\u09A5\u09CD\u09B0")), + // U+09C7: "ে" BENGALI VOWEL SIGN E + // U+09E9: "৩" BENGALI DIGIT THREE + // U+098F: "এ" BENGALI LETTER E + key("\u09C7", joinMoreKeys("\u09E9", "\u098F")), + // U+09B0: "র" BENGALI LETTER RA + // U+09EA: "৪" BENGALI DIGIT FOUR + key("\u09B0", joinMoreKeys("\u09EA")), + // U+09A4: "ত" BENGALI LETTER TA + // U+09EB: "৫" BENGALI DIGIT FIVE + // U+09CE: "ৎ" BENGALI LETTER KHANDA TA + // U+09A4/U+09CD/U+09A4: + // "ত্ত" BENGALI LETTER TA/BENGALI SIGN VIRAMA/BENGALI LETTER TA + // U+09A4/U+09CD/U+09A8: + // "ত্ন" BENGALI LETTER TA/BENGALI SIGN VIRAMA/BENGALI LETTER NA + // U+09A4/U+09CD/U+09AC: + // "ত্ব" BENGALI LETTER TA/BENGALI SIGN VIRAMA/BENGALI LETTER BA + // U+09A4/U+09CD/U+09AE: + // "ত্ম" BENGALI LETTER TA/BENGALI SIGN VIRAMA/BENGALI LETTER MA + key("\u09A4", joinMoreKeys("\u09EB", "\u09CE", "\u09A4\u09CD\u09A4", + "\u09A4\u09CD\u09A8", "\u09A4\u09CD\u09AC", "\u09A4\u09CD\u09AE")), + // U+09DF: "য়" BENGALI LETTER YYA + // U+09EC: "৬" BENGALI DIGIT SIX + key("\u09DF", joinMoreKeys("\u09EC")), + // U+09C1: "ু" BENGALI VOWEL SIGN U + // U+09ED: "৭" BENGALI DIGIT SEVEN + // U+0989: "উ" BENGALI LETTER U + key("\u09C1", joinMoreKeys("\u09ED", "\u0989")), + // U+09BF: "ি" BENGALI VOWEL SIGN I + // U+09EE: "৮" BENGALI DIGIT EIGHT + // U+0987: "ই BENGALI LETTER I + key("\u09Bf", joinMoreKeys("\u09EE", "\u0987")), + // U+09CB: "ো" BENGALI VOWEL SIGN O + // U+09EF: "৯" BENGALI DIGIT NINE + // U+0993: "ও" BENGALI LETTER O + key("\u09CB", joinMoreKeys("\u09EF", "\u0993")), + // U+09AA: "প" BENGALI LETTER PA + // U+09E6: "০" BENGALI DIGIT ZERO + // U+09AA/U+09CD/U+09A4: + // "প্ত" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER TA + // U+09AA/U+09CD/U+09A8: + // "প্ন" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER NA + // U+09AA/U+09CD/U+09AA: + // "প্প" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER PA + // U+09AA/U+09CD/U+09AF: + // "প্য" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER YA + // U+09AA/U+09CD/U+09B0: + // "প্র" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER RA + // U+09AA/U+09CD/U+09B2: + // "প্ল" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER LA + // U+09AA/U+09CD/U+09B8: + // "প্স" BENGALI LETTER PA/BENGALI SIGN VIRAMA/BENGALI LETTER SA + key("\u09AA", joinMoreKeys("\u09E6", "\u09AA\u09CD\u09A4", "\u09AA\u09CD\u09A8", + "\u09AA\u09CD\u09AA", "\u09AA\u09CD\u09AF", "\u09AA\u09CD\u09B0", + "\u09AA\u09CD\u09B2", "\u09AA\u09CD\u09B8")), + // U+0986: "আ" BENGALI LETTER AA + key("\u0986")) + .setKeysOfRow(2, + // U+09BE: "া BENGALI VOWEL SIGN AA + // U+0986: "আ" BENGALI LETTER AA + key("\u09BE", moreKey("\u0986")), + // U+09B8: "স" BENGALI LETTER SA + // U+09B8/U+09CD/U+09AC: + // "স্ব" BENGALI LETTER SA/BENGALI SIGN VIRAMA/BENGALI LETTER BA + // U+09B8/U+09CD/U+09A4: + // "স্ত" BENGALI LETTER SA/BENGALI SIGN VIRAMA/BENGALI LETTER TA + // U+09B8/U+09CD/U+099F: + // "স্ট" BENGALI LETTER SA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA + // U+09B8/U+09CD/U+0995: + // "স্ক" BENGALI LETTER SA/BENGALI SIGN VIRAMA/BENGALI LETTER KA + // U+09B8/U+09CD/U+09AA: + // "স্প" BENGALI LETTER SA/BENGALI SIGN VIRAMA/BENGALI LETTER PA + key("\u09B8", joinMoreKeys("\u09B8\u09CD\u09AC", "\u09B8\u09CD\u09A4", + "\u09B8\u09CD\u099F", "\u09B8\u09CD\u0995", "\u09B8\u09CD\u09AA")), + // U+09A6: "দ" BENGALI LETTER DA + // U+09A6/U+09CD/U+09A6: + // "দ্দ" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER DA + // U+09A6/U+09CD/U+09A7: + // "দ্ধ" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER DHA + // U+09A6/U+09CD/U+09AC: + // "দ্ব" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER BA + // U+09A6/U+09CD/U+09AD: + // "দ্ভ" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER BHA + // U+09A6/U+09CD/U+09AE: + // "দ্ম" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER MA + // U+09A6/U+09CD/U+09AF: + // "দ্য" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER YA + // U+09A6/U+09CD/U+09B0: + // "দ্র" BENGALI LETTER DA/BENGALI SIGN VIRAMA/BENGALI LETTER RA + key("\u09A6", joinMoreKeys("\u09A6\u09CD\u09A6", "\u09A6\u09CD\u09A7", + "\u09A6\u09CD\u09AC", "\u09A6\u09CD\u09AD", "\u09A6\u09CD\u09AE", + "\u09A6\u09CD\u09AF", "\u09A6\u09CD\u09B0")), + // U+09C3: "ৃ" BENGALI VOWEL SIGN VOCALIC R + // U+098B: "ঋ" BENGALI LETTER VOCALIC R + key("\u09C3", moreKey("\u098B")), + // U+0997: "গ" BENGALI LETTER GA + // U+0997/U+09CD/U+09A7: + // "গ্ধ" BENGALI LETTER GA/BENGALI SIGN VIRAMA/BENGALI LETTER DH A + // U+0997/U+09CD/U+09B0: + // "গ্র" BENGALI LETTER GA/BENGALI SIGN VIRAMA/BENGALI LETTER RA + // U+0997/U+09CD/U+09B2: + // "গ্ল" BENGALI LETTER GA/BENGALI SIGN VIRAMA/BENGALI LETTER LA + // U+0997/U+09CD/U+09A8: + // "গ্ন" BENGALI LETTER GA/BENGALI SIGN VIRAMA/BENGALI LETTER NA + key("\u0997", joinMoreKeys("\u0997\u09CD\u09A7", "\u0997\u09CD\u09B0", + "\u0997\u09CD\u09B2", "\u0997\u09CD\u09A8")), + // U+09CD: "্" BENGALI SIGN VIRAMA + key("\u09CD"), + // U+099C: "জ" BENGALI LETTER JA + // U+099C/U+09CD/U+099E: + // "জ্ঞ" BENGALI LETTER JA/BENGALI SIGN VIRAMA/BENGALI LETTER NYA + // U+099C/U+09CD/U+099C: + // "জ্জ" BENGALI LETTER JA/BENGALI SIGN VIRAMA/BENGALI LETTER JA + // U+099C/U+09CD/U+09AF: + // "জ্ব" BENGALI LETTER JA/BENGALI SIGN VIRAMA/BENGALI LETTER YA + // U+099C/U+09CD/U+09AC: + // "জ্য" BENGALI LETTER JA/BENGALI SIGN VIRAMA/BENGALI LETTER BA + // U+099C/U+09CD/U+09B0: + // "জ্র" BENGALI LETTER JA/BENGALI SIGN VIRAMA/BENGALI LETTER RA + key("\u099C", joinMoreKeys("\u099C\u09CD\u099E", "\u099C\u09CD\u099C", + "\u099C\u09CD\u09AF", "\u099C\u09CD\u09AC", "\u099C\u09CD\u09B0")), + // U+0995: "ক" BENGALI LETTER KA + // U+0995/U+09CD/U+09B7: + // "ক্ষ" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER SSA + // U+0995/U+09CD/U+0995: + // "ক্ক" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER KA + // U+0995/U+09CD/U+099F: + // "ক্ট" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA + // U+0995/U+09CD/U+09A4: + // "ক্ত" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER TA + // U+0995/U+09CD/U+09B0: + // "ক্র" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER RA + // U+0995/U+09CD/U+09B8: + // "ক্স" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER SA + // U+0995/U+09CD/U+09B2: + // "ক্ল" BENGALI LETTER KA/BENGALI SIGN VIRAMA/BENGALI LETTER LA + key("\u0995", joinMoreKeys("\u0995\u09CD\u09B7", "\u0995\u09CD\u0995", + "\u0995\u09CD\u099F", "\u0995\u09CD\u09A4", "\u0995\u09CD\u09B0", + "\u0995\u09CD\u09B8", "\u0995\u09CD\u09B2")), + // U+09B2: "ল" BENGALI LETTER LA + // U+09B2/U+09CD/U+0995: + // "ল্ক" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER KA + // U+09B2/U+09CD/U+0997: + // "ল্গ" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER GA + // U+09B2/U+09CD/U+099F: + // "ল্ট" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA + // U+09B2/U+09CD/U+09A1: + // "ল্ড" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER DDA + // U+09B2/U+09CD/U+09A4: + // "ল্ত" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER TA + // U+09B2/U+09CD/U+09A6: + // "ল্দ" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER DA + // U+09B2/U+09CD/U+09A7: + // "ল্ধ" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER DHA + // U+09B2/U+09CD/U+09AA: + // "ল্প" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER PA + // U+09B2/U+09CD/U+09AB: + // "ল্ফ" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER PHA + // U+09B2/U+09CD/U+09AC: + // "ল্ব" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER BA + // U+09B2/U+09CD/U+09AE: + // "ল্ম" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER MA + // U+09B2/U+09CD/U+09B2: + // "ল্ল" BENGALI LETTER LA/BENGALI SIGN VIRAMA/BENGALI LETTER LA + key("\u09B2", joinMoreKeys("\u09B2\u09CD\u0995", "\u09B2\u09CD\u0997", + "\u09B2\u09CD\u099F", "\u09B2\u09CD\u09A1", "\u09B2\u09CD\u09A4", + "\u09B2\u09CD\u09A6", "\u09B2\u09CD\u09A7", "\u09B2\u09CD\u09AA", + "\u09B2\u09CD\u09AB", "\u09B2\u09CD\u09AC", "\u09B2\u09CD\u09AE", + "\u09B2\u09CD\u09B2")), + // U+0987: "ই" BENGALI LETTER I + key("\u0987"), + // U+0989: "উ" BENGALI LETTER U + key("\u0989")) + .setKeysOfRow(3, + // U+09AF: "য" BENGALI LETTER YA + // U+09CD/U+09AF: "্য" BENGALI SIGN VIRAMA/BENGALI LETTER YA + key("\u09AF", moreKey("\u09CD\u09AF")), + // U+09B7: "ষ" BENGALI LETTER SSA + // U+09B7/U+09CD/U+0995: + // "ষ্ক" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER KA + // U+09B7/U+09CD/U+099F: + // "ষ্ট" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA + // U+09B7/U+09CD/U+09A0: + // "ষ্ঠ" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER TTHA + // U+09B7/U+09CD/U+09A3: + // "ষ্ণ" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER NNA + // U+09B7/U+09CD/U+09AA: + // "ষ্প" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER PA + // U+09B7/U+09CD/U+09AB: + // "ষ্ফ" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER PHA + // U+09B7/U+09CD/U+09AE: + // "ষ্ম" BENGALI LETTER SSA/BENGALI SIGN VIRAMA/BENGALI LETTER MA + key("\u09B7", joinMoreKeys("\u09B7\u09CD\u0995", "\u09B7\u09CD\u099F", + "\u09B7\u09CD\u09A0", "\u09B7\u09CD\u09A3", "\u09B7\u09CD\u09AA", + "\u09B7\u09CD\u09AB", "\u09B7\u09CD\u09AE")), + // U+099A: "চ" BENGALI LETTER CA + // U+099A/U+09CD/U+099A: + // "চ্চ" BENGALI LETTER CA/BENGALI SIGN VIRAMA/BENGALI LETTER CA + // U+099A/U+09CD/U+099B: + // "চ্ছ" BENGALI LETTER CA/BENGALI SIGN VIRAMA/BENGALI LETTER CHA + key("\u099A", joinMoreKeys("\u099A\u09CD\u099A", "\u099A\u09CD\u099B")), + // U+09AD: "ভ" BENGALI LETTER BHA + // U+09AD/U+09CD/U+09AF: + // "ভ্" BENGALI LETTER BHA/BENGALI SIGN VIRAMA/BENGALI LETTER YA + // U+09AD/U+09CD/U+09B0: + // "ভ্র" BENGALI LETTER BHA/BENGALI SIGN VIRAMA/BENGALI LETTER RA + // U+09AD/U+09CD/U+09B2: + // "ভ্ল" BENGALI LETTER BHA/BENGALI SIGN VIRAMA/BENGALI LETTER LA + key("\u09AD", joinMoreKeys("\u09AD\u09CD\u09AF", "\u09AD\u09CD\u09B0", + "\u09AD\u09CD\u09B2")), + // U+09AC: "ব" BENGALI LETTER BA + // U+09CD/U+09AC: "্ব" BENGALI SIGN VIRAMA/BENGALI LETTER BA + // U+09AC/U+09CD/U+09B0: + // "ব্র" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER RA + // U+09AC/U+09CD/U+099C: + // "ব্জ" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER JA + // U+09AC/U+09CD/U+09A6: + // "ব্দ" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER DA + // U+09AC/U+09CD/U+09A7: + // "ব্ধ" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER DHA + // U+09AC/U+09CD/U+09AC: + // "ব্ব" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER BA + // U+09AC/U+09CD/U+09B2: + // "ব্ল" BENGALI LETTER BA/BENGALI SIGN VIRAMA/BENGALI LETTER LA + // U+09F1: "ৱ" BENGALI LETTER RA WITH MIDDLE DIAGONAL + // U+09F0: "ৰ" BENGALI LETTER RA WITH LOWER DIAGONAL + key("\u09AC", joinMoreKeys("\u09CD\u09AC", "\u09AC\u09CD\u09B0", + "\u09AC\u09CD\u099C", "\u09AC\u09CD\u09A6", "\u09AC\u09CD\u09A7", + "\u09AC\u09CD\u09AC", "\u09AC\u09CD\u09B2", "\u09F1", "\u09F0")), + // U+09A8: "ন" BENGALI LETTER NA + // U+09A8/U+09CD/U+09A4: + // "ন্ত" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER TA + // U+09A8/U+09CD/U+09A5: + // "ন্থ" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER THA + // U+09A8/U+09CD/U+099F: + // "ন্ট" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA + // U+09A8/U+09CD/U+09A6: + // "ন্দ" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER DA + // U+09A8/U+09CD/U+09A7: + // "ন্ধ" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER DHA + // U+09A8/U+09CD/U+09A1: + // "ন্ড" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER DDA + // U+09A8/U+09CD/U+09A8: + // "ন্ন" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER NA + // U+09A8/U+09CD/U+09AC: + // "ন্ব" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER BA + // U+09A8/U+09CD/U+09AE: + // "ন্ম" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER MA + // U+09A8/U+09CD/U+09B8: + // "ন্স" BENGALI LETTER NA/BENGALI SIGN VIRAMA/BENGALI LETTER SA + key("\u09A8", joinMoreKeys("\u09A8\u09CD\u09A4", "\u09A8\u09CD\u09A5", + "\u09A8\u09CD\u099F", "\u09A8\u09CD\u09A6", "\u09A8\u09CD\u09A7", + "\u09A8\u09CD\u09A1", "\u09A8\u09CD\u09A8", "\u09A8\u09CD\u09AC", + "\u09A8\u09CD\u09AE", "\u09A8\u09CD\u09B8")), + // U+09AE: "ম" BENGALI LETTER MA + // U+09AE/U+09CD/U+09A8: + // "ম্ন" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER NA + // U+09AE/U+09CD/U+09AA: + // "ম্প" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER PA + // U+09AE/U+09CD/U+09AC: + // "ম্ব" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER BA + // U+09AE/U+09CD/U+09AD: + // "ম্ভ" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER BHA + // U+09AE/U+09CD/U+09AE: + // "ম্ম" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER MA + // U+09AE/U+09CD/U+09B0: + // "ম্র" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER RA + // U+09AE/U+09CD/U+09B2: + // "ম্ল" BENGALI LETTER MA/BENGALI SIGN VIRAMA/BENGALI LETTER LA + key("\u09AE", joinMoreKeys("\u09AE\u09CD\u09A8", "\u09AE\u09CD\u09AA", + "\u09AE\u09CD\u09AC", "\u09AE\u09CD\u09AD", "\u09AE\u09CD\u09AE", + "\u09AE\u09CD\u09B0", "\u09AE\u09CD\u09B2")), + // U+098F: "এ" BENGALI LETTER E + key("\u098F"), + // U+0993: "ও" BENGALI LETTER O + key("\u0993")) + .build(); + + private static final ExpectedKey[][] ALPHABET_SHIFTED_COMMON = new ExpectedKeyboardBuilder() + .setKeysOfRow(1, + // U+09A2: "ঢ" BENGALI LETTER DDHA + key("\u09A2"), + // U+09A0: "ঠ" BENGALI LETTER TTHA + key("\u09A0"), + // U+09C8: "ৈ" BENGALI VOWEL SIGN AI + // U+0990: "ঐ" BENGALI LETTER AI + key("\u09C8", moreKey("\u0990")), + // U+09DC: "ড়" BENGALI LETTER RRA + // U+09BC: "়" BENGALI SIGN NUKTA + key("\u09DC", moreKey("\u09BC")), + // U+099F: "ট" BENGALI LETTER TTA + // U+09F3: "৳" BENGALI RUPEE SIGN + // U+099F/U+09CD/U+099F: + // "ট্ট" BENGALI LETTER TTA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA + // U+099F/U+09CD/U+09AC: + // "ট্ব" BENGALI LETTER TTA/BENGALI SIGN VIRAMA/BENGALI LETTER BA + // U+099F/U+09CD/U+09AE: + // "ট্ম" BENGALI LETTER TTA/BENGALI SIGN VIRAMA/BENGALI LETTER MA + key("\u099F", joinMoreKeys("\u09F3", "\u099F\u09CD\u099F", "\u099F\u09CD\u09AC", + "\u099F\u09CD\u09AE")), + // U+099E: "ঞ" BENGALI LETTER NYA + // U+099E/U+09CD/U+099A: + // "ঞ্চ" BENGALI LETTER NYA/BENGALI SIGN VIRAMA/BENGALI LETTER CA + // U+099E/U+09CD/U+099B: + // "ঞ্ছ" BENGALI LETTER NYA/BENGALI SIGN VIRAMA/BENGALI LETTER CHA + // U+099E/U+09CD/U+099C: + // "ঞ্জ" BENGALI LETTER NYA/BENGALI SIGN VIRAMA/BENGALI LETTER JA + key("\u099E", joinMoreKeys("\u099E\u09CD\u099A", "\u099E\u09CD\u099B", + "\u099E\u09CD\u099C")), + // U+09C2: "ূ" BENGALI VOWEL SIGN UU + // U+098A: "ঊ" BENGALI LETTER UU + key("\u09C2", moreKey("\u098A")), + // U+09C0: "ী" BENGALI VOWEL SIGN II + // U+0988: "ঈ" BENGALI LETTER II + key("\u09C0", moreKey("\u0988")), + // U+09CC: "ৌ" BENGALI VOWEL SIGN AU + // U+099A: "ঔ" BENGALI LETTER CA + // U+09D7: "ৗ" BENGALI AU LENGTH MARK + key("\u09CC", joinMoreKeys("\u099A", "\u09D7")), + // U+09AB: "ফ" BENGALI LETTER PHA + // U+09AB/U+09CD/U+099F: + // "ফ্ট" BENGALI LETTER PHA/BENGALI SIGN VIRAMA/BENGALI LETTER TTA + // U+09AB/U+09CD/U+09AF: + // "ফ্য" BENGALI LETTER PHA/BENGALI SIGN VIRAMA/BENGALI LETTER YA + // U+09AB/U+09CD/U+09B0: + // "ফ্র" BENGALI LETTER PHA/BENGALI SIGN VIRAMA/BENGALI LETTER RA + // U+09AB/U+09CD/U+09B2: + // "ফ্ল" BENGALI LETTER PHA/BENGALI SIGN VIRAMA/BENGALI LETTER LA + key("\u09AB", joinMoreKeys("\u09AB\u09CD\u099F", "\u09AB\u09CD\u09AF", + "\u09AB\u09CD\u09B0", "\u09AB\u09CD\u09B2")), + // U+098B: "ঋ" BENGALI LETTER VOCALIC R + // U+098C: "ঌ" BENGALI LETTER VOCALIC L + // U+09E1: "ৡ" BENGALI LETTER VOCALIC LL + // U+09F4: "৴" BENGALI CURRENCY NUMERATOR ONE + // U+09F5: "৵" BENGALI CURRENCY NUMERATOR TWO + // U+09F6: "৶" BENGALI CURRENCY NUMERATOR THREE + // U+09E2: " ৢ" BENGALI VOWEL SIGN VOCALIC L + // U+09E3: " ৣ" BENGALI VOWEL SIGN VOCALIC LL + key("\u098B", joinMoreKeys("\u098C", "\u09E1", "\u09F4", "\u09F5", "\u09F6", + "\u09E2", "\u09E3"))) + .setKeysOfRow(2, + // U+0985: "অ" BENGALI LETTER A + key("\u0985"), + // U+09B6: "শ" BENGALI LETTER SHA + // U+09B6/U+09CD/U+099A: + // "শ্চ" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER CA + // U+09B6/U+09CD/U+099B: + // "শ্ছ" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER CHA + // U+09B6/U+09CD/U+09A4: + // "শ্ত" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER TA + // U+09B6/U+09CD/U+09A8: + // "শ্ন" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER NA + // U+09B6/U+09CD/U+09AC: + // "শ্ব" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER BA + // U+09B6/U+09CD/U+09AE: + // "শ্ম" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER MA + // U+09B6/U+09CD/U+09B0: + // "শ্র" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER RA + // U+09B6/U+09CD/U+09B2: + // "শ্ল" BENGALI LETTER SHA/BENGALI SIGN VIRAMA/BENGALI LETTER LA + key("\u09B6", joinMoreKeys("\u09B6\u09CD\u099A", "\u09B6\u09CD\u099B", + "\u09B6\u09CD\u09A4", "\u09B6\u09CD\u09A8", "\u09B6\u09CD\u09AC", + "\u09B6\u09CD\u09AE", "\u09B6\u09CD\u09B0", "\u09B6\u09CD\u09B2")), + // U+09A1: "ড" BENGALI LETTER DDA + // U+09A1/U+09CD/U+09A1: + // "ড্ড" BENGALI LETTER DDA/BENGALI SIGN VIRAMA/BENGALI LETTER DDA + key("\u09A1", moreKey("\u09A1\u09CD\u09A1")), + // U+09DD: "ঢ়" BENGALI LETTER RHA + key("\u09DD"), + // U+0998: "ঘ" BENGALI LETTER GHA + key("\u0998"), + // U+09B9: "হ" BENGALI LETTER HA + // U+09BD: "ঽ" BENGALI SIGN AVAGRAHA + // U+09B9/U+09CD/U+09A3: + // "হ্ণ" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER NNA + // U+09B9/U+09CD/U+09A8: + // "হ্ন" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER NA + // U+09B9/U+09CD/U+09AC: + // "হ্ব" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER BA + // U+09B9/U+09CD/U+09AE: + // "হ্ম" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER MA + // U+09B9/U+09CD/U+09B0: + // "হ্র" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER RA + // U+09B9/U+09CD/U+09B2: + // "হ্ল" BENGALI LETTER HA/BENGALI SIGN VIRAMA/BENGALI LETTER LA + key("\u09B9", joinMoreKeys("\u09BD", "\u09B9\u09CD\u09A3", "\u09B9\u09CD\u09A8", + "\u09B9\u09CD\u09AC", "\u09B9\u09CD\u09AE", "\u09B9\u09CD\u09B0", + "\u09B9\u09CD\u09B2")), + // U+099D: "ঝ" BENGALI LETTER JHA + key("\u099D"), + // U+0996: "খ" BENGALI LETTER KHA + key("\u0996"), + // U+09CE: "ৎ" BENGALI LETTER KHANDA TA + key("\u09CE"), + // U+0988: "ঈ" BENGALI LETTER II + key("\u0988"), + // U+098A: "ঊ" BENGALI LETTER UU + key("\u098A")) + .setKeysOfRow(3, + // U+0964: "।" DEVANAGARI DANDA + // U+0965: "॥" DEVANAGARI DOUBLE DANDA + key("\u0964", moreKey("\u0965")), + // U+0999: "ঙ BENGALI LETTER NGA + // U+0999/U+09CD/U+0995: "ঙ্ক" + // U+0999/U+09CD/U+0996: "ঙ্খ" + // U+0999/U+09CD/U+0997: "ঙ্গ" + key("\u0999", joinMoreKeys("\u0999\u09CD\u0995", "\u0999\u09CD\u0996", + "\u0999\u09CD\u0997")), + // U+099B: "ছ" BENGALI LETTER CHA + key("\u099B"), + // U+0983: "ঃ" BENGALI SIGN VISARGA + key("\u0983"), + // U+0981: "ঁ" BENGALI SIGN CANDRABINDU + key("\u0981"), + // U+09A3: "ণ" BENGALI LETTER NNA + // U+09A3/U+09CD/U+099F: + // "ণ্ট" BENGALI LETTER NNA/BENGALI SIGN VIRAMA/BENGALI LETTER TT/A + // U+09A3/U+09CD/U+09A1: + // "ণ্ড" BENGALI LETTER NNA/BENGALI SIGN VIRAMA/BENGALI LETTER DDA + // U+09A3/U+09CD/U+09A3: + // "ণ্ণ" BENGALI LETTER NNA/BENGALI SIGN VIRAMA/BENGALI LETTER NN + key("\u09A3", joinMoreKeys("\u09A3\u09CD\u099F", "\u09A3\u09CD\u09A1", + "\u09A3\u09CD\u09A3")), + // U+0982: "ং" BENGALI SIGN ANUSVARA + key("\u0982"), + // U+0990: "ঐ" BENGALI LETTER AI + key("\u0990"), + // U+0994: "ঔ" BENGALI LETTER AU + key("\u0994")) + .build(); +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Bulgarian.java b/tests/src/com/android/inputmethod/keyboard/layout/Bulgarian.java index 3282e44ae..bbe038414 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Bulgarian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Bulgarian.java @@ -16,7 +16,8 @@ package com.android.inputmethod.keyboard.layout; -import com.android.inputmethod.keyboard.layout.EastSlavic.EastSlavicCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.EastSlavicCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -25,17 +26,17 @@ import java.util.Locale; public final class Bulgarian extends LayoutBase { private static final String LAYOUT_NAME = "bulgarian"; - public Bulgarian(final LayoutCustomizer customizer) { - super(customizer, Symbols.class, SymbolsShifted.class); + public Bulgarian(final Locale locale) { + super(new BulgarianCustomizer(locale), Symbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class BulgarianCustomizer extends LayoutCustomizer { + private static class BulgarianCustomizer extends LayoutCustomizer { private final EastSlavicCustomizer mEastSlavicCustomizer; - public BulgarianCustomizer(final Locale locale) { + BulgarianCustomizer(final Locale locale) { super(locale); mEastSlavicCustomizer = new EastSlavicCustomizer(locale); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/BulgarianBds.java b/tests/src/com/android/inputmethod/keyboard/layout/BulgarianBds.java index 20a5f7dac..74372b9bc 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/BulgarianBds.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/BulgarianBds.java @@ -16,7 +16,7 @@ package com.android.inputmethod.keyboard.layout; -import com.android.inputmethod.keyboard.layout.EastSlavic.EastSlavicCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.EastSlavicCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -25,15 +25,15 @@ import java.util.Locale; public final class BulgarianBds extends LayoutBase { private static final String LAYOUT_NAME = "bulgarian_bds"; - public BulgarianBds(final LayoutCustomizer customizer) { - super(customizer, Symbols.class, SymbolsShifted.class); + public BulgarianBds(final Locale locale) { + super(new BulgarianBdsCustomizer(locale), Symbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class BulgarianBdsCustomizer extends EastSlavicCustomizer { - public BulgarianBdsCustomizer(final Locale locale) { super(locale); } + private static class BulgarianBdsCustomizer extends EastSlavicCustomizer { + BulgarianBdsCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Colemak.java b/tests/src/com/android/inputmethod/keyboard/layout/Colemak.java index a4a9701cd..3f8ce28eb 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Colemak.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Colemak.java @@ -17,6 +17,7 @@ package com.android.inputmethod.keyboard.layout; import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Dvorak.java b/tests/src/com/android/inputmethod/keyboard/layout/Dvorak.java index ba94c8dee..7cb3b92a7 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Dvorak.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Dvorak.java @@ -17,12 +17,9 @@ package com.android.inputmethod.keyboard.layout; import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKey.ExpectedAdditionalMoreKey; -import com.android.inputmethod.latin.settings.CustomInputStyleSettingsFragment; - -import java.util.Locale; /** * The Dvorak alphabet keyboard. @@ -37,52 +34,17 @@ public class Dvorak extends LayoutBase { @Override public String getName() { return LAYOUT_NAME; } - public static class DvorakCustomizer extends LayoutCustomizer { - public DvorakCustomizer(final Locale locale) { super(locale); } - - @Override - public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) { - return isPhone ? joinKeys(SHIFT_KEY): joinKeys(SHIFT_KEY, key("q")); - } - - @Override - public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { - return isPhone ? EMPTY_KEYS : joinKeys(key("z"), SHIFT_KEY); - } - - @Override - public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) { - // U+00A1: "¡" INVERTED EXCLAMATION MARK - return isPhone ? joinKeys(key("q", SETTINGS_KEY)) - : joinKeys(key("!", joinMoreKeys("\u00A1", SETTINGS_KEY))); - } - - @Override - public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) { - final ExpectedAdditionalMoreKey[] punctuationMoreKeys = - convertToAdditionalMoreKeys(getPunctuationMoreKeys(isPhone)); - // U+00BF: "¿" INVERTED QUESTION MARK - return isPhone - ? joinKeys(key("z", punctuationMoreKeys)) - : joinKeys(key("?", joinMoreKeys(punctuationMoreKeys, "\u00BF"))); - } - - private static ExpectedAdditionalMoreKey[] convertToAdditionalMoreKeys( - final ExpectedKey ... moreKeys) { - final ExpectedAdditionalMoreKey[] additionalMoreKeys = - new ExpectedAdditionalMoreKey[moreKeys.length]; - for (int index = 0; index < moreKeys.length; index++) { - additionalMoreKeys[index] = ExpectedAdditionalMoreKey.newInstance(moreKeys[index]); - } - return additionalMoreKeys; - } - } - @Override public ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) { return ALPHABET_COMMON; } + /** + * Get the left most key of the first row. + * @param isPhone true if requesting phone's keys. + * @param elementId the element id of the requesting shifted mode. + * @return the left most key of the first row. + */ protected ExpectedKey getRow1_1Key(final boolean isPhone, final int elementId) { if (elementId == KeyboardId.ELEMENT_ALPHABET || elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) { @@ -91,6 +53,12 @@ public class Dvorak extends LayoutBase { return key("\"", additionalMoreKey("1")); } + /** + * Get the 2nd left key of the first row. + * @param isPhone true if requesting phone's keys. + * @param elementId the element id of the requesting shifted mode. + * @return the 2nd left key of the first row. + */ protected ExpectedKey getRow1_2Key(final boolean isPhone, final int elementId) { if (elementId == KeyboardId.ELEMENT_ALPHABET || elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) { @@ -99,6 +67,12 @@ public class Dvorak extends LayoutBase { return key("<", additionalMoreKey("2")); } + /** + * Get the 3rd left key of the first row. + * @param isPhone true if requesting phone's keys. + * @param elementId the element id of the requesting shifted mode. + * @return the 3rd left key of the first row. + */ protected ExpectedKey getRow1_3Key(final boolean isPhone, final int elementId) { if (elementId == KeyboardId.ELEMENT_ALPHABET || elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) { diff --git a/tests/src/com/android/inputmethod/keyboard/layout/EastSlavic.java b/tests/src/com/android/inputmethod/keyboard/layout/EastSlavic.java index 7fcc974c2..f95d2d20e 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/EastSlavic.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/EastSlavic.java @@ -16,11 +16,9 @@ package com.android.inputmethod.keyboard.layout; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; - -import java.util.Locale; public final class EastSlavic extends LayoutBase { private static final String LAYOUT_NAME = "east_slavic"; @@ -32,26 +30,6 @@ public final class EastSlavic extends LayoutBase { @Override public String getName() { return LAYOUT_NAME; } - public static class EastSlavicCustomizer extends LayoutCustomizer { - public EastSlavicCustomizer(final Locale locale) { - super(locale); - } - - @Override - public final ExpectedKey getAlphabetKey() { return EAST_SLAVIC_ALPHABET_KEY; } - - @Override - public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { - return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS; - } - - // U+0410: "А" CYRILLIC CAPITAL LETTER A - // U+0411: "Б" CYRILLIC CAPITAL LETTER BE - // U+0412: "В" CYRILLIC CAPITAL LETTER VE - private static final ExpectedKey EAST_SLAVIC_ALPHABET_KEY = key( - "\u0410\u0411\u0412", Constants.CODE_SWITCH_ALPHA_SYMBOL); - } - @Override ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) { return ALPHABET_COMMON; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Farsi.java b/tests/src/com/android/inputmethod/keyboard/layout/Farsi.java index 7390457d0..6dc4559dc 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Farsi.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Farsi.java @@ -18,26 +18,25 @@ package com.android.inputmethod.keyboard.layout; import com.android.inputmethod.keyboard.layout.Symbols.RtlSymbols; import com.android.inputmethod.keyboard.layout.SymbolsShifted.RtlSymbolsShifted; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; import java.util.Locale; public final class Farsi extends LayoutBase { private static final String LAYOUT_NAME = "farsi"; - public Farsi(final LayoutCustomizer customizer) { - super(customizer, FarsiSymbols.class, FarsiSymbolsShifted.class); + public Farsi(final Locale locale) { + super(new FarsiCustomizer(locale), FarsiSymbols.class, FarsiSymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class FarsiCustomizer extends LayoutCustomizer { - public FarsiCustomizer(final Locale locale) { - super(locale); - } + private static class FarsiCustomizer extends LayoutCustomizer { + FarsiCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getAlphabetKey() { return FARSI_ALPHABET_KEY; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Georgian.java b/tests/src/com/android/inputmethod/keyboard/layout/Georgian.java index 6f20dfcd1..d1ac5fd6e 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Georgian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Georgian.java @@ -17,9 +17,10 @@ package com.android.inputmethod.keyboard.layout; import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; import java.util.Locale; @@ -29,15 +30,15 @@ import java.util.Locale; public final class Georgian extends LayoutBase { private static final String LAYOUT_NAME = "georgian"; - public Georgian(final LayoutCustomizer customizer) { - super(customizer, Symbols.class, SymbolsShifted.class); + public Georgian(final Locale locale) { + super(new GeorgianCustomizer(locale), Symbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class GeorgianCustomizer extends LayoutCustomizer { - public GeorgianCustomizer(final Locale locale) { super(locale); } + private static class GeorgianCustomizer extends LayoutCustomizer { + GeorgianCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getAlphabetKey() { return GEORGIAN_ALPHABET_KEY; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Greek.java b/tests/src/com/android/inputmethod/keyboard/layout/Greek.java index 475052c75..0209c2ae1 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Greek.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Greek.java @@ -17,9 +17,10 @@ package com.android.inputmethod.keyboard.layout; import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.layout.customizer.EuroCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; import java.util.Locale; @@ -29,15 +30,15 @@ import java.util.Locale; public final class Greek extends LayoutBase { private static final String LAYOUT_NAME = "greek"; - public Greek(final LayoutCustomizer customizer) { - super(customizer, Symbols.class, SymbolsShifted.class); + public Greek(final Locale locale) { + super(new GreekCustomizer(locale), Symbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class GreekCustomizer extends EuroCustomizer { - public GreekCustomizer(final Locale locale) { super(locale); } + private static class GreekCustomizer extends EuroCustomizer { + GreekCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getAlphabetKey() { return GREEK_ALPHABET_KEY; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Hebrew.java b/tests/src/com/android/inputmethod/keyboard/layout/Hebrew.java index 552f0d3d5..1b91b47ae 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Hebrew.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Hebrew.java @@ -18,26 +18,25 @@ package com.android.inputmethod.keyboard.layout; import com.android.inputmethod.keyboard.layout.Symbols.RtlSymbols; import com.android.inputmethod.keyboard.layout.SymbolsShifted.RtlSymbolsShifted; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; import java.util.Locale; public final class Hebrew extends LayoutBase { private static final String LAYOUT_NAME = "hebrew"; - public Hebrew(final LayoutCustomizer customizer) { - super(customizer, HebrewSymbols.class, RtlSymbolsShifted.class); + public Hebrew(final Locale locale) { + super(new HebrewCustomizer(locale), HebrewSymbols.class, RtlSymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class HebrewCustomizer extends LayoutCustomizer { - public HebrewCustomizer(final Locale locale) { - super(locale); - } + private static class HebrewCustomizer extends LayoutCustomizer { + HebrewCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getAlphabetKey() { return HEBREW_ALPHABET_KEY; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Hindi.java b/tests/src/com/android/inputmethod/keyboard/layout/Hindi.java index b12b8be64..82f67aca2 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Hindi.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Hindi.java @@ -19,11 +19,9 @@ package com.android.inputmethod.keyboard.layout; import static com.android.inputmethod.keyboard.layout.DevanagariLetterConstants.*; import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; - -import java.util.Locale; /** * The Hindi keyboard. @@ -38,50 +36,6 @@ public final class Hindi extends LayoutBase { @Override public String getName() { return LAYOUT_NAME; } - public static class HindiCustomizer extends LayoutCustomizer { - public HindiCustomizer(final Locale locale) { super(locale); } - - @Override - public ExpectedKey getAlphabetKey() { return HINDI_ALPHABET_KEY; } - - @Override - public ExpectedKey getSymbolsKey() { return HINDI_SYMBOLS_KEY; } - - @Override - public ExpectedKey getBackToSymbolsKey() { return HINDI_BACK_TO_SYMBOLS_KEY; } - - @Override - public ExpectedKey getCurrencyKey() { return CURRENCY_RUPEE; } - - @Override - public ExpectedKey[] getOtherCurrencyKeys() { - return SymbolsShifted.CURRENCIES_OTHER_GENERIC; - } - - @Override - public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { - return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS; - } - - // U+0915: "क" DEVANAGARI LETTER KA - // U+0916: "ख" DEVANAGARI LETTER KHA - // U+0917: "ग" DEVANAGARI LETTER GA - private static final ExpectedKey HINDI_ALPHABET_KEY = key( - "\u0915\u0916\u0917", Constants.CODE_SWITCH_ALPHA_SYMBOL); - // U+0967: "१" DEVANAGARI DIGIT ONE - // U+0968: "२" DEVANAGARI DIGIT TWO - // U+0969: "३" DEVANAGARI DIGIT THREE - private static final String HINDI_SYMBOLS_LABEL = "?\u0967\u0968\u0969"; - private static final ExpectedKey HINDI_SYMBOLS_KEY = key(HINDI_SYMBOLS_LABEL, - Constants.CODE_SWITCH_ALPHA_SYMBOL); - private static final ExpectedKey HINDI_BACK_TO_SYMBOLS_KEY = key(HINDI_SYMBOLS_LABEL, - Constants.CODE_SHIFT); - - // U+20B9: "₹" INDIAN RUPEE SIGN - private static final ExpectedKey CURRENCY_RUPEE = key("\u20B9", - Symbols.CURRENCY_GENERIC_MORE_KEYS); - } - @Override ExpectedKey[][] getCommonAlphabetLayout(boolean isPhone) { return ALPHABET_COMMON; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/HindiCompact.java b/tests/src/com/android/inputmethod/keyboard/layout/HindiCompact.java index c2a15f3f3..a2e339919 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/HindiCompact.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/HindiCompact.java @@ -18,8 +18,8 @@ package com.android.inputmethod.keyboard.layout; import static com.android.inputmethod.keyboard.layout.DevanagariLetterConstants.*; -import com.android.inputmethod.keyboard.layout.Hindi.HindiCustomizer; import com.android.inputmethod.keyboard.layout.Hindi.HindiSymbols; +import com.android.inputmethod.keyboard.layout.customizer.HindiCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -31,41 +31,20 @@ import java.util.Locale; public final class HindiCompact extends LayoutBase { private static final String LAYOUT_NAME = "hindi_compact"; - public HindiCompact(final LayoutCustomizer customizer) { - super(customizer, HindiSymbols.class, SymbolsShifted.class); + public HindiCompact(final Locale locale) { + super(new HindiCompactCustomizer(locale), HindiSymbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class HindiCompactCustomizer extends HindiCustomizer { - public HindiCompactCustomizer(final Locale locale) { super(locale); } + private static class HindiCompactCustomizer extends HindiCustomizer { + HindiCompactCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) { return EMPTY_KEYS; } - - @Override - public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) { - // U+0964: "।" DEVANAGARI DANDA - final ExpectedKey periodKey = key("\u0964", getPunctuationMoreKeys(isPhone)); - return joinKeys(periodKey); - } - - @Override - public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) { - return isPhone ? HINDI_PHONE_PUNCTUATION_MORE_KEYS : HINDI_TABLET_PUNCTUATION_MORE_KEYS; - } - - // Punctuation more keys for phone form factor. - private static final ExpectedKey[] HINDI_PHONE_PUNCTUATION_MORE_KEYS = joinKeys( - ",", ".", "?", "!", "#", ")", "(", "/", ";", - "'", "@", ":", "-", "\"", "+", "%", "&"); - // Punctuation more keys for tablet form factor. - private static final ExpectedKey[] HINDI_TABLET_PUNCTUATION_MORE_KEYS = joinKeys( - ",", ".", "'", "#", ")", "(", "/", ";", - "@", ":", "-", "\"", "+", "%", "&"); } @Override diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Kannada.java b/tests/src/com/android/inputmethod/keyboard/layout/Kannada.java index 8bee1f83b..5a8d32cb8 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Kannada.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Kannada.java @@ -16,9 +16,10 @@ package com.android.inputmethod.keyboard.layout; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; import java.util.Locale; @@ -28,15 +29,15 @@ import java.util.Locale; public final class Kannada extends LayoutBase { private static final String LAYOUT_NAME = "kannada"; - public Kannada(final LayoutCustomizer customizer) { - super(customizer, Symbols.class, SymbolsShifted.class); + public Kannada(final Locale locale) { + super(new KannadaCustomizer(locale), Symbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class KannadaCustomizer extends LayoutCustomizer { - public KannadaCustomizer(final Locale locale) { super(locale); } + private static class KannadaCustomizer extends LayoutCustomizer { + KannadaCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getAlphabetKey() { return KANNADA_ALPHABET_KEY; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Khmer.java b/tests/src/com/android/inputmethod/keyboard/layout/Khmer.java index 7e4f159ab..4d82f090b 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Khmer.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Khmer.java @@ -17,9 +17,10 @@ package com.android.inputmethod.keyboard.layout; import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; import java.util.Locale; @@ -29,15 +30,15 @@ import java.util.Locale; public final class Khmer extends LayoutBase { private static final String LAYOUT_NAME = "khmer"; - public Khmer(final LayoutCustomizer customizer) { - super(customizer, Symbols.class, SymbolsShifted.class); + public Khmer(final Locale locale) { + super(new KhmerCustomizer(locale), Symbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class KhmerCustomizer extends LayoutCustomizer { - public KhmerCustomizer(final Locale locale) { super(locale); } + private static class KhmerCustomizer extends LayoutCustomizer { + KhmerCustomizer(final Locale locale) { super(locale); } @Override public int getNumberOfRows() { return 5; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Lao.java b/tests/src/com/android/inputmethod/keyboard/layout/Lao.java index aaa1c8a8a..149f75397 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Lao.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Lao.java @@ -17,9 +17,10 @@ package com.android.inputmethod.keyboard.layout; import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; import java.util.Locale; @@ -29,15 +30,15 @@ import java.util.Locale; public final class Lao extends LayoutBase { private static final String LAYOUT_NAME = "lao"; - public Lao(final LayoutCustomizer customizer) { - super(customizer, Symbols.class, SymbolsShifted.class); + public Lao(final Locale locale) { + super(new LaoCustomizer(locale), Symbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class LaoCustomizer extends LayoutCustomizer { - public LaoCustomizer(final Locale locale) { super(locale); } + private static class LaoCustomizer extends LayoutCustomizer { + LaoCustomizer(final Locale locale) { super(locale); } @Override public int getNumberOfRows() { return 5; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/LayoutBase.java b/tests/src/com/android/inputmethod/keyboard/layout/LayoutBase.java index b05789b73..285a50ce9 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/LayoutBase.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/LayoutBase.java @@ -17,11 +17,10 @@ package com.android.inputmethod.keyboard.layout; import com.android.inputmethod.keyboard.KeyboardId; -import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.AbstractLayoutBase; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; import java.util.Locale; @@ -29,200 +28,6 @@ import java.util.Locale; * The base class of keyboard layout. */ public abstract class LayoutBase extends AbstractLayoutBase { - /** - * This class is used to customize common keyboard layout to language specific layout. - */ - public static class LayoutCustomizer { - private final Locale mLocale; - - // Empty keys definition to remove keys by adding this. - protected static final ExpectedKey[] EMPTY_KEYS = joinKeys(); - - public LayoutCustomizer(final Locale locale) { - mLocale = locale; - } - - public final Locale getLocale() { - return mLocale; - } - - public int getNumberOfRows() { - return 4; - } - - /** - * Set accented letters to common layout. - * @param builder the {@link ExpectedKeyboardBuilder} object that contains common keyboard - * layout. - * @return the {@link ExpectedKeyboardBuilder} object that contains accented letters as - * "more keys". - */ - public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { - return builder; - } - - /** - * Get the function key to switch to alphabet layout. - * @return the {@link ExpectedKey} of the alphabet key. - */ - public ExpectedKey getAlphabetKey() { return ALPHABET_KEY; } - - /** - * Get the function key to switch to symbols layout. - * @return the {@link ExpectedKey} of the symbols key. - */ - public ExpectedKey getSymbolsKey() { return SYMBOLS_KEY; } - - /** - * Get the function key to switch to symbols shift layout. - * @param isPhone true if requesting phone's key. - * @return the {@link ExpectedKey} of the symbols shift key. - */ - public ExpectedKey getSymbolsShiftKey(boolean isPhone) { - return isPhone ? SYMBOLS_SHIFT_KEY : TABLET_SYMBOLS_SHIFT_KEY; - } - - /** - * Get the function key to switch from symbols shift to symbols layout. - * @return the {@link ExpectedKey} of the back to symbols key. - */ - public ExpectedKey getBackToSymbolsKey() { return BACK_TO_SYMBOLS_KEY; } - - /** - * Get the currency key. - * @return the {@link ExpectedKey} of the currency key. - */ - public ExpectedKey getCurrencyKey() { return Symbols.CURRENCY_DOLLAR; } - - /** - * Get other currencies keys. - * @return the array of {@link ExpectedKey} that represents other currency keys. - */ - public ExpectedKey[] getOtherCurrencyKeys() { - return SymbolsShifted.CURRENCIES_OTHER_THAN_DOLLAR; - } - - /** - * Get "more keys" of double quotation mark. - * @return the array of {@link ExpectedKey} of more double quotation marks in natural order. - */ - public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_9LR; } - - /** - * Get "more keys" of single quotation mark. - * @return the array of {@link ExpectedKey} of more single quotation marks in natural order. - */ - public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_9LR; } - - /** - * Get double angle quotation marks in natural order. - * @return the array of {@link ExpectedKey} of double angle quotation marks in natural - * order. - */ - public ExpectedKey[] getDoubleAngleQuoteKeys() { return Symbols.DOUBLE_ANGLE_QUOTES_LR; } - - /** - * Get single angle quotation marks in natural order. - * @return the array of {@link ExpectedKey} of single angle quotation marks in natural - * order. - */ - public ExpectedKey[] getSingleAngleQuoteKeys() { return Symbols.SINGLE_ANGLE_QUOTES_LR; } - - /** - * Get the left shift keys. - * @param isPhone true if requesting phone's keys. - * @return the array of {@link ExpectedKey} that should be placed at left edge of the - * keyboard. - */ - public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) { - return joinKeys(SHIFT_KEY); - } - - /** - * Get the right shift keys. - * @param isPhone true if requesting phone's keys. - * @return the array of {@link ExpectedKey} that should be placed at right edge of the - * keyboard. - */ - public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { - return isPhone ? EMPTY_KEYS : joinKeys(EXCLAMATION_AND_QUESTION_MARKS, SHIFT_KEY); - } - - /** - * Get the enter key. - * @param isPhone true if requesting phone's key. - * @return the array of {@link ExpectedKey} that should be placed as an enter key. - */ - public ExpectedKey getEnterKey(final boolean isPhone) { - return isPhone ? key(ENTER_KEY, EMOJI_ACTION_KEY) : ENTER_KEY; - } - - /** - * Get the emoji key. - * @param isPhone true if requesting phone's key. - * @return the array of {@link ExpectedKey} that should be placed as an emoji key. - */ - public ExpectedKey getEmojiKey(final boolean isPhone) { - return EMOJI_NORMAL_KEY; - } - - /** - * Get the space keys. - * @param isPhone true if requesting phone's keys. - * @return the array of {@link ExpectedKey} that should be placed at the center of the - * keyboard. - */ - public ExpectedKey[] getSpaceKeys(final boolean isPhone) { - return joinKeys(LANGUAGE_SWITCH_KEY, SPACE_KEY); - } - - /** - * Get the keys left to the spacebar. - * @param isPhone true if requesting phone's keys. - * @return the array of {@link ExpectedKey} that should be placed at left of the spacebar. - */ - public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) { - // U+002C: "," COMMA - return joinKeys(key("\u002C", SETTINGS_KEY)); - } - - /** - * Get the keys right to the spacebar. - * @param isPhone true if requesting phone's keys. - * @return the array of {@link ExpectedKey} that should be placed at right of the spacebar. - */ - public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) { - final ExpectedKey periodKey = key(".", getPunctuationMoreKeys(isPhone)); - return joinKeys(periodKey); - } - - /** - * Get "more keys" for the punctuation key (usually the period key). - * @param isPhone true if requesting phone's keys. - * @return the array of {@link ExpectedKey} that are "more keys" of the punctuation key. - */ - public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) { - return isPhone ? PHONE_PUNCTUATION_MORE_KEYS : TABLET_PUNCTUATION_MORE_KEYS; - } - } - - /** - * The layout customize class for countries that use Euro. - */ - public static class EuroCustomizer extends LayoutCustomizer { - public EuroCustomizer(final Locale locale) { - super(locale); - } - - @Override - public final ExpectedKey getCurrencyKey() { return Symbols.CURRENCY_EURO; } - - @Override - public final ExpectedKey[] getOtherCurrencyKeys() { - return SymbolsShifted.CURRENCIES_OTHER_THAN_EURO; - } - } - private final LayoutCustomizer mCustomizer; private final Symbols mSymbols; private final SymbolsShifted mSymbolsShifted; @@ -258,77 +63,6 @@ public abstract class LayoutBase extends AbstractLayoutBase { */ public final LayoutCustomizer getCustomizer() { return mCustomizer; } - // Icon ids. - private static final int ICON_DELETE = KeyboardIconsSet.getIconId( - KeyboardIconsSet.NAME_DELETE_KEY); - private static final int ICON_SPACE = KeyboardIconsSet.getIconId( - KeyboardIconsSet.NAME_SPACE_KEY); - private static final int ICON_TAB = KeyboardIconsSet.getIconId( - KeyboardIconsSet.NAME_TAB_KEY); - private static final int ICON_SHORTCUT = KeyboardIconsSet.getIconId( - KeyboardIconsSet.NAME_SHORTCUT_KEY); - private static final int ICON_SETTINGS = KeyboardIconsSet.getIconId( - KeyboardIconsSet.NAME_SETTINGS_KEY); - private static final int ICON_LANGUAGE_SWITCH = KeyboardIconsSet.getIconId( - KeyboardIconsSet.NAME_LANGUAGE_SWITCH_KEY); - private static final int ICON_ENTER = KeyboardIconsSet.getIconId( - KeyboardIconsSet.NAME_ENTER_KEY); - private static final int ICON_EMOJI_ACTION = KeyboardIconsSet.getIconId( - KeyboardIconsSet.NAME_EMOJI_ACTION_KEY); - private static final int ICON_EMOJI_NORMAL = KeyboardIconsSet.getIconId( - KeyboardIconsSet.NAME_EMOJI_NORMAL_KEY); - private static final int ICON_SHIFT = KeyboardIconsSet.getIconId( - KeyboardIconsSet.NAME_SHIFT_KEY); - private static final int ICON_SHIFTED_SHIFT = KeyboardIconsSet.getIconId( - KeyboardIconsSet.NAME_SHIFT_KEY_SHIFTED); - private static final int ICON_ZWNJ = KeyboardIconsSet.getIconId( - KeyboardIconsSet.NAME_ZWNJ_KEY); - private static final int ICON_ZWJ = KeyboardIconsSet.getIconId( - KeyboardIconsSet.NAME_ZWJ_KEY); - - // Functional keys. - public static final ExpectedKey DELETE_KEY = key(ICON_DELETE, Constants.CODE_DELETE); - public static final ExpectedKey TAB_KEY = key(ICON_TAB, Constants.CODE_TAB); - public static final ExpectedKey SHORTCUT_KEY = key(ICON_SHORTCUT, Constants.CODE_SHORTCUT); - public static final ExpectedKey SETTINGS_KEY = key(ICON_SETTINGS, Constants.CODE_SETTINGS); - public static final ExpectedKey LANGUAGE_SWITCH_KEY = key( - ICON_LANGUAGE_SWITCH, Constants.CODE_LANGUAGE_SWITCH); - public static final ExpectedKey ENTER_KEY = key(ICON_ENTER, Constants.CODE_ENTER); - public static final ExpectedKey EMOJI_ACTION_KEY = key(ICON_EMOJI_ACTION, Constants.CODE_EMOJI); - public static final ExpectedKey EMOJI_NORMAL_KEY = key(ICON_EMOJI_NORMAL, Constants.CODE_EMOJI); - public static final ExpectedKey SPACE_KEY = key(ICON_SPACE, Constants.CODE_SPACE); - static final ExpectedKey CAPSLOCK_MORE_KEY = key(" ", Constants.CODE_CAPSLOCK); - public static final ExpectedKey SHIFT_KEY = key(ICON_SHIFT, - Constants.CODE_SHIFT, CAPSLOCK_MORE_KEY); - public static final ExpectedKey SHIFTED_SHIFT_KEY = key(ICON_SHIFTED_SHIFT, - Constants.CODE_SHIFT, CAPSLOCK_MORE_KEY); - static final ExpectedKey ALPHABET_KEY = key("ABC", Constants.CODE_SWITCH_ALPHA_SYMBOL); - static final ExpectedKey SYMBOLS_KEY = key("?123", Constants.CODE_SWITCH_ALPHA_SYMBOL); - static final ExpectedKey BACK_TO_SYMBOLS_KEY = key("?123", Constants.CODE_SHIFT); - static final ExpectedKey SYMBOLS_SHIFT_KEY = key("= \\ <", Constants.CODE_SHIFT); - static final ExpectedKey TABLET_SYMBOLS_SHIFT_KEY = key("~ [ <", Constants.CODE_SHIFT); - - // U+00A1: "¡" INVERTED EXCLAMATION MARK - // U+00BF: "¿" INVERTED QUESTION MARK - static final ExpectedKey[] EXCLAMATION_AND_QUESTION_MARKS = joinKeys( - key("!", moreKey("\u00A1")), key("?", moreKey("\u00BF"))); - // U+200C: ZERO WIDTH NON-JOINER - // U+200D: ZERO WIDTH JOINER - static final ExpectedKey ZWNJ_KEY = key(ICON_ZWNJ, "\u200C"); - static final ExpectedKey ZWJ_KEY = key(ICON_ZWJ, "\u200D"); - // Domain key - public static final ExpectedKey DOMAIN_KEY = - key(".com", joinMoreKeys(".net", ".org", ".gov", ".edu")).preserveCase(); - - // Punctuation more keys for phone form factor. - public static final ExpectedKey[] PHONE_PUNCTUATION_MORE_KEYS = joinKeys( - ",", "?", "!", "#", ")", "(", "/", ";", - "'", "@", ":", "-", "\"", "+", "%", "&"); - // Punctuation more keys for tablet form factor. - public static final ExpectedKey[] TABLET_PUNCTUATION_MORE_KEYS = joinKeys( - ",", "'", "#", ")", "(", "/", ";", - "@", ":", "-", "\"", "+", "%", "&"); - /** * Helper method to create alphabet layout adding special function keys. * @param builder the {@link ExpectedKeyboardBuilder} object that contains common keyboard @@ -386,7 +120,7 @@ public abstract class LayoutBase extends AbstractLayoutBase { ExpectedKey[][] getCommonAlphabetShiftLayout(final boolean isPhone, final int elementId) { final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder( getCommonAlphabetLayout(isPhone)); - getCustomizer().setAccentedLetters(builder); + getCustomizer().setAccentedLetters(builder, elementId); builder.toUpperCase(getLocale()); return builder.build(); } @@ -411,7 +145,7 @@ public abstract class LayoutBase extends AbstractLayoutBase { final ExpectedKeyboardBuilder builder; if (elementId == KeyboardId.ELEMENT_ALPHABET) { builder = new ExpectedKeyboardBuilder(getCommonAlphabetLayout(isPhone)); - getCustomizer().setAccentedLetters(builder); + getCustomizer().setAccentedLetters(builder, elementId); } else { final ExpectedKey[][] commonLayout = getCommonAlphabetShiftLayout(isPhone, elementId); if (commonLayout == null) { diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Malayalam.java b/tests/src/com/android/inputmethod/keyboard/layout/Malayalam.java index b44b888e1..3497c356f 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Malayalam.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Malayalam.java @@ -16,9 +16,10 @@ package com.android.inputmethod.keyboard.layout; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; import java.util.Locale; @@ -28,15 +29,15 @@ import java.util.Locale; public final class Malayalam extends LayoutBase { private static final String LAYOUT_NAME = "malayalam"; - public Malayalam(final LayoutCustomizer customizer) { - super(customizer, Symbols.class, SymbolsShifted.class); + public Malayalam(final Locale locale) { + super(new MalayalamCustomizer(locale), Symbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class MalayalamCustomizer extends LayoutCustomizer { - public MalayalamCustomizer(final Locale locale) { super(locale); } + private static class MalayalamCustomizer extends LayoutCustomizer { + MalayalamCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getAlphabetKey() { return MALAYALAM_ALPHABET_KEY; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Marathi.java b/tests/src/com/android/inputmethod/keyboard/layout/Marathi.java index 00cf838f9..af26ec555 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Marathi.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Marathi.java @@ -18,8 +18,8 @@ package com.android.inputmethod.keyboard.layout; import static com.android.inputmethod.keyboard.layout.DevanagariLetterConstants.*; -import com.android.inputmethod.keyboard.layout.Hindi.HindiCustomizer; import com.android.inputmethod.keyboard.layout.Hindi.HindiSymbols; +import com.android.inputmethod.keyboard.layout.customizer.DevanagariCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -31,20 +31,37 @@ import java.util.Locale; public final class Marathi extends LayoutBase { private static final String LAYOUT_NAME = "marathi"; - public Marathi(final LayoutCustomizer customizer) { - super(customizer, HindiSymbols.class, SymbolsShifted.class); + public Marathi(final Locale locale) { + super(new MarathiCustomizer(locale), HindiSymbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class MarathiCustomizer extends HindiCustomizer { - public MarathiCustomizer(final Locale locale) { super(locale); } + private static class MarathiCustomizer extends DevanagariCustomizer { + MarathiCustomizer(final Locale locale) { super(locale); } + + @Override + public ExpectedKey getCurrencyKey() { return CURRENCY_RUPEE; } + + @Override + public ExpectedKey[] getOtherCurrencyKeys() { + return SymbolsShifted.CURRENCIES_OTHER_GENERIC; + } @Override public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) { return EMPTY_KEYS; } + + @Override + public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { + return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS; + } + + // U+20B9: "₹" INDIAN RUPEE SIGN + private static final ExpectedKey CURRENCY_RUPEE = key("\u20B9", + Symbols.CURRENCY_GENERIC_MORE_KEYS); } @Override diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Mongolian.java b/tests/src/com/android/inputmethod/keyboard/layout/Mongolian.java index 3c6c05841..288a17e10 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Mongolian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Mongolian.java @@ -16,7 +16,7 @@ package com.android.inputmethod.keyboard.layout; -import com.android.inputmethod.keyboard.layout.EastSlavic.EastSlavicCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.EastSlavicCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -25,17 +25,15 @@ import java.util.Locale; public final class Mongolian extends LayoutBase { private static final String LAYOUT_NAME = "mongolian"; - public Mongolian(final LayoutCustomizer customizer) { - super(customizer, Symbols.class, SymbolsShifted.class); + public Mongolian(final Locale locale) { + super(new MongolianCustomizer(locale), Symbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class MongolianMNCustomizer extends EastSlavicCustomizer { - public MongolianMNCustomizer(final Locale locale) { - super(locale); - } + private static class MongolianCustomizer extends EastSlavicCustomizer { + MongolianCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getCurrencyKey() { return CURRENCY_TUGRIK; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Myanmar.java b/tests/src/com/android/inputmethod/keyboard/layout/Myanmar.java deleted file mode 100644 index 3c70d3266..000000000 --- a/tests/src/com/android/inputmethod/keyboard/layout/Myanmar.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.inputmethod.keyboard.layout; - -import com.android.inputmethod.keyboard.KeyboardId; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; - -import java.util.Locale; - -/** - * The Myanmar alphabet keyboard. - */ -public final class Myanmar extends LayoutBase { - private static final String LAYOUT_NAME = "myanmar"; - - public Myanmar(final LayoutCustomizer customizer) { - super(customizer, Symbols.class, SymbolsShifted.class); - } - - @Override - public String getName() { return LAYOUT_NAME; } - - public static class MyanmarCustomizer extends LayoutCustomizer { - public MyanmarCustomizer(final Locale locale) { super(locale); } - - @Override - public int getNumberOfRows() { return 5; } - - @Override - public ExpectedKey getAlphabetKey() { return MYANMAR_ALPHABET_KEY; } - - @Override - public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { - return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS; - } - - @Override - public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) { - // U+002C: "," COMMA - // U+104A: "၊" MYANMAR SIGN LITTLE SECTION - return isPhone ? joinKeys(key("\u002C", SETTINGS_KEY)) - : joinKeys(key("\u104A", moreKey(","), SETTINGS_KEY)); - } - - @Override - public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) { - // U+104B: "။" MYANMAR SIGN SECTION - final ExpectedKey periodKey = key("\u104B", getPunctuationMoreKeys(isPhone)); - return joinKeys(periodKey); - } - - @Override - public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) { - return isPhone ? MYANMAR_PHONE_PUNCTUATION_MORE_KEYS - : MYANMAR_TABLET_PUNCTUATION_MORE_KEYS; - } - - // U+1000: "က" MYANMAR LETTER KA - // U+1001: "ခ" MYANMAR LETTER KHA - // U+1002: "ဂ" MYANMAR LETTER GA - private static final ExpectedKey MYANMAR_ALPHABET_KEY = key( - "\u1000\u1001\u1002", Constants.CODE_SWITCH_ALPHA_SYMBOL); - - // U+104A: "၊" MYANMAR SIGN LITTLE SECTION - // Punctuation more keys for phone form factor. - private static final ExpectedKey[] MYANMAR_PHONE_PUNCTUATION_MORE_KEYS = joinKeys( - "\u104A", ".", "?", "!", "#", ")", "(", "/", ";", - "...", "'", "@", ":", "-", "\"", "+", "%", "&"); - // Punctuation more keys for tablet form factor. - private static final ExpectedKey[] MYANMAR_TABLET_PUNCTUATION_MORE_KEYS = joinKeys( - ".", "'", "#", ")", "(", "/", ";", "@", - "...", ":", "-", "\"", "+", "%", "&"); - } - - @Override - ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) { return ALPHABET_COMMON; } - - @Override - public ExpectedKey[][] getCommonAlphabetShiftLayout(final boolean isPhone, - final int elementId) { - if (elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) { - return getCommonAlphabetLayout(isPhone); - } - return ALPHABET_SHIFTED_COMMON; - } - - private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder() - .setKeysOfRow(1, - // U+1041: "၁" MYANMAR DIGIT ONE - key("\u1041", moreKey("1")), - // U+1042: "၂" MYANMAR DIGIT TWO - key("\u1042", moreKey("2")), - // U+1043: "၃" MYANMAR DIGIT THREE - key("\u1043", moreKey("3")), - // U+1044: "၄" MYANMAR DIGIT FOUR - key("\u1044", moreKey("4")), - // U+1045: "၅" MYANMAR DIGIT FIVE - key("\u1045", moreKey("5")), - // U+1046: "၆" MYANMAR DIGIT SIX - key("\u1046", moreKey("6")), - // U+1047: "၇" MYANMAR DIGIT SEVEN - key("\u1047", moreKey("7")), - // U+1048: "၈" MYANMAR DIGIT EIGHT - key("\u1048", moreKey("8")), - // U+1049: "၉" MYANMAR DIGIT NINE - key("\u1049", moreKey("9")), - // U+1040: "၀" MYANMAR DIGIT ZERO - key("\u1040", moreKey("0"))) - .setKeysOfRow(2, - // U+1006: "ဆ" MYANMAR LETTER CHA - // U+1039/U+1006: "္ဆ" MYANMAR SIGN VIRAMA/MYANMAR LETTER CHA - key("\u1006", moreKey("\u1039\u1006")), - // U+1010: "တ" MYANMAR LETTER TA - // U+1039/U+1010: "္တ" MYANMAR SIGN VIRAMA/MYANMAR LETTER TA - key("\u1010", moreKey("\u1039\u1010")), - // U+1014: "န" MYANMAR LETTER NA - // U+1039/U+1014: "္န" MYANMAR SIGN VIRAMA/MYANMAR LETTER NA - key("\u1014", moreKey("\u1039\u1014")), - // U+1019: "မ" MYANMAR LETTER MA - // U+1039/U+1019: "္မ" MYANMAR SIGN VIRAMA/MYANMAR LETTER MA - key("\u1019", moreKey("\u1039\u1019")), - // U+1021: "အ" MYANMAR LETTER A - // U+1015: "ပ" MYANMAR LETTER PA - "\u1021", "\u1015", - // U+1000: "က" MYANMAR LETTER KA - // U+1039/U+1000: "္က" MYANMAR SIGN VIRAMA/MYANMAR LETTER KA - key("\u1000", moreKey("\u1039\u1000")), - // U+1004: "င" MYANMAR LETTER NGA - // U+101E: "သ" MYANMAR LETTER SA - "\u1004", "\u101E", - // U+1005: "စ" MYANMAR LETTER CA - // U+1039/U+1005: "္စ" MYANMAR SIGN VIRAMA/MYANMAR LETTER CA - key("\u1005", moreKey("\u1039\u1005"))) - .setKeysOfRow(3, - // U+1031: "ေ" MYANMAR VOWEL SIGN E - // U+103B: "ျ" MYANMAR CONSONANT SIGN MEDIAL YA - // U+103C: "ြ" MYANMAR CONSONANT SIGN MEDIAL RA - "\u1031", "\u103B", "\u103C", - // U+103D: "ွ" MYANMAR CONSONANT SIGN MEDIAL WA - // U+103E: "ှ" MYANMAR CONSONANT SIGN MEDIAL HA - // U+103D/U+103E: - // "ွှ" MYANMAR CONSONANT SIGN MEDIAL WA/MYANMAR CONSONANT SIGN MEDIAL HA - key("\u103D", joinMoreKeys("\u103E", "\u103D\u103E")), - // U+102D: "ိ" MYANMAR VOWEL SIGN I - // U+102E: "ီ" MYANMAR VOWEL SIGN II - key("\u102D", moreKey("\u102E")), - // U+102F: "ု" MYANMAR VOWEL SIGN U - // U+1030: "ူ" MYANMAR VOWEL SIGN UU - key("\u102F", moreKey("\u1030")), - // U+102C: "ာ" MYANMAR VOWEL SIGN AA - // U+102B: "ါ" MYANMAR VOWEL SIGN TALL AA - key("\u102C", moreKey("\u102B")), - // U+103A: "်" MYANMAR SIGN ASAT - // U+1032: "ဲ" MYANMAR VOWEL SIGN AI - key("\u103A", moreKey("\u1032")), - // U+1037: "့" MYANMAR SIGN DOT BELOW - // U+1036: "ံ" MYANMAR SIGN ANUSVARA - key("\u1037", moreKey("\u1036")), - // U+1038: "း" MYANMAR SIGN VISARGA - "\u1038") - .setKeysOfRow(4, - // U+1016: "ဖ" MYANMAR LETTER PHA - "\u1016", - // U+1011: "ထ" MYANMAR LETTER THA - // U+1039/U+1011: "္ထ" MYANMAR SIGN VIRAMA/MYANMAR LETTER THA - key("\u1011", moreKey("\u1039\u1011")), - // U+1001: "ခ" MYANMAR LETTER KHA - // U+1039/U+1001: "္ခ" MYANMAR SIGN VIRAMA/MYANMAR LETTER KHA - key("\u1001", moreKey("\u1039\u1001")), - // U+101C: "လ" MYANMAR LETTER LA - // U+1039/U+101C: "္လ" MYANMAR SIGN VIRAMA/MYANMAR LETTER LA - key("\u101C", moreKey("\u1039\u101C")), - // U+1018: "ဘ" MYANMAR LETTER BHA - // U+1039/U+1018: "္ဘ" MYANMAR SIGN VIRAMA/MYANMAR LETTER BHA - key("\u1018", moreKey("\u1039\u1018")), - // U+100A: "ည" MYANMAR LETTER NNYA - // U+1009: "ဉ" MYANMAR LETTER NYA - key("\u100A", moreKey("\u1009")), - // U+101B: "ရ" MYANMAR LETTER RA - // U+101D: "ဝ" MYANMAR LETTER WA - "\u101B", "\u101D") - .build(); - - private static final ExpectedKey[][] ALPHABET_SHIFTED_COMMON = new ExpectedKeyboardBuilder() - .setKeysOfRow(1, - // U+1027: "ဧ" MYANMAR LETTER E - // U+104F: "၏" MYANMAR SYMBOL GENITIVE - // U+1024: "ဤ" MYANMAR LETTER II - // U+1023: "ဣ" MYANMAR LETTER I - // U+104E: "၎" MYANMAR SYMBOL AFOREMENTIONED - // U+1000/U+103B/U+1015/U+103A: "ကျပ်" MYANMAR LETTER KA - // /MYANMAR CONSONANT SIGN MEDIAL YA/MYANMAR LETTER PA/MYANMAR SIGN ASAT - // U+1029: "ဩ" MYANMAR LETTER O - // U+102A: "ဪ" MYANMAR LETTER AU - // U+104D: "၍" MYANMAR SYMBOL COMPLETED - // U+104C: "၌" MYANMAR SYMBOL LOCATIVE - "\u1027", "\u104F", "\u1024", "\u1023", "\u104E", "\u1000\u103B\u1015\u103A", - "\u1029", "\u102A", "\u104D", "\u104C") - .setKeysOfRow(2, - // U+1017: "ဗ" MYANMAR LETTER BA - // U+1039/U+1017: "္ဗ" MYANMAR SIGN VIRAMA/MYANMAR LETTER BA - key("\u1017", moreKey("\u1039\u1017")), - // U+1012: "ဒ" MYANMAR LETTER DA - // U+1039/U+1012: "္ဒ" MYANMAR SIGN VIRAMA/MYANMAR LETTER DA - key("\u1012", moreKey("\u1039\u1012")), - // U+1013: "ဓ" MYANMAR LETTER DHA - // U+1039/U+1013: "္ဓ" MYANMAR SIGN VIRAMA/MYANMAR LETTER DHA - key("\u1013", moreKey("\u1039\u1013")), - // U+1003: "ဃ" MYANMAR LETTER GHA - // U+100E: "ဎ" MYANMAR LETTER DDHA - // U+103F: "ဿ" MYANMAR LETTER GREAT SA - // U+100F: "ဏ" MYANMAR LETTER NNA - "\u1003", "\u100E", "\u103F", "\u100F", - // U+1008: "ဈ" MYANMAR LETTER JHA - // U+1039/U+1008: "္ဈ" MYANMAR SIGN VIRAMA/MYANMAR LETTER JHA - key("\u1008", moreKey("\u1039\u1008")), - // U+1007: "ဇ" MYANMAR LETTER JA - // U+1039/U+1007: "္ဇ" MYANMAR SIGN VIRAMA/MYANMAR LETTER JA - key("\u1007", moreKey("\u1039\u1007")), - // U+1002: "ဂ" MYANMAR LETTER GA - // U+1039/U+1002: "္ဂ" MYANMAR SIGN VIRAMA/MYANMAR LETTER GA - key("\u1002", moreKey("\u1039\u1002"))) - .setKeysOfRow(3, - // U+101A: "ယ" MYANMAR LETTER YA - // U+1039: "္" MYANMAR SIGN VIRAMA - // U+1004/U+103A/U+1039: "င်္င" MYANMAR LETTER NGA - // /MYANMAR SIGN ASAT/MYANMAR SIGN VIRAMA - // U+103E: "ှ" MYANMAR CONSONANT SIGN MEDIAL HA - // U+102E: "ီ" MYANMAR VOWEL SIGN II - // U+1030: "ူ" MYANMAR VOWEL SIGN UU - // U+102B: "ါ" MYANMAR VOWEL SIGN TALL AA - // U+1032: "ဲ" MYANMAR VOWEL SIGN AI - // U+1036: "ံ" MYANMAR SIGN ANUSVARA - // U+101F: "ဟ" MYANMAR LETTER HA - "\u101A", "\u1039", "\u1004\u103A\u1039", "\u103E", "\u102E", "\u1030", - "\u102B", "\u1032", "\u1036", "\u101F") - .setKeysOfRow(4, - // U+1025: "ဥ" MYANMAR LETTER U - // U+1026: "ဦ" MYANMAR LETTER UU - // U+100C: "ဌ" MYANMAR LETTER TTHA - // U+100B: "ဋ" MYANMAR LETTER TTA - // U+100D: "ဍ" MYANMAR LETTER DDA - // U+1020: "ဠ" MYANMAR LETTER LLA - // U+100B/U+1039/U+100C: "ဋ္ဌ" MYANMAR LETTER TTA - // /MYANMAR SIGN VIRAMA/MYANMAR LETTER TTHA - "\u1025", "\u1026", "\u100C", "\u100B", "\u100D", "\u1020", - "\u100B\u1039\u100C", - // U+100F/U+1039/U+100D: "ဏ္ဍ" MYANMAR LETTER NNA - // /MYANMAR SIGN VIRAMA/MYANMAR LETTER DDA - // U+100F/U+1039/U+100C: "ဏ္ဌ" MYANMAR LETTER NNA - // /MYANMAR SIGN VIRAMA/MYANMAR LETTER TTHA - key("\u100F\u1039\u100D", moreKey("\u100F\u1039\u100C"))) - .build(); -} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/NepaliRomanized.java b/tests/src/com/android/inputmethod/keyboard/layout/NepaliRomanized.java index 7933d078c..299cb61b2 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/NepaliRomanized.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/NepaliRomanized.java @@ -19,8 +19,8 @@ package com.android.inputmethod.keyboard.layout; import static com.android.inputmethod.keyboard.layout.DevanagariLetterConstants.*; import com.android.inputmethod.keyboard.KeyboardId; -import com.android.inputmethod.keyboard.layout.Hindi.HindiCustomizer; import com.android.inputmethod.keyboard.layout.Hindi.HindiSymbols; +import com.android.inputmethod.keyboard.layout.customizer.NepaliCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -32,35 +32,18 @@ import java.util.Locale; public final class NepaliRomanized extends LayoutBase { private static final String LAYOUT_NAME = "nepali_romanized"; - public NepaliRomanized(final LayoutCustomizer customizer) { - super(customizer, HindiSymbols.class, SymbolsShifted.class); + public NepaliRomanized(final Locale locale) { + super(new NepaliCustomizer(locale), HindiSymbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class NepaliRomanizedCustomizer extends HindiCustomizer { - public NepaliRomanizedCustomizer(final Locale locale) { super(locale); } - - @Override - public ExpectedKey getCurrencyKey() { return CURRENCY_NEPALI; } - - @Override - public ExpectedKey[] getSpaceKeys(final boolean isPhone) { - return joinKeys(LANGUAGE_SWITCH_KEY, SPACE_KEY, key(ZWNJ_KEY, ZWJ_KEY)); - } - - // U+0930/U+0941/U+002E "रु." NEPALESE RUPEE SIGN - private static final ExpectedKey CURRENCY_NEPALI = key("\u0930\u0941\u002E", - Symbols.DOLLAR_SIGN, Symbols.CENT_SIGN, Symbols.EURO_SIGN, Symbols.POUND_SIGN, - Symbols.YEN_SIGN, Symbols.PESO_SIGN); - } - @Override - ExpectedKey[][] getCommonAlphabetLayout(boolean isPhone) { return ALPHABET_COMMON; } + ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) { return ALPHABET_COMMON; } @Override - ExpectedKey[][] getCommonAlphabetShiftLayout(boolean isPhone, final int elementId) { + ExpectedKey[][] getCommonAlphabetShiftLayout(final boolean isPhone, final int elementId) { if (elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) { return getCommonAlphabetLayout(isPhone); } @@ -126,11 +109,9 @@ public final class NepaliRomanized extends LayoutBase { // U+0928: "न" DEVANAGARI LETTER NA // U+092E: "म" DEVANAGARI LETTER MA "\u0937", "\u0921", "\u091A", "\u0935", "\u092C", "\u0928", "\u092E", - // U+0964: "।" DEVANAGARI DANDA - // U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA - key("\u0964", moreKey("\u093D")), // U+094D: "्" DEVANAGARI SIGN VIRAMA - key(SIGN_VIRAMA, "\u094D")) + // U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA + key(SIGN_VIRAMA, "\u094D", moreKey("\u093D"))) .build(); private static final ExpectedKey[][] ALPHABET_SHIFTED_COMMON = new ExpectedKeyboardBuilder() @@ -180,8 +161,6 @@ public final class NepaliRomanized extends LayoutBase { // U+0902: "ं" DEVANAGARI SIGN ANUSVARA key(SIGN_ANUSVARA, "\u0902"), // U+0919: "ङ" DEVANAGARI LETTER NGA - "\u0919", - // U+094D: "्" DEVANAGARI SIGN VIRAMA - key(SIGN_VIRAMA, "\u094D")) + "\u0919") .build(); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/NepaliTraditional.java b/tests/src/com/android/inputmethod/keyboard/layout/NepaliTraditional.java index 4d6cdedbf..0a2bea342 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/NepaliTraditional.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/NepaliTraditional.java @@ -20,7 +20,7 @@ import static com.android.inputmethod.keyboard.layout.DevanagariLetterConstants. import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.keyboard.layout.Hindi.HindiSymbols; -import com.android.inputmethod.keyboard.layout.NepaliRomanized.NepaliRomanizedCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.NepaliCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -32,93 +32,31 @@ import java.util.Locale; public final class NepaliTraditional extends LayoutBase { private static final String LAYOUT_NAME = "nepali_traditional"; - public NepaliTraditional(final LayoutCustomizer customizer) { - super(customizer, HindiSymbols.class, SymbolsShifted.class); + public NepaliTraditional(final Locale locale) { + super(new NepaliTraditionalCustomizer(locale), HindiSymbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class NepaliTraditionalCustomizer extends NepaliRomanizedCustomizer { - public NepaliTraditionalCustomizer(final Locale locale) { super(locale); } + private static class NepaliTraditionalCustomizer extends NepaliCustomizer { + NepaliTraditionalCustomizer(final Locale locale) { super(locale); } @Override - public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { return EMPTY_KEYS; } - - @Override - public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) { - if (isPhone) { - // U+094D: "्" DEVANAGARI SIGN VIRAMA - return joinKeys(key(SIGN_VIRAMA, "\u094D", PHONE_PUNCTUATION_MORE_KEYS)); - } - return super.getKeysRightToSpacebar(isPhone); + public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { + return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS; } } @Override - ExpectedKey[][] getCommonAlphabetLayout(boolean isPhone) { - final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON); - if (isPhone) { - builder.addKeysOnTheRightOfRow(3, - // U+0947: "े" DEVANAGARI VOWEL SIGN E - // U+0903: "ः" DEVANAGARI SIGN VISARGA - // U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA - key(VOWEL_SIGN_E, "\u0947", joinMoreKeys( - moreKey(SIGN_VISARGA, "\u0903"), "\u093D")), - // U+0964: "।" DEVANAGARI DANDA - "\u0964", - // U+0930: "र" DEVANAGARI LETTER RA - // U+0930/U+0941: "रु" DEVANAGARI LETTER RA/DEVANAGARI VOWEL SIGN U - key("\u0930", moreKey("\u0930\u0941"))); - } else { - builder.addKeysOnTheRightOfRow(3, - // U+0903: "ः" DEVANAGARI SIGN VISARGA - // U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA - key(SIGN_VISARGA, "\u0903", moreKey("\u093D")), - // U+0947: "े" DEVANAGARI VOWEL SIGN E - key(VOWEL_SIGN_E, "\u0947"), - // U+0964: "।" DEVANAGARI DANDA - "\u0964", - // U+0930: "र" DEVANAGARI LETTER RA - key("\u0930", moreKey("!")), - // U+094D: "्" DEVANAGARI SIGN VIRAMA - key(SIGN_VIRAMA, "\u094D", moreKey("?"))); - } - return builder.build(); - } + ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) { return ALPHABET_COMMON; } @Override - ExpectedKey[][] getCommonAlphabetShiftLayout(boolean isPhone, final int elementId) { + ExpectedKey[][] getCommonAlphabetShiftLayout(final boolean isPhone, final int elementId) { if (elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) { return getCommonAlphabetLayout(isPhone); } - final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder( - ALPHABET_SHIFTED_COMMON); - if (isPhone) { - builder.addKeysOnTheRightOfRow(3, - // U+0902: "ं" DEVANAGARI SIGN ANUSVARA - key(SIGN_ANUSVARA, "\u0902"), - // U+0919: "ङ" DEVANAGARI LETTER NGA - "\u0919", - // U+0948: "ै" DEVANAGARI VOWEL SIGN AI - // U+0936/U+094D/U+0930: - // "श्र" DEVANAGARI LETTER SHA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER RA - key(VOWEL_SIGN_AI, "\u0948", moreKey("\u0936\u094D\u0930"))); - } else { - builder.addKeysOnTheRightOfRow(3, - // U+0902: "ं" DEVANAGARI SIGN ANUSVARA - key(SIGN_ANUSVARA, "\u0902"), - // U+0919: "ङ" DEVANAGARI LETTER NGA - "\u0919", - // U+0948: "ै" DEVANAGARI VOWEL SIGN AI - // U+0936/U+094D/U+0930: - // "श्र" DEVANAGARI LETTER SHA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER RA - key(VOWEL_SIGN_AI, "\u0948", moreKey("\u0936\u094D\u0930")), - // U+0930/U+0941: "रु" DEVANAGARI LETTER RA/DEVANAGARI VOWEL SIGN U - key("\u0930\u0941", moreKey("!")), - "?"); - } - return builder.build(); + return ALPHABET_SHIFTED_COMMON; } private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder() @@ -181,7 +119,17 @@ public final class NepaliTraditional extends LayoutBase { // U+0916: "ख" DEVANAGARI LETTER KHA // U+0926: "द" DEVANAGARI LETTER DA // U+0932: "ल" DEVANAGARI LETTER LA - "\u0936", "\u0939", "\u0905", "\u0916", "\u0926", "\u0932") + "\u0936", "\u0939", "\u0905", "\u0916", "\u0926", "\u0932", + // U+0947: "े" DEVANAGARI VOWEL SIGN E + // U+0903: "ः" DEVANAGARI SIGN VISARGA + // U+093D: "ऽ" DEVANAGARI SIGN AVAGRAHA + key(VOWEL_SIGN_E, "\u0947", joinMoreKeys( + moreKey(SIGN_VISARGA, "\u0903"), "\u093D")), + // U+094D: "्" DEVANAGARI SIGN VIRAMA + key(SIGN_VIRAMA, "\u094D"), + // U+0930: "र" DEVANAGARI LETTER RA + // U+0930/U+0941: "रु" DEVANAGARI LETTER RA/DEVANAGARI VOWEL SIGN U + key("\u0930", moreKey("\u0930\u0941"))) .build(); private static final ExpectedKey[][] ALPHABET_SHIFTED_COMMON = new ExpectedKeyboardBuilder() @@ -264,6 +212,14 @@ public final class NepaliTraditional extends LayoutBase { key(VOWEL_SIGN_AU, "\u094C"), // U+0926/U+094D/U+092F: // "द्य" DEVANAGARI LETTER DA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER YA - "\u0926\u094D\u092F") + "\u0926\u094D\u092F", + // U+0902: "ं" DEVANAGARI SIGN ANUSVARA + key(SIGN_ANUSVARA, "\u0902"), + // U+0919: "ङ" DEVANAGARI LETTER NGA + "\u0919", + // U+0948: "ै" DEVANAGARI VOWEL SIGN AI + // U+0936/U+094D/U+0930: + // "श्र" DEVANAGARI LETTER SHA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER RA + key(VOWEL_SIGN_AI, "\u0948", moreKey("\u0936\u094D\u0930"))) .build(); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Nordic.java b/tests/src/com/android/inputmethod/keyboard/layout/Nordic.java index c791c404d..4f718e64f 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Nordic.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Nordic.java @@ -16,6 +16,7 @@ package com.android.inputmethod.keyboard.layout; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/PcQwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/PcQwerty.java index 3f7340fd0..0085ac6a8 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/PcQwerty.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/PcQwerty.java @@ -17,11 +17,10 @@ package com.android.inputmethod.keyboard.layout; import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import java.util.Locale; - /** * The PC QWERTY alphabet keyboard. */ @@ -35,35 +34,6 @@ public final class PcQwerty extends LayoutBase { @Override public String getName() { return LAYOUT_NAME; } - public static class PcQwertyCustomizer extends LayoutCustomizer { - public PcQwertyCustomizer(final Locale locale) { super(locale); } - - @Override - public int getNumberOfRows() { return 5; } - - @Override - public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) { - return joinKeys(SHIFT_KEY); - } - - @Override - public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { - return joinKeys(SHIFT_KEY); - } - - @Override - public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) { - return joinKeys(SETTINGS_KEY); - } - - @Override - public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) { - return isPhone - ? joinKeys(key(ENTER_KEY, EMOJI_ACTION_KEY)) - : joinKeys(EMOJI_NORMAL_KEY); - } - } - @Override ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) { final LayoutCustomizer customizer = getCustomizer(); diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Qwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/Qwerty.java index d790a1e53..508df0c17 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Qwerty.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Qwerty.java @@ -16,6 +16,7 @@ package com.android.inputmethod.keyboard.layout; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Qwertz.java b/tests/src/com/android/inputmethod/keyboard/layout/Qwertz.java index 26ba6cffb..cc41fbf20 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Qwertz.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Qwertz.java @@ -16,6 +16,7 @@ package com.android.inputmethod.keyboard.layout; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/SerbianQwertz.java b/tests/src/com/android/inputmethod/keyboard/layout/SerbianQwertz.java new file mode 100644 index 000000000..a4936288a --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/SerbianQwertz.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout; + +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +public final class SerbianQwertz extends LayoutBase { + private static final String LAYOUT_NAME = "serbian_qwertz"; + + public SerbianQwertz(final LayoutCustomizer customizer) { + super(customizer, Symbols.class, SymbolsShifted.class); + } + + @Override + public String getName() { return LAYOUT_NAME; } + + @Override + ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) { return ALPHABET_COMMON; } + + public static final String ROW1_11 = "ROW1_11"; + public static final String ROW2_10 = "ROW2_10"; + public static final String ROW2_11 = "ROW2_11"; + public static final String ROW3_8 = "ROW3_8"; + public static final String ROW3_9 = "ROW3_9"; + + private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder() + .setKeysOfRow(1, + key("q", additionalMoreKey("1")), + key("w", additionalMoreKey("2")), + key("e", additionalMoreKey("3")), + key("r", additionalMoreKey("4")), + key("t", additionalMoreKey("5")), + key("z", additionalMoreKey("6")), + key("u", additionalMoreKey("7")), + key("i", additionalMoreKey("8")), + key("o", additionalMoreKey("9")), + key("p", additionalMoreKey("0")), + ROW1_11) + .setKeysOfRow(2, "a", "s", "d", "f", "g", "h", "j", "k", "l", ROW2_10, ROW2_11) + .setKeysOfRow(3, "y", "x", "c", "v", "b", "n", "m", ROW3_8, ROW3_9) + .build(); +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Sinhala.java b/tests/src/com/android/inputmethod/keyboard/layout/Sinhala.java index 354141d5a..c3a9351f7 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Sinhala.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Sinhala.java @@ -17,9 +17,10 @@ package com.android.inputmethod.keyboard.layout; import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; import java.util.Locale; @@ -29,15 +30,15 @@ import java.util.Locale; public final class Sinhala extends LayoutBase { private static final String LAYOUT_NAME = "sinhala"; - public Sinhala(final LayoutCustomizer customizer) { - super(customizer, Symbols.class, SymbolsShifted.class); + public Sinhala(final Locale locale) { + super(new SinhalaCustomizer(locale), Symbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class SinhalaCustomizer extends LayoutCustomizer { - public SinhalaCustomizer(final Locale locale) { super(locale); } + private static class SinhalaCustomizer extends LayoutCustomizer { + SinhalaCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getAlphabetKey() { return SINHALA_ALPHABET_KEY; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/SouthSlavic.java b/tests/src/com/android/inputmethod/keyboard/layout/SouthSlavic.java index be8b435d4..ad8278754 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/SouthSlavic.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/SouthSlavic.java @@ -16,11 +16,9 @@ package com.android.inputmethod.keyboard.layout; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; - -import java.util.Locale; public final class SouthSlavic extends LayoutBase { private static final String LAYOUT_NAME = "south_slavic"; @@ -32,26 +30,6 @@ public final class SouthSlavic extends LayoutBase { @Override public String getName() { return LAYOUT_NAME; } - public static class SouthSlavicLayoutCustomizer extends LayoutCustomizer { - public SouthSlavicLayoutCustomizer(final Locale locale) { - super(locale); - } - - @Override - public final ExpectedKey getAlphabetKey() { return SOUTH_SLAVIC_ALPHABET_KEY; } - - @Override - public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { - return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS; - } - - // U+0410: "А" CYRILLIC CAPITAL LETTER A - // U+0411: "Б" CYRILLIC CAPITAL LETTER BE - // U+0412: "В" CYRILLIC CAPITAL LETTER VE - private static final ExpectedKey SOUTH_SLAVIC_ALPHABET_KEY = key( - "\u0410\u0411\u0412", Constants.CODE_SWITCH_ALPHA_SYMBOL); - } - @Override ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) { return ALPHABET_COMMON; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Spanish.java b/tests/src/com/android/inputmethod/keyboard/layout/Spanish.java index 225b9f604..fc6f1ea95 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Spanish.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Spanish.java @@ -16,6 +16,7 @@ package com.android.inputmethod.keyboard.layout; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Swiss.java b/tests/src/com/android/inputmethod/keyboard/layout/Swiss.java index 01a602054..57e3725a5 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Swiss.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Swiss.java @@ -16,6 +16,7 @@ package com.android.inputmethod.keyboard.layout; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Symbols.java b/tests/src/com/android/inputmethod/keyboard/layout/Symbols.java index 803089721..7ad7b5442 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Symbols.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Symbols.java @@ -16,7 +16,7 @@ package com.android.inputmethod.keyboard.layout; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.AbstractLayoutBase; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -41,13 +41,13 @@ public class Symbols extends AbstractLayoutBase { customizer.getSingleQuoteMoreKeys(), customizer.getSingleAngleQuoteKeys()))); if (isPhone) { builder.addKeysOnTheLeftOfRow(3, customizer.getSymbolsShiftKey(isPhone)) - .addKeysOnTheRightOfRow(3, LayoutBase.DELETE_KEY) + .addKeysOnTheRightOfRow(3, DELETE_KEY) .addKeysOnTheLeftOfRow(4, customizer.getAlphabetKey()) .addKeysOnTheRightOfRow(4, customizer.getEnterKey(isPhone)); } else { // Tablet symbols keyboard has extra two keys at the left edge of the 3rd row. builder.addKeysOnTheLeftOfRow(3, (Object[])joinKeys("\\", "=")); - builder.addKeysOnTheRightOfRow(1, LayoutBase.DELETE_KEY) + builder.addKeysOnTheRightOfRow(1, DELETE_KEY) .addKeysOnTheRightOfRow(2, customizer.getEnterKey(isPhone)) .addKeysOnTheLeftOfRow(3, customizer.getSymbolsShiftKey(isPhone)) .addKeysOnTheRightOfRow(3, customizer.getSymbolsShiftKey(isPhone)) @@ -167,7 +167,7 @@ public class Symbols extends AbstractLayoutBase { // U+00BF: "¿" INVERTED QUESTION MARK key("?", moreKey("\u00BF"))) .setKeysOfRow(4, - key(","), key("_"), LayoutBase.SPACE_KEY, key("/"), + key(","), key("_"), SPACE_KEY, key("/"), // U+2026: "…" HORIZONTAL ELLIPSIS key(".", moreKey("\u2026"))) .build(); diff --git a/tests/src/com/android/inputmethod/keyboard/layout/SymbolsShifted.java b/tests/src/com/android/inputmethod/keyboard/layout/SymbolsShifted.java index 19cb6075a..64262167d 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/SymbolsShifted.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/SymbolsShifted.java @@ -16,7 +16,7 @@ package com.android.inputmethod.keyboard.layout; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import com.android.inputmethod.keyboard.layout.expected.AbstractLayoutBase; @@ -37,7 +37,7 @@ public class SymbolsShifted extends AbstractLayoutBase { builder.replaceKeyOfLabel(OTHER_CURRENCIES, (Object[])customizer.getOtherCurrencyKeys()); if (isPhone) { builder.addKeysOnTheLeftOfRow(3, customizer.getBackToSymbolsKey()) - .addKeysOnTheRightOfRow(3, LayoutBase.DELETE_KEY) + .addKeysOnTheRightOfRow(3, DELETE_KEY) .addKeysOnTheLeftOfRow(4, customizer.getAlphabetKey()) .addKeysOnTheRightOfRow(4, customizer.getEnterKey(isPhone)); } else { @@ -45,7 +45,7 @@ public class SymbolsShifted extends AbstractLayoutBase { // U+00BF: "¿" INVERTED QUESTION MARK // U+00A1: "¡" INVERTED EXCLAMATION MARK builder.addKeysOnTheRightOfRow(3, (Object[])joinKeys("\u00A1", "\u00BF")); - builder.addKeysOnTheRightOfRow(1, LayoutBase.DELETE_KEY) + builder.addKeysOnTheRightOfRow(1, DELETE_KEY) .addKeysOnTheRightOfRow(2, customizer.getEnterKey(isPhone)) .addKeysOnTheLeftOfRow(3, customizer.getBackToSymbolsKey()) .addKeysOnTheRightOfRow(3, customizer.getBackToSymbolsKey()) @@ -122,7 +122,7 @@ public class SymbolsShifted extends AbstractLayoutBase { // U+2264: "≤" LESS-THAN OR EQUAL TO // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK key("<", joinMoreKeys("\u2039", "\u2264", "\u00AB")), - LayoutBase.SPACE_KEY, + SPACE_KEY, // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK // U+2265: "≥" GREATER-THAN EQUAL TO // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Tamil.java b/tests/src/com/android/inputmethod/keyboard/layout/Tamil.java index 597b6fa55..1413e366a 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Tamil.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Tamil.java @@ -16,11 +16,9 @@ package com.android.inputmethod.keyboard.layout; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; - -import java.util.Locale; /** * The Tamil keyboard. @@ -35,29 +33,6 @@ public final class Tamil extends LayoutBase { @Override public String getName() { return LAYOUT_NAME; } - public static class TamilCustomizer extends LayoutCustomizer { - public TamilCustomizer(final Locale locale) { super(locale); } - - @Override - public ExpectedKey getAlphabetKey() { return TAMIL_ALPHABET_KEY; } - - @Override - public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) { - return EMPTY_KEYS; - } - - @Override - public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { - return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS; - } - - // U+0BA4: "த" TAMIL LETTER TA - // U+0BAE/U+0BBF: "மி" TAMIL LETTER MA/TAMIL VOWEL SIGN I - // U+0BB4/U+0BCD: "ழ்" TAMIL LETTER LLLA/TAMIL SIGN VIRAMA - private static final ExpectedKey TAMIL_ALPHABET_KEY = key( - "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", Constants.CODE_SWITCH_ALPHA_SYMBOL); - } - @Override ExpectedKey[][] getCommonAlphabetLayout(boolean isPhone) { return ALPHABET_COMMON; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Telugu.java b/tests/src/com/android/inputmethod/keyboard/layout/Telugu.java index cc8224c54..81437f3ac 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Telugu.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Telugu.java @@ -16,9 +16,10 @@ package com.android.inputmethod.keyboard.layout; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; import java.util.Locale; @@ -28,15 +29,15 @@ import java.util.Locale; public final class Telugu extends LayoutBase { private static final String LAYOUT_NAME = "telugu"; - public Telugu(final LayoutCustomizer customizer) { - super(customizer, Symbols.class, SymbolsShifted.class); + public Telugu(final Locale locale) { + super(new TeluguCustomizer(locale), Symbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class TeluguCustomizer extends LayoutCustomizer { - public TeluguCustomizer(final Locale locale) { super(locale); } + private static class TeluguCustomizer extends LayoutCustomizer { + TeluguCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getAlphabetKey() { return TELUGU_ALPHABET_KEY; } @@ -139,8 +140,8 @@ public final class Telugu extends LayoutBase { key("\u0C2A", moreKey("\u0C2B")), // U+0C30: "ర" TELUGU LETTER RA // U+0C31: "ఱ" TELUGU LETTER RRA - // U+0C43: "ృ" TELUGU VOWEL SIGN VOCALIC R - key("\u0C30", joinMoreKeys("\u0C31", "\u0C43")), + // U+0C4D/U+0C30: "్ర" TELUGU SIGN VIRAMA/TELUGU LETTER RA + key("\u0C30", joinMoreKeys("\u0C31", "\u0C4D\u0C30")), // U+0C15: "క" TELUGU LETTER KA // U+0C16: "ఖ" TELUGU LETTER KHA key("\u0C15", moreKey("\u0C16")), @@ -154,18 +155,21 @@ public final class Telugu extends LayoutBase { // U+0C20: "ఠ" TELUGU LETTER TTHA key("\u0C1F", moreKey("\u0C20"))) .setKeysOfRow(3, - // U+0C46: "ె" TELUGU VOWEL SIGN E + // U+0C4A: "ొ" TELUGU VOWEL SIGN O // U+0C12: "ఒ" TELUGU LETTER O - key("\u0C46", moreKey("\u0C12")), - // U+0C02: "ం" TELUGU SIGN ANUSVARA + key("\u0C4A", moreKey("\u0C12")), + // U+0C46: "ె" TELUGU VOWEL SIGN E // U+0C0E: "ఎ" TELUGU LETTER E - key("\u0C02", moreKey("\u0C0E")), + key("\u0C46", moreKey("\u0C0E")), // U+0C2E: "మ" TELUGU LETTER MA - "\u0C2E", + // U+0C02: "ం" TELUGU SIGN ANUSVARA + // U+0C01: "ఁ" TELUGU SIGN CANDRABINDU + key("\u0C2E", joinMoreKeys("\u0C02", "\u0C01")), // U+0C28: "న" TELUGU LETTER NA // U+0C23: "ణ" TELUGU LETTER NNA // U+0C19: "ఙ" TELUGU LETTER NGA - key("\u0C28", joinMoreKeys("\u0C23", "\u0C19")), + // U+0C1E: "ఞ" TELUGU LETTER NYA + key("\u0C28", joinMoreKeys("\u0C23", "\u0C19", "\u0C1E")), // U+0C35: "వ" TELUGU LETTER VA "\u0C35", // U+0C32: "ల" TELUGU LETTER LA @@ -175,8 +179,8 @@ public final class Telugu extends LayoutBase { // U+0C36: "శ" TELUGU LETTER SHA key("\u0C38", moreKey("\u0C36")), // U+0C0B: "ఋ" TELUGU LETTER VOCALIC R - // U+0C4D/U+0C30: "్ర" TELUGU SIGN VIRAMA/TELUGU LETTER RA - key("\u0C0B", moreKey("\u0C4D\u0C30")), + // U+0C43: "ృ" TELUGU VOWEL SIGN VOCALIC R + key("\u0C0B", moreKey("\u0C43")), // U+0C37: "ష" TELUGU LETTER SSA // U+0C15/U+0C4D/U+0C37: // "క్ష" TELUGU LETTER KA/TELUGU SIGN VIRAMA/TELUGU LETTER SSA diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Thai.java b/tests/src/com/android/inputmethod/keyboard/layout/Thai.java index cfda2947c..ce5fd8068 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/Thai.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/Thai.java @@ -17,9 +17,10 @@ package com.android.inputmethod.keyboard.layout; import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; import java.util.Locale; @@ -29,15 +30,15 @@ import java.util.Locale; public final class Thai extends LayoutBase { private static final String LAYOUT_NAME = "thai"; - public Thai(final LayoutCustomizer customizer) { - super(customizer, Symbols.class, SymbolsShifted.class); + public Thai(final Locale locale) { + super(new ThaiCustomizer(locale), Symbols.class, SymbolsShifted.class); } @Override public String getName() { return LAYOUT_NAME; } - public static class ThaiCustomizer extends LayoutCustomizer { - public ThaiCustomizer(final Locale locale) { super(locale); } + private static class ThaiCustomizer extends LayoutCustomizer { + ThaiCustomizer(final Locale locale) { super(locale); } @Override public int getNumberOfRows() { return 5; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/Uzbek.java b/tests/src/com/android/inputmethod/keyboard/layout/Uzbek.java new file mode 100644 index 000000000..f37fd2241 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/Uzbek.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout; + +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +/** + * The Uzbek alphabet keyboard. + */ +public final class Uzbek extends LayoutBase { + private static final String LAYOUT_NAME = "uzbek"; + + public Uzbek(final LayoutCustomizer customizer) { + super(customizer, Symbols.class, SymbolsShifted.class); + } + + @Override + public String getName() { return LAYOUT_NAME; } + + @Override + ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) { return ALPHABET_COMMON; } + + public static final String ROW1_11 = "ROW1_11"; + public static final String ROW2_10 = "ROW2_10"; + public static final String ROW2_11 = "ROW2_11"; + + private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder() + .setKeysOfRow(1, + key("q", additionalMoreKey("1")), + key("w", additionalMoreKey("2")), + key("e", additionalMoreKey("3")), + key("r", additionalMoreKey("4")), + key("t", additionalMoreKey("5")), + key("y", additionalMoreKey("6")), + key("u", additionalMoreKey("7")), + key("i", additionalMoreKey("8")), + key("o", additionalMoreKey("9")), + key("p", additionalMoreKey("0")), + ROW1_11) + .setKeysOfRow(2, "a", "s", "d", "f", "g", "h", "j", "k", "l", ROW2_10, ROW2_11) + .setKeysOfRow(3, "z", "x", "c", "v", "b", "n", "m") + .build(); +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/BengaliCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/BengaliCustomizer.java new file mode 100644 index 000000000..f13c26114 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/BengaliCustomizer.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.SymbolsShifted; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.latin.common.Constants; + +import java.util.Locale; + +public class BengaliCustomizer extends LayoutCustomizer { + public BengaliCustomizer(final Locale locale) { super(locale); } + + @Override + public ExpectedKey getAlphabetKey() { return BENGALI_ALPHABET_KEY; } + + @Override + public ExpectedKey[] getOtherCurrencyKeys() { + return SymbolsShifted.CURRENCIES_OTHER_GENERIC; + } + + @Override + public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { + return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS; + } + + // U+0995: "क" BENGALI LETTER KA + // U+0996: "ख" BENGALI LETTER KHA + // U+0997: "ग" BENGALI LETTER GA + private static final ExpectedKey BENGALI_ALPHABET_KEY = key( + "\u0995\u0996\u0997", Constants.CODE_SWITCH_ALPHA_SYMBOL); +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/DanishCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/DanishCustomizer.java new file mode 100644 index 000000000..3d91194f2 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/DanishCustomizer.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.Nordic; +import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +public class DanishCustomizer extends EuroCustomizer { + public DanishCustomizer(final Locale locale) { super(locale); } + + @Override + public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; } + + @Override + public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_R9L; } + + @Override + public ExpectedKey[] getDoubleAngleQuoteKeys() { return Symbols.DOUBLE_ANGLE_QUOTES_RL; } + + @Override + public ExpectedKey[] getSingleAngleQuoteKeys() { return Symbols.SINGLE_ANGLE_QUOTES_RL; } + + protected void setNordicKeys(final ExpectedKeyboardBuilder builder) { + builder + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + .replaceKeyOfLabel(Nordic.ROW1_11, "\u00E5") + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + .replaceKeyOfLabel(Nordic.ROW2_10, "\u00E6") + .setMoreKeysOf("\u00E6", "\u00E4") + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + .replaceKeyOfLabel(Nordic.ROW2_11, "\u00F8") + .setMoreKeysOf("\u00F8", "\u00F6"); + } + + protected void setMoreKeysOfA(final ExpectedKeyboardBuilder builder) { + builder + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + .setMoreKeysOf("a", "\u00E1", "\u00E4", "\u00E0", "\u00E2", "\u00E3", "\u0101"); + } + + protected void setMoreKeysOfO(final ExpectedKeyboardBuilder builder) { + builder + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + .setMoreKeysOf("o", "\u00F6", "\u00F3", "\u00F4", "\u00F2", "\u00F5", "\u0153", + "\u014D"); + } + + @Override + public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { + setNordicKeys(builder); + setMoreKeysOfA(builder); + setMoreKeysOfO(builder); + return builder + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + .setMoreKeysOf("e", "\u00E9", "\u00EB") + // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE + // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS + .setMoreKeysOf("y", "\u00FD", "\u00FF") + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + .setMoreKeysOf("u", "\u00FA", "\u00FC", "\u00FB", "\u00F9", "\u016B") + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + .setMoreKeysOf("i", "\u00ED", "\u00EF") + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + .setMoreKeysOf("s", "\u00DF", "\u015B", "\u0161") + // U+00F0: "ð" LATIN SMALL LETTER ETH + .setMoreKeysOf("d", "\u00F0") + // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE + .setMoreKeysOf("l", "\u0142") + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + .setMoreKeysOf("n", "\u00F1", "\u0144"); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/DevanagariCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/DevanagariCustomizer.java new file mode 100644 index 000000000..13f9171d4 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/DevanagariCustomizer.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.latin.common.Constants; + +import java.util.Locale; + +public class DevanagariCustomizer extends LayoutCustomizer { + public DevanagariCustomizer(final Locale locale) { super(locale); } + + @Override + public ExpectedKey getAlphabetKey() { return HINDI_ALPHABET_KEY; } + + @Override + public ExpectedKey getSymbolsKey() { return HINDI_SYMBOLS_KEY; } + + @Override + public ExpectedKey getBackToSymbolsKey() { return HINDI_BACK_TO_SYMBOLS_KEY; } + + // U+0915: "क" DEVANAGARI LETTER KA + // U+0916: "ख" DEVANAGARI LETTER KHA + // U+0917: "ग" DEVANAGARI LETTER GA + private static final ExpectedKey HINDI_ALPHABET_KEY = key( + "\u0915\u0916\u0917", Constants.CODE_SWITCH_ALPHA_SYMBOL); + // U+0967: "१" DEVANAGARI DIGIT ONE + // U+0968: "२" DEVANAGARI DIGIT TWO + // U+0969: "३" DEVANAGARI DIGIT THREE + private static final String HINDI_SYMBOLS_LABEL = "?\u0967\u0968\u0969"; + private static final ExpectedKey HINDI_SYMBOLS_KEY = key(HINDI_SYMBOLS_LABEL, + Constants.CODE_SWITCH_ALPHA_SYMBOL); + private static final ExpectedKey HINDI_BACK_TO_SYMBOLS_KEY = key(HINDI_SYMBOLS_LABEL, + Constants.CODE_SHIFT); +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/DutchCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/DutchCustomizer.java new file mode 100644 index 000000000..825afb64b --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/DutchCustomizer.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +public class DutchCustomizer extends EuroCustomizer { + public DutchCustomizer(final Locale locale) { super(locale); } + + @Override + public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_L9R; } + + @Override + public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_L9R; } + + @Override + public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { + return builder + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + .setMoreKeysOf("a", + "\u00E1", "\u00E4", "\u00E2", "\u00E0", "\u00E6", "\u00E3", "\u00E5", + "\u0101") + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + .setMoreKeysOf("e", + "\u00E9", "\u00EB", "\u00EA", "\u00E8", "\u0119", "\u0117", "\u0113") + // U+0133: "ij" LATIN SMALL LIGATURE IJ + .setMoreKeysOf("y", "\u0133") + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + .setMoreKeysOf("u", "\u00FA", "\u00FC", "\u00FB", "\u00F9", "\u016B") + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + // U+0133: "ij" LATIN SMALL LIGATURE IJ + .setMoreKeysOf("i", + "\u00ED", "\u00EF", "\u00EC", "\u00EE", "\u012F", "\u012B", "\u0133") + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + .setMoreKeysOf("o", + "\u00F3", "\u00F6", "\u00F4", "\u00F2", "\u00F5", "\u0153", "\u00F8", + "\u014D") + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + .setMoreKeysOf("n", "\u00F1", "\u0144"); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/DvorakCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/DvorakCustomizer.java new file mode 100644 index 000000000..b7b018793 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/DvorakCustomizer.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey.ExpectedAdditionalMoreKey; + +import java.util.Locale; + +public class DvorakCustomizer extends LayoutCustomizer { + public DvorakCustomizer(final Locale locale) { super(locale); } + + @Override + public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) { + return isPhone ? joinKeys(SHIFT_KEY): joinKeys(SHIFT_KEY, key("q")); + } + + @Override + public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { + return isPhone ? EMPTY_KEYS : joinKeys(key("z"), SHIFT_KEY); + } + + @Override + public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) { + // U+00A1: "¡" INVERTED EXCLAMATION MARK + return isPhone ? joinKeys(key("q", SETTINGS_KEY)) + : joinKeys(key("!", joinMoreKeys("\u00A1", SETTINGS_KEY))); + } + + @Override + public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) { + final ExpectedAdditionalMoreKey[] punctuationMoreKeys = + convertToAdditionalMoreKeys(getPunctuationMoreKeys(isPhone)); + // U+00BF: "¿" INVERTED QUESTION MARK + return isPhone + ? joinKeys(key("z", punctuationMoreKeys)) + : joinKeys(key("?", joinMoreKeys(punctuationMoreKeys, "\u00BF"))); + } + + private static ExpectedAdditionalMoreKey[] convertToAdditionalMoreKeys( + final ExpectedKey ... moreKeys) { + final ExpectedAdditionalMoreKey[] additionalMoreKeys = + new ExpectedAdditionalMoreKey[moreKeys.length]; + for (int index = 0; index < moreKeys.length; index++) { + additionalMoreKeys[index] = ExpectedAdditionalMoreKey.newInstance(moreKeys[index]); + } + return additionalMoreKeys; + } + + public static class EnglishDvorakCustomizer extends DvorakCustomizer { + private final EnglishCustomizer mEnglishCustomizer; + + public EnglishDvorakCustomizer(final Locale locale) { + super(locale); + mEnglishCustomizer = new EnglishCustomizer(locale); + } + + @Override + public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { + return mEnglishCustomizer.setAccentedLetters(builder); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/EastSlavicCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/EastSlavicCustomizer.java new file mode 100644 index 000000000..8815b068c --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/EastSlavicCustomizer.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.latin.common.Constants; + +import java.util.Locale; + +public class EastSlavicCustomizer extends LayoutCustomizer { + public EastSlavicCustomizer(final Locale locale) { super(locale); } + + @Override + public final ExpectedKey getAlphabetKey() { return EAST_SLAVIC_ALPHABET_KEY; } + + @Override + public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { + return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS; + } + + // U+0410: "А" CYRILLIC CAPITAL LETTER A + // U+0411: "Б" CYRILLIC CAPITAL LETTER BE + // U+0412: "В" CYRILLIC CAPITAL LETTER VE + private static final ExpectedKey EAST_SLAVIC_ALPHABET_KEY = key( + "\u0410\u0411\u0412", Constants.CODE_SWITCH_ALPHA_SYMBOL); +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/EnglishCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/EnglishCustomizer.java index 3e82f65bf..9a9c6bb2f 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/EnglishCustomizer.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/EnglishCustomizer.java @@ -14,15 +14,14 @@ * limitations under the License. */ -package com.android.inputmethod.keyboard.layout.tests; +package com.android.inputmethod.keyboard.layout.customizer; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; -class EnglishCustomizer extends LayoutCustomizer { - EnglishCustomizer(final Locale locale) { super(locale); } +public class EnglishCustomizer extends LayoutCustomizer { + public EnglishCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/EstonianEECustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/EstonianEECustomizer.java new file mode 100644 index 000000000..a7d611a3e --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/EstonianEECustomizer.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.KeyboardId; +import com.android.inputmethod.keyboard.layout.Nordic; +import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +public class EstonianEECustomizer extends EuroCustomizer { + public EstonianEECustomizer(final Locale locale) { super(locale); } + + @Override + public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; } + + @Override + public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_R9L; } + + protected void setNordicKeys(final ExpectedKeyboardBuilder builder) { + builder + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + .replaceKeyOfLabel(Nordic.ROW1_11, "\u00FC") + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + .replaceKeyOfLabel(Nordic.ROW2_10, "\u00F6") + .setMoreKeysOf("\u00F6", "\u00F5") + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + .replaceKeyOfLabel(Nordic.ROW2_11, "\u00E4"); + } + + protected void setMoreKeysOfA(final ExpectedKeyboardBuilder builder) { + builder + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK + .setMoreKeysOf("a", "\u0101", "\u00E0", "\u00E1", "\u00E2", "\u00E3", "\u00E5", + "\u00E6", "\u0105"); + } + + protected void setMoreKeysOfI(final ExpectedKeyboardBuilder builder, final int elementId) { + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+0131: "ı" LATIN SMALL LETTER DOTLESS I + if (elementId == KeyboardId.ELEMENT_ALPHABET) { + builder.setMoreKeysOf("i", + "\u012B", "\u00EC", "\u012F", "\u00ED", "\u00EE", "\u00EF", "\u0131"); + } else { + // The upper-case letter of "ı" in Estonian locale is "I". It should be omitted + // from the more keys of "I". + builder.setMoreKeysOf("i", + "\u012B", "\u00EC", "\u012F", "\u00ED", "\u00EE", "\u00EF"); + } + } + + protected void setMoreKeysOfO(final ExpectedKeyboardBuilder builder) { + builder + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + .setMoreKeysOf("o", "\u00F5", "\u00F2", "\u00F3", "\u00F4", "\u0153", "\u0151", + "\u00F8"); + } + + protected void setMoreKeysOfU(final ExpectedKeyboardBuilder builder) { + builder + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE + // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE + .setMoreKeysOf("u", "\u016B", "\u0173", "\u00F9", "\u00FA", "\u00FB", "\u016F", + "\u0171"); + } + + @Override + public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder, + final int elementId) { + setNordicKeys(builder); + setMoreKeysOfA(builder); + setMoreKeysOfI(builder, elementId); + setMoreKeysOfO(builder); + setMoreKeysOfU(builder); + return builder + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+011B: "ě" LATIN SMALL LETTER E WITH CARON + .setMoreKeysOf("e", + "\u0113", "\u00E8", "\u0117", "\u00E9", "\u00EA", "\u00EB", "\u0119", + "\u011B") + // U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA + // U+0159: "ř" LATIN SMALL LETTER R WITH CARON + // U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE + .setMoreKeysOf("r", "\u0157", "\u0159", "\u0155") + // U+0163: "ţ" LATIN SMALL LETTER T WITH CEDILLA + // U+0165: "ť" LATIN SMALL LETTER T WITH CARON + .setMoreKeysOf("t", "\u0163", "\u0165") + // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE + // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS + .setMoreKeysOf("y", "\u00FD", "\u00FF") + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA + .setMoreKeysOf("s", "\u0161", "\u00DF", "\u015B", "\u015F") + // U+010F: "ď" LATIN SMALL LETTER D WITH CARON + .setMoreKeysOf("d", "\u010F") + // U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA + // U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE + .setMoreKeysOf("g", "\u0123", "\u011F") + // U+0137: "ķ" LATIN SMALL LETTER K WITH CEDILLA + .setMoreKeysOf("k", "\u0137") + // U+013C: "ļ" LATIN SMALL LETTER L WITH CEDILLA + // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE + // U+013A: "ĺ" LATIN SMALL LETTER L WITH ACUTE + // U+013E: "ľ" LATIN SMALL LETTER L WITH CARON + .setMoreKeysOf("l", "\u013C", "\u0142", "\u013A", "\u013E") + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE + // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE + .setMoreKeysOf("z", "\u017E", "\u017C", "\u017A") + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + .setMoreKeysOf("c", "\u010D", "\u00E7", "\u0107") + // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + .setMoreKeysOf("n", "\u0146", "\u00F1", "\u0144"); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/EuroCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/EuroCustomizer.java new file mode 100644 index 000000000..ee0236d88 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/EuroCustomizer.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.SymbolsShifted; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; + +import java.util.Locale; + +/** + * The layout customize class for countries that use Euro. + */ +public class EuroCustomizer extends LayoutCustomizer { + public EuroCustomizer(final Locale locale) { + super(locale); + } + + @Override + public final ExpectedKey getCurrencyKey() { return Symbols.CURRENCY_EURO; } + + @Override + public final ExpectedKey[] getOtherCurrencyKeys() { + return SymbolsShifted.CURRENCIES_OTHER_THAN_EURO; + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/FinnishCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/FinnishCustomizer.java new file mode 100644 index 000000000..a792f9143 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/FinnishCustomizer.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.Nordic; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +public class FinnishCustomizer extends EuroCustomizer { + public FinnishCustomizer(final Locale locale) { super(locale); } + + protected void setNordicKeys(final ExpectedKeyboardBuilder builder) { + builder + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + .replaceKeyOfLabel(Nordic.ROW1_11, "\u00E5") + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + .replaceKeyOfLabel(Nordic.ROW2_10, "\u00F6") + .setMoreKeysOf("\u00F6","\u00F8") + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E6: "æ" LATIN SMALL LETTER AE + .replaceKeyOfLabel(Nordic.ROW2_11, "\u00E4") + .setMoreKeysOf("\u00E4", "\u00E6"); + } + + protected void setMoreKeysOfA(final ExpectedKeyboardBuilder builder) { + builder + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + .setMoreKeysOf("a", "\u00E6", "\u00E0", "\u00E1", "\u00E2", "\u00E3", "\u0101"); + } + + protected void setMoreKeysOfO(final ExpectedKeyboardBuilder builder) { + builder + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + .setMoreKeysOf("o", "\u00F8", "\u00F4", "\u00F2", "\u00F3", "\u00F5", "\u0153", + "\u014D"); + } + + @Override + public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { + setNordicKeys(builder); + setMoreKeysOfA(builder); + setMoreKeysOfO(builder); + return builder + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + .setMoreKeysOf("u", "\u00FC") + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + .setMoreKeysOf("s", "\u0161", "\u00DF", "\u015B") + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE + // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE + .setMoreKeysOf("z", "\u017E", "\u017A", "\u017C"); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/FrenchCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/FrenchCustomizer.java index ab90267d0..d7798cc56 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/FrenchCustomizer.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/FrenchCustomizer.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.android.inputmethod.keyboard.layout.tests; +package com.android.inputmethod.keyboard.layout.customizer; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; -class FrenchCustomizer extends LayoutCustomizer { - FrenchCustomizer(final Locale locale) { super(locale); } +public class FrenchCustomizer extends LayoutCustomizer { + public FrenchCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { @@ -86,4 +86,21 @@ class FrenchCustomizer extends LayoutCustomizer { .setMoreKeysOf("c", "\u00E7", "\u0107", "\u010D") .setAdditionalMoreKeysPositionOf("c", 2); } + + public static final class FrenchEuroCustomizer extends FrenchCustomizer { + private final EuroCustomizer mEuroCustomizer; + + public FrenchEuroCustomizer(final Locale locale) { + super(locale); + mEuroCustomizer = new EuroCustomizer(locale); + } + + @Override + public final ExpectedKey getCurrencyKey() { return mEuroCustomizer.getCurrencyKey(); } + + @Override + public final ExpectedKey[] getOtherCurrencyKeys() { + return mEuroCustomizer.getOtherCurrencyKeys(); + } + } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/GermanCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/GermanCustomizer.java index 6d38937aa..e0e4c78b1 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/GermanCustomizer.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/GermanCustomizer.java @@ -14,16 +14,15 @@ * limitations under the License. */ -package com.android.inputmethod.keyboard.layout.tests; +package com.android.inputmethod.keyboard.layout.customizer; import com.android.inputmethod.keyboard.layout.Symbols; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; -class GermanCustomizer extends LayoutCustomizer { +public class GermanCustomizer extends LayoutCustomizer { public GermanCustomizer(final Locale locale) { super(locale); } @Override @@ -86,4 +85,21 @@ class GermanCustomizer extends LayoutCustomizer { // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE .setMoreKeysOf("n", "\u00F1", "\u0144"); } + + public static class GermanEuroCustomizer extends GermanCustomizer { + private final EuroCustomizer mEuroCustomizer; + + public GermanEuroCustomizer(final Locale locale) { + super(locale); + mEuroCustomizer = new EuroCustomizer(locale); + } + + @Override + public ExpectedKey getCurrencyKey() { return mEuroCustomizer.getCurrencyKey(); } + + @Override + public ExpectedKey[] getOtherCurrencyKeys() { + return mEuroCustomizer.getOtherCurrencyKeys(); + } + } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/HindiCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/HindiCustomizer.java new file mode 100644 index 000000000..c7fe9dbd5 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/HindiCustomizer.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.SymbolsShifted; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; + +import java.util.Locale; + +public class HindiCustomizer extends DevanagariCustomizer { + public HindiCustomizer(final Locale locale) { super(locale); } + + @Override + public ExpectedKey getCurrencyKey() { return CURRENCY_RUPEE; } + + @Override + public ExpectedKey[] getOtherCurrencyKeys() { + return SymbolsShifted.CURRENCIES_OTHER_GENERIC; + } + + @Override + public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { + return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS; + } + + @Override + public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) { + // U+0964: "।" DEVANAGARI DANDA + final ExpectedKey periodKey = key("\u0964", getPunctuationMoreKeys(isPhone)); + return joinKeys(periodKey); + } + + @Override + public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) { + return isPhone ? HINDI_PHONE_PUNCTUATION_MORE_KEYS : HINDI_TABLET_PUNCTUATION_MORE_KEYS; + } + + // U+20B9: "₹" INDIAN RUPEE SIGN + private static final ExpectedKey CURRENCY_RUPEE = key("\u20B9", + Symbols.CURRENCY_GENERIC_MORE_KEYS); + + // Punctuation more keys for phone form factor. + private static final ExpectedKey[] HINDI_PHONE_PUNCTUATION_MORE_KEYS = joinKeys( + ",", ".", "?", "!", "#", ")", "(", "/", ";", + "'", "@", ":", "-", "\"", "+", "%", "&"); + // Punctuation more keys for tablet form factor. + private static final ExpectedKey[] HINDI_TABLET_PUNCTUATION_MORE_KEYS = joinKeys( + ",", ".", "'", "#", ")", "(", "/", ";", + "@", ":", "-", "\"", "+", "%", "&"); +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/ItalianCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/ItalianCustomizer.java index 735070946..3b547fdc4 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/ItalianCustomizer.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/ItalianCustomizer.java @@ -14,14 +14,13 @@ * limitations under the License. */ -package com.android.inputmethod.keyboard.layout.tests; +package com.android.inputmethod.keyboard.layout.customizer; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; -class ItalianCustomizer extends LayoutCustomizer { +public class ItalianCustomizer extends LayoutCustomizer { public ItalianCustomizer(final Locale locale) { super(locale); } @Override diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/LayoutCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/LayoutCustomizer.java new file mode 100644 index 000000000..27f55342e --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/LayoutCustomizer.java @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.SymbolsShifted; +import com.android.inputmethod.keyboard.layout.expected.AbstractLayoutBase; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +/** + * This class is used to customize common keyboard layout to language specific layout. + */ +public class LayoutCustomizer extends AbstractLayoutBase { + private final Locale mLocale; + + // Empty keys definition to remove keys by adding this. + protected static final ExpectedKey[] EMPTY_KEYS = joinKeys(); + + public LayoutCustomizer(final Locale locale) { mLocale = locale; } + + public final Locale getLocale() { return mLocale; } + + public int getNumberOfRows() { return 4; } + + /** + * Set accented letters to a specific keyboard element. + * @param builder the {@link ExpectedKeyboardBuilder} object that contains common keyboard + * layout. + * @param elementId the element id of keyboard + * @return the {@link ExpectedKeyboardBuilder} object that contains accented letters as + * "more keys". + */ + public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder, + final int elementId) { + // This method can be overridden by an extended class to provide customized expected + // accented letters depending on the shift state of keyboard. + // This is a default behavior to call a shift-state-independent + // {@link #setAccentedLetters(ExpectedKeyboardBuilder)} implementation, so that + // <code>elementId</code> is ignored here. + return setAccentedLetters(builder); + } + + /** + * Set accented letters to common layout. + * @param builder the {@link ExpectedKeyboardBuilder} object that contains common keyboard + * layout. + * @return the {@link ExpectedKeyboardBuilder} object that contains accented letters as + * "more keys". + */ + public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { + return builder; + } + + /** + * Get the function key to switch to alphabet layout. + * @return the {@link ExpectedKey} of the alphabet key. + */ + public ExpectedKey getAlphabetKey() { return ALPHABET_KEY; } + + /** + * Get the function key to switch to symbols layout. + * @return the {@link ExpectedKey} of the symbols key. + */ + public ExpectedKey getSymbolsKey() { return SYMBOLS_KEY; } + + /** + * Get the function key to switch to symbols shift layout. + * @param isPhone true if requesting phone's key. + * @return the {@link ExpectedKey} of the symbols shift key. + */ + public ExpectedKey getSymbolsShiftKey(boolean isPhone) { + return isPhone ? SYMBOLS_SHIFT_KEY : TABLET_SYMBOLS_SHIFT_KEY; + } + + /** + * Get the function key to switch from symbols shift to symbols layout. + * @return the {@link ExpectedKey} of the back to symbols key. + */ + public ExpectedKey getBackToSymbolsKey() { return BACK_TO_SYMBOLS_KEY; } + + /** + * Get the currency key. + * @return the {@link ExpectedKey} of the currency key. + */ + public ExpectedKey getCurrencyKey() { return Symbols.CURRENCY_DOLLAR; } + + /** + * Get other currencies keys. + * @return the array of {@link ExpectedKey} that represents other currency keys. + */ + public ExpectedKey[] getOtherCurrencyKeys() { + return SymbolsShifted.CURRENCIES_OTHER_THAN_DOLLAR; + } + + /** + * Get "more keys" of double quotation mark. + * @return the array of {@link ExpectedKey} of more double quotation marks in natural order. + */ + public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_9LR; } + + /** + * Get "more keys" of single quotation mark. + * @return the array of {@link ExpectedKey} of more single quotation marks in natural order. + */ + public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_9LR; } + + /** + * Get double angle quotation marks in natural order. + * @return the array of {@link ExpectedKey} of double angle quotation marks in natural + * order. + */ + public ExpectedKey[] getDoubleAngleQuoteKeys() { return Symbols.DOUBLE_ANGLE_QUOTES_LR; } + + /** + * Get single angle quotation marks in natural order. + * @return the array of {@link ExpectedKey} of single angle quotation marks in natural + * order. + */ + public ExpectedKey[] getSingleAngleQuoteKeys() { return Symbols.SINGLE_ANGLE_QUOTES_LR; } + + /** + * Get the left shift keys. + * @param isPhone true if requesting phone's keys. + * @return the array of {@link ExpectedKey} that should be placed at left edge of the + * keyboard. + */ + public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) { + return joinKeys(SHIFT_KEY); + } + + /** + * Get the right shift keys. + * @param isPhone true if requesting phone's keys. + * @return the array of {@link ExpectedKey} that should be placed at right edge of the + * keyboard. + */ + public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { + return isPhone ? EMPTY_KEYS : joinKeys(EXCLAMATION_AND_QUESTION_MARKS, SHIFT_KEY); + } + + /** + * Get the enter key. + * @param isPhone true if requesting phone's key. + * @return the array of {@link ExpectedKey} that should be placed as an enter key. + */ + public ExpectedKey getEnterKey(final boolean isPhone) { + return isPhone ? key(ENTER_KEY, EMOJI_ACTION_KEY) : ENTER_KEY; + } + + /** + * Get the emoji key. + * @param isPhone true if requesting phone's key. + * @return the array of {@link ExpectedKey} that should be placed as an emoji key. + */ + public ExpectedKey getEmojiKey(final boolean isPhone) { + return EMOJI_NORMAL_KEY; + } + + /** + * Get the space keys. + * @param isPhone true if requesting phone's keys. + * @return the array of {@link ExpectedKey} that should be placed at the center of the + * keyboard. + */ + public ExpectedKey[] getSpaceKeys(final boolean isPhone) { + return joinKeys(LANGUAGE_SWITCH_KEY, SPACE_KEY); + } + + /** + * Get the keys left to the spacebar. + * @param isPhone true if requesting phone's keys. + * @return the array of {@link ExpectedKey} that should be placed at left of the spacebar. + */ + public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) { + // U+002C: "," COMMA + return joinKeys(key("\u002C", SETTINGS_KEY)); + } + + /** + * Get the keys right to the spacebar. + * @param isPhone true if requesting phone's keys. + * @return the array of {@link ExpectedKey} that should be placed at right of the spacebar. + */ + public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) { + final ExpectedKey periodKey = key(".", getPunctuationMoreKeys(isPhone)); + return joinKeys(periodKey); + } + + /** + * Get "more keys" for the punctuation key (usually the period key). + * @param isPhone true if requesting phone's keys. + * @return the array of {@link ExpectedKey} that are "more keys" of the punctuation key. + */ + public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) { + return isPhone ? PHONE_PUNCTUATION_MORE_KEYS : TABLET_PUNCTUATION_MORE_KEYS; + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/NepaliCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/NepaliCustomizer.java new file mode 100644 index 000000000..264322f54 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/NepaliCustomizer.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.SymbolsShifted; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; + +import java.util.Locale; + +public class NepaliCustomizer extends DevanagariCustomizer { + public NepaliCustomizer(final Locale locale) { super(locale); } + + @Override + public ExpectedKey getCurrencyKey() { return CURRENCY_NEPALI; } + + @Override + public ExpectedKey[] getOtherCurrencyKeys() { + return SymbolsShifted.CURRENCIES_OTHER_GENERIC; + } + + @Override + public ExpectedKey[] getSpaceKeys(final boolean isPhone) { + return joinKeys(LANGUAGE_SWITCH_KEY, SPACE_KEY, key(ZWNJ_KEY, ZWJ_KEY)); + } + + @Override + public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) { + // U+0964: "।" DEVANAGARI DANDA + final ExpectedKey periodKey = key("\u0964", getPunctuationMoreKeys(isPhone)); + return joinKeys(periodKey); + } + + @Override + public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) { + return isPhone ? NEPALI_PHONE_PUNCTUATION_MORE_KEYS + : NEPALI_TABLET_PUNCTUATION_MORE_KEYS; + } + + // U+0930/U+0941/U+002E "रु." NEPALESE RUPEE SIGN + private static final ExpectedKey CURRENCY_NEPALI = key("\u0930\u0941\u002E", + Symbols.DOLLAR_SIGN, Symbols.CENT_SIGN, Symbols.EURO_SIGN, Symbols.POUND_SIGN, + Symbols.YEN_SIGN, Symbols.PESO_SIGN); + + // Punctuation more keys for phone form factor. + private static final ExpectedKey[] NEPALI_PHONE_PUNCTUATION_MORE_KEYS = joinKeys( + ".", ",", "?", "!", "#", ")", "(", "/", ";", + "'", "@", ":", "-", "\"", "+", "%", "&"); + // Punctuation more keys for tablet form factor. + private static final ExpectedKey[] NEPALI_TABLET_PUNCTUATION_MORE_KEYS = joinKeys( + ".", ",", "'", "#", ")", "(", "/", ";", + "@", ":", "-", "\"", "+", "%", "&"); +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/NoLanguageCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/NoLanguageCustomizer.java index 9edbcab69..b6bf5bfeb 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/NoLanguageCustomizer.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/NoLanguageCustomizer.java @@ -14,15 +14,14 @@ * limitations under the License. */ -package com.android.inputmethod.keyboard.layout.tests; +package com.android.inputmethod.keyboard.layout.customizer; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; -class NoLanguageCustomizer extends LayoutCustomizer { - NoLanguageCustomizer(final Locale locale) { super(locale); } +public class NoLanguageCustomizer extends LayoutCustomizer { + public NoLanguageCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/NorwegianCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/NorwegianCustomizer.java new file mode 100644 index 000000000..6cc44e578 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/NorwegianCustomizer.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.Nordic; +import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +public class NorwegianCustomizer extends LayoutCustomizer { + public NorwegianCustomizer(final Locale locale) { super(locale); } + + @Override + public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_L9R; } + + @Override + public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_L9R; } + + protected void setNordicKeys(final ExpectedKeyboardBuilder builder) { + builder + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + .replaceKeyOfLabel(Nordic.ROW1_11, "\u00E5") + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + .replaceKeyOfLabel(Nordic.ROW2_10, "\u00F8") + .setMoreKeysOf("\u00F8", "\u00F6") + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + .replaceKeyOfLabel(Nordic.ROW2_11, "\u00E6") + .setMoreKeysOf("\u00E6", "\u00E4"); + } + + protected void setMoreKeysOfA(final ExpectedKeyboardBuilder builder) { + builder + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + .setMoreKeysOf("a", "\u00E4", "\u00E0", "\u00E1", "\u00E2", "\u00E3", "\u0101"); + } + + protected void setMoreKeysOfO(final ExpectedKeyboardBuilder builder) { + builder + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + .setMoreKeysOf("o", "\u00F6", "\u00F4", "\u00F2", "\u00F3", "\u00F5", "\u0153", + "\u014D"); + } + + @Override + public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { + setNordicKeys(builder); + setMoreKeysOfA(builder); + setMoreKeysOfO(builder); + return builder + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE + // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON + .setMoreKeysOf("e", + "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0119", "\u0117", "\u0113") + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + .setMoreKeysOf("u", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B"); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/PcQwertyCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/PcQwertyCustomizer.java new file mode 100644 index 000000000..9a0f764ae --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/PcQwertyCustomizer.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; + +import java.util.Locale; + +public class PcQwertyCustomizer extends LayoutCustomizer { + public PcQwertyCustomizer(final Locale locale) { super(locale); } + + @Override + public int getNumberOfRows() { return 5; } + + @Override + public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) { + return joinKeys(SHIFT_KEY); + } + + @Override + public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { + return joinKeys(SHIFT_KEY); + } + + @Override + public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) { + return joinKeys(SETTINGS_KEY); + } + + @Override + public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) { + return isPhone + ? joinKeys(key(ENTER_KEY, EMOJI_ACTION_KEY)) + : joinKeys(EMOJI_NORMAL_KEY); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/PortugueseCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/PortugueseCustomizer.java index 629e8cb8b..4fc64cc62 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/PortugueseCustomizer.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/PortugueseCustomizer.java @@ -14,15 +14,14 @@ * limitations under the License. */ -package com.android.inputmethod.keyboard.layout.tests; +package com.android.inputmethod.keyboard.layout.customizer; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; -class PortugueseCustomizer extends LayoutCustomizer { - PortugueseCustomizer(final Locale locale) { super(locale); } +public class PortugueseCustomizer extends LayoutCustomizer { + public PortugueseCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/SerbianLatinCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/SerbianLatinCustomizer.java new file mode 100644 index 000000000..4d03c8ba6 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/SerbianLatinCustomizer.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.SerbianQwertz; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +public class SerbianLatinCustomizer extends LayoutCustomizer { + public SerbianLatinCustomizer(final Locale locale) { super(locale); } + + @Override + public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { + return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS; + } + + protected void setSerbianKeys(final ExpectedKeyboardBuilder builder) { + builder + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + .replaceKeyOfLabel(SerbianQwertz.ROW1_11, "\u0161") + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + .replaceKeyOfLabel(SerbianQwertz.ROW2_10, "\u010D") + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + .replaceKeyOfLabel(SerbianQwertz.ROW2_11, "\u0107") + // U+0111: "đ" LATIN SMALL LETTER D WITH STROKE + .replaceKeyOfLabel(SerbianQwertz.ROW3_8, "\u0111") + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + .replaceKeyOfLabel(SerbianQwertz.ROW3_9, "\u017E"); + } + + @SuppressWarnings("unused") + protected void setMoreKeysOfS(final ExpectedKeyboardBuilder builder) { + // Serbian QWERTZ has a dedicated "š" key. + } + + @SuppressWarnings("unused") + protected void setMoreKeysOfC(final ExpectedKeyboardBuilder builder) { + // Serbian QWERTZ has a dedicated "č" and "ć" keys. + } + + @SuppressWarnings("unused") + protected void setMoreKeysOfD(final ExpectedKeyboardBuilder builder) { + // Serbian QWERTZ has a dedicated "đ" key. + } + + @SuppressWarnings("unused") + protected void setMoreKeysOfZ(final ExpectedKeyboardBuilder builder) { + // Serbian QWERTZ has a dedicated "ž" key. + } + + @Override + public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { + setSerbianKeys(builder); + setMoreKeysOfS(builder); + setMoreKeysOfC(builder); + setMoreKeysOfD(builder); + setMoreKeysOfZ(builder); + return builder + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + .setMoreKeysOf("e", "\u00E8") + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + .setMoreKeysOf("i", "\u00EC"); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/SouthSlavicLayoutCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/SouthSlavicLayoutCustomizer.java new file mode 100644 index 000000000..bec816000 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/SouthSlavicLayoutCustomizer.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.latin.common.Constants; + +import java.util.Locale; + +public class SouthSlavicLayoutCustomizer extends LayoutCustomizer { + public SouthSlavicLayoutCustomizer(final Locale locale) { + super(locale); + } + + @Override + public final ExpectedKey getAlphabetKey() { return SOUTH_SLAVIC_ALPHABET_KEY; } + + @Override + public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { + return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS; + } + + // U+0410: "А" CYRILLIC CAPITAL LETTER A + // U+0411: "Б" CYRILLIC CAPITAL LETTER BE + // U+0412: "В" CYRILLIC CAPITAL LETTER VE + private static final ExpectedKey SOUTH_SLAVIC_ALPHABET_KEY = key( + "\u0410\u0411\u0412", Constants.CODE_SWITCH_ALPHA_SYMBOL); +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/SpanishCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/SpanishCustomizer.java index 8974ad6ec..1284f054e 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/SpanishCustomizer.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/SpanishCustomizer.java @@ -14,28 +14,24 @@ * limitations under the License. */ -package com.android.inputmethod.keyboard.layout.tests; +package com.android.inputmethod.keyboard.layout.customizer; -import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Spanish; -import com.android.inputmethod.keyboard.layout.expected.AbstractLayoutBase; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; -class SpanishCustomizer extends LayoutCustomizer { - SpanishCustomizer(final Locale locale) { super(locale); } +public class SpanishCustomizer extends LayoutCustomizer { + public SpanishCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) { - return isPhone ? PHONE_PUNCTUATION_MORE_KEYS - : LayoutBase.TABLET_PUNCTUATION_MORE_KEYS; + return isPhone ? SPANISH_PHONE_PUNCTUATION_MORE_KEYS : TABLET_PUNCTUATION_MORE_KEYS; } // Punctuation more keys for phone form factor. - private static final ExpectedKey[] PHONE_PUNCTUATION_MORE_KEYS = AbstractLayoutBase.joinKeys( + private static final ExpectedKey[] SPANISH_PHONE_PUNCTUATION_MORE_KEYS = joinKeys( // U+00A1: "¡" INVERTED EXCLAMATION MARK // U+00BF: "¿" INVERTED QUESTION MARK ",", "?", "!", "#", ")", "(", "/", ";", "\u00A1", diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/SwedishCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/SwedishCustomizer.java new file mode 100644 index 000000000..f4ff59458 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/SwedishCustomizer.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.Nordic; +import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +public class SwedishCustomizer extends LayoutCustomizer { + private final LayoutCustomizer mEuroCustomizer; + + public SwedishCustomizer(final Locale locale) { + super(locale); + mEuroCustomizer = new EuroCustomizer(locale); + } + + @Override + public ExpectedKey getCurrencyKey() { + return mEuroCustomizer.getCurrencyKey(); + } + + @Override + public ExpectedKey[] getOtherCurrencyKeys() { + return mEuroCustomizer.getOtherCurrencyKeys(); + } + + @Override + public ExpectedKey[] getDoubleAngleQuoteKeys() { return Symbols.DOUBLE_ANGLE_QUOTES_RL; } + + @Override + public ExpectedKey[] getSingleAngleQuoteKeys() { return Symbols.SINGLE_ANGLE_QUOTES_RL; } + + protected void setNordicKeys(final ExpectedKeyboardBuilder builder) { + builder + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + .replaceKeyOfLabel(Nordic.ROW1_11, "\u00E5") + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+0153: "œ" LATIN SMALL LIGATURE OE + .replaceKeyOfLabel(Nordic.ROW2_10, "\u00F6") + .setMoreKeysOf("\u00F6", "\u00F8", "\u0153") + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E6: "æ" LATIN SMALL LETTER AE + .replaceKeyOfLabel(Nordic.ROW2_11, "\u00E4") + .setMoreKeysOf("\u00E4", "\u00E6"); + } + + protected void setMoreKeysOfA(final ExpectedKeyboardBuilder builder) { + builder + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + .setMoreKeysOf("a", "\u00E6", "\u00E1", "\u00E0", "\u00E2", "\u0105", "\u00E3"); + } + + protected void setMoreKeysOfO(final ExpectedKeyboardBuilder builder) { + builder + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + .setMoreKeysOf("o", "\u00F8", "\u0153", "\u00F3", "\u00F2", "\u00F4", "\u00F5", + "\u014D"); + } + + @Override + public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { + setNordicKeys(builder); + setMoreKeysOfA(builder); + setMoreKeysOfO(builder); + return builder + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX + // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS + // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK + .setMoreKeysOf("e", "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0119") + // U+0159: "ř" LATIN SMALL LETTER R WITH CARON + .setMoreKeysOf("r", "\u0159") + // U+0165: "ť" LATIN SMALL LETTER T WITH CARON + // U+00FE: "þ" LATIN SMALL LETTER THORN + .setMoreKeysOf("t", "\u0165", "\u00FE") + // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE + // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS + .setMoreKeysOf("y", "\u00FD", "\u00FF") + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + .setMoreKeysOf("u", "\u00FC", "\u00FA", "\u00F9", "\u00FB", "\u016B") + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + .setMoreKeysOf("i", "\u00ED", "\u00EC", "\u00EE", "\u00EF") + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + .setMoreKeysOf("s", "\u015B", "\u0161", "\u015F", "\u00DF") + // U+00F0: "ð" LATIN SMALL LETTER ETH + // U+010F: "ď" LATIN SMALL LETTER D WITH CARON + .setMoreKeysOf("d", "\u00F0", "\u010F") + // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE + .setMoreKeysOf("l", "\u0142") + // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE + .setMoreKeysOf("z", "\u017A", "\u017E", "\u017C") + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + .setMoreKeysOf("c", "\u00E7", "\u0107", "\u010D") + // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+0148: "ň" LATIN SMALL LETTER N WITH CARON + .setMoreKeysOf("n", "\u0144", "\u00F1", "\u0148"); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/TamilCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/TamilCustomizer.java new file mode 100644 index 000000000..de82aaf9e --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/TamilCustomizer.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.latin.common.Constants; + +import java.util.Locale; + +public class TamilCustomizer extends LayoutCustomizer { + public TamilCustomizer(final Locale locale) { super(locale); } + + @Override + public ExpectedKey getAlphabetKey() { return TAMIL_ALPHABET_KEY; } + + @Override + public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) { + return EMPTY_KEYS; + } + + @Override + public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { + return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS; + } + + // U+0BA4: "த" TAMIL LETTER TA + // U+0BAE/U+0BBF: "மி" TAMIL LETTER MA/TAMIL VOWEL SIGN I + // U+0BB4/U+0BCD: "ழ்" TAMIL LETTER LLLA/TAMIL SIGN VIRAMA + private static final ExpectedKey TAMIL_ALPHABET_KEY = key( + "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD", Constants.CODE_SWITCH_ALPHA_SYMBOL); +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/TurkicCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/TurkicCustomizer.java new file mode 100644 index 000000000..3fd3aa219 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/TurkicCustomizer.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +/** + * Turkic languages layout customizer. + */ +public class TurkicCustomizer extends LayoutCustomizer { + public TurkicCustomizer(final Locale locale) { super(locale); } + + @Override + public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { + return builder + // U+0259: "ə" LATIN SMALL LETTER SCHWA + // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE + .setMoreKeysOf("e", "\u0259", "\u00E9") + // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE + .setMoreKeysOf("y", "\u00FD") + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + .setMoreKeysOf("u", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B") + // U+0131: "ı" LATIN SMALL LETTER DOTLESS I + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + .setMoreKeysOf("i", + "\u0131", "\u00EE", "\u00EF", "\u00EC", "\u00ED", "\u012F", "\u012B") + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + .setMoreKeysOf("o", + "\u00F6", "\u00F4", "\u0153", "\u00F2", "\u00F3", "\u00F5", "\u00F8", + "\u014D") + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + .setMoreKeysOf("a", "\u00E2", "\u00E4", "\u00E1") + // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + .setMoreKeysOf("s", "\u015F", "\u00DF", "\u015B", "\u0161") + // U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE + .setMoreKeysOf("g", "\u011F") + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + .setMoreKeysOf("z", "\u017E") + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + .setMoreKeysOf("c", "\u00E7", "\u0107", "\u010D") + // U+0148: "ň" LATIN SMALL LETTER N WITH CARON + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + .setMoreKeysOf("n", "\u0148", "\u00F1"); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/customizer/UzbekCustomizer.java b/tests/src/com/android/inputmethod/keyboard/layout/customizer/UzbekCustomizer.java new file mode 100644 index 000000000..99486163e --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/customizer/UzbekCustomizer.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.customizer; + +import com.android.inputmethod.keyboard.layout.Nordic; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +public class UzbekCustomizer extends TurkicCustomizer { + public UzbekCustomizer(final Locale locale) { super(locale); } + + protected void setUzbekKeys(final ExpectedKeyboardBuilder builder) { + builder + // U+006F/U+02BB: "oʻ" LATIN SMALL LETTER O/MODIFIER LETTER TURNED COMMA + .replaceKeyOfLabel(Nordic.ROW1_11, "o\u02BB") + // U+0067/U+02BB: "gʻ" LATIN SMALL LETTER G/MODIFIER LETTER TURNED COMMA + .replaceKeyOfLabel(Nordic.ROW2_10, "g\u02BB") + // U+02BC: "ʼ" MODIFIER LETTER APOSTROPHE + .replaceKeyOfLabel(Nordic.ROW2_11, "\u02BC"); + } + + @Override + public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { + setUzbekKeys(builder); + return super.setAccentedLetters(builder); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/AbstractLayoutBase.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/AbstractLayoutBase.java index 3556cb4bf..2232548eb 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/expected/AbstractLayoutBase.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/AbstractLayoutBase.java @@ -16,7 +16,9 @@ package com.android.inputmethod.keyboard.layout.expected; +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey.ExpectedAdditionalMoreKey; +import com.android.inputmethod.latin.common.Constants; /** * Base class to create an expected keyboard for unit test. @@ -102,4 +104,75 @@ public abstract class AbstractLayoutBase { public static ExpectedKey[] joinKeys(final Object ... keys) { return ExpectedKeyboardBuilder.joinKeys(keys); } + + // Icon ids. + private static final int ICON_DELETE = KeyboardIconsSet.getIconId( + KeyboardIconsSet.NAME_DELETE_KEY); + private static final int ICON_SPACE = KeyboardIconsSet.getIconId( + KeyboardIconsSet.NAME_SPACE_KEY); + private static final int ICON_TAB = KeyboardIconsSet.getIconId( + KeyboardIconsSet.NAME_TAB_KEY); + private static final int ICON_SHORTCUT = KeyboardIconsSet.getIconId( + KeyboardIconsSet.NAME_SHORTCUT_KEY); + private static final int ICON_SETTINGS = KeyboardIconsSet.getIconId( + KeyboardIconsSet.NAME_SETTINGS_KEY); + private static final int ICON_LANGUAGE_SWITCH = KeyboardIconsSet.getIconId( + KeyboardIconsSet.NAME_LANGUAGE_SWITCH_KEY); + private static final int ICON_ENTER = KeyboardIconsSet.getIconId( + KeyboardIconsSet.NAME_ENTER_KEY); + private static final int ICON_EMOJI_ACTION = KeyboardIconsSet.getIconId( + KeyboardIconsSet.NAME_EMOJI_ACTION_KEY); + private static final int ICON_EMOJI_NORMAL = KeyboardIconsSet.getIconId( + KeyboardIconsSet.NAME_EMOJI_NORMAL_KEY); + private static final int ICON_SHIFT = KeyboardIconsSet.getIconId( + KeyboardIconsSet.NAME_SHIFT_KEY); + private static final int ICON_SHIFTED_SHIFT = KeyboardIconsSet.getIconId( + KeyboardIconsSet.NAME_SHIFT_KEY_SHIFTED); + private static final int ICON_ZWNJ = KeyboardIconsSet.getIconId( + KeyboardIconsSet.NAME_ZWNJ_KEY); + private static final int ICON_ZWJ = KeyboardIconsSet.getIconId( + KeyboardIconsSet.NAME_ZWJ_KEY); + + // Functional keys. + protected static final ExpectedKey DELETE_KEY = key(ICON_DELETE, Constants.CODE_DELETE); + protected static final ExpectedKey TAB_KEY = key(ICON_TAB, Constants.CODE_TAB); + protected static final ExpectedKey SHORTCUT_KEY = key(ICON_SHORTCUT, Constants.CODE_SHORTCUT); + protected static final ExpectedKey SETTINGS_KEY = key(ICON_SETTINGS, Constants.CODE_SETTINGS); + protected static final ExpectedKey LANGUAGE_SWITCH_KEY = key( + ICON_LANGUAGE_SWITCH, Constants.CODE_LANGUAGE_SWITCH); + protected static final ExpectedKey ENTER_KEY = key(ICON_ENTER, Constants.CODE_ENTER); + protected static final ExpectedKey EMOJI_ACTION_KEY = key(ICON_EMOJI_ACTION, Constants.CODE_EMOJI); + protected static final ExpectedKey EMOJI_NORMAL_KEY = key(ICON_EMOJI_NORMAL, Constants.CODE_EMOJI); + protected static final ExpectedKey SPACE_KEY = key(ICON_SPACE, Constants.CODE_SPACE); + protected static final ExpectedKey CAPSLOCK_MORE_KEY = key(" ", Constants.CODE_CAPSLOCK); + protected static final ExpectedKey SHIFT_KEY = key(ICON_SHIFT, + Constants.CODE_SHIFT, CAPSLOCK_MORE_KEY); + protected static final ExpectedKey SHIFTED_SHIFT_KEY = key(ICON_SHIFTED_SHIFT, + Constants.CODE_SHIFT, CAPSLOCK_MORE_KEY); + protected static final ExpectedKey ALPHABET_KEY = key("ABC", Constants.CODE_SWITCH_ALPHA_SYMBOL); + protected static final ExpectedKey SYMBOLS_KEY = key("?123", Constants.CODE_SWITCH_ALPHA_SYMBOL); + protected static final ExpectedKey BACK_TO_SYMBOLS_KEY = key("?123", Constants.CODE_SHIFT); + protected static final ExpectedKey SYMBOLS_SHIFT_KEY = key("= \\ <", Constants.CODE_SHIFT); + protected static final ExpectedKey TABLET_SYMBOLS_SHIFT_KEY = key("~ [ <", Constants.CODE_SHIFT); + + // U+00A1: "¡" INVERTED EXCLAMATION MARK + // U+00BF: "¿" INVERTED QUESTION MARK + protected static final ExpectedKey[] EXCLAMATION_AND_QUESTION_MARKS = joinKeys( + key("!", moreKey("\u00A1")), key("?", moreKey("\u00BF"))); + // U+200C: ZERO WIDTH NON-JOINER + // U+200D: ZERO WIDTH JOINER + protected static final ExpectedKey ZWNJ_KEY = key(ICON_ZWNJ, "\u200C"); + protected static final ExpectedKey ZWJ_KEY = key(ICON_ZWJ, "\u200D"); + // Domain key + protected static final ExpectedKey DOMAIN_KEY = + key(".com", joinMoreKeys(".net", ".org", ".gov", ".edu")).preserveCase(); + + // Punctuation more keys for phone form factor. + protected static final ExpectedKey[] PHONE_PUNCTUATION_MORE_KEYS = joinKeys( + ",", "?", "!", "#", ")", "(", "/", ";", + "'", "@", ":", "-", "\"", "+", "%", "&"); + // Punctuation more keys for tablet form factor. + protected static final ExpectedKey[] TABLET_PUNCTUATION_MORE_KEYS = joinKeys( + ",", "'", "#", ")", "(", "/", ";", + "@", ":", "-", "\"", "+", "%", "&"); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java index 56149189f..2a040f564 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/ActualKeyboardBuilder.java @@ -19,12 +19,15 @@ package com.android.inputmethod.keyboard.layout.expected; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; import com.android.inputmethod.keyboard.internal.MoreKeySpec; -import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.utils.StringUtils; +import com.android.inputmethod.latin.common.Constants; +import com.android.inputmethod.latin.common.StringUtils; import java.util.ArrayList; import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + /** * This class builds an actual keyboard for unit test. * @@ -98,9 +101,13 @@ public final class ActualKeyboardBuilder extends AbstractKeyboardBuilder<Key> { @Override public String stringize(final MoreKeySpec spec) { + if (spec == null) { + return "null"; + } return toString(spec.mLabel, spec.mIconId, spec.mOutputText, spec.mCode); } + @Nonnull static String toString(final String label, final int iconId, final String outputText, final int code) { final String visual = (iconId != KeyboardIconsSet.ICON_UNDEFINED) @@ -125,7 +132,7 @@ public final class ActualKeyboardBuilder extends AbstractKeyboardBuilder<Key> { static final KeyStringizer STRINGIZER = new KeyStringizer(); @Override - public String stringize(final Key key) { + public String stringize(@Nullable final Key key) { if (key == null) { return "NULL"; } @@ -150,7 +157,8 @@ public final class ActualKeyboardBuilder extends AbstractKeyboardBuilder<Key> { * @param key the key to be converted to string. * @return the human readable representation of <code>key</code>. */ - public static String toString(final Key key) { + @Nonnull + public static String toString(@Nullable final Key key) { return KeyStringizer.STRINGIZER.stringize(key); } @@ -159,7 +167,8 @@ public final class ActualKeyboardBuilder extends AbstractKeyboardBuilder<Key> { * @param keys the keyboard row to be converted to string. * @return the human readable representation of <code>keys</code>. */ - public static String toString(final Key[] keys) { + @Nonnull + public static String toString(@Nullable final Key[] keys) { return KeyStringizer.STRINGIZER.join(keys); } @@ -168,7 +177,7 @@ public final class ActualKeyboardBuilder extends AbstractKeyboardBuilder<Key> { static final KeyArrayStringizer STRINGIZER = new KeyArrayStringizer(); @Override - public String stringize(final Key[] keyArray) { + public String stringize(@Nullable final Key[] keyArray) { return KeyStringizer.STRINGIZER.join(keyArray); } } @@ -178,7 +187,8 @@ public final class ActualKeyboardBuilder extends AbstractKeyboardBuilder<Key> { * @param rows the keyboard to be converted to string. * @return the human readable representation of <code>rows</code>. */ - public static String toString(final Key[][] rows) { + @Nonnull + public static String toString(@Nullable final Key[][] rows) { return KeyArrayStringizer.STRINGIZER.join(rows, "\n" /* delimiter */); } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKey.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKey.java index 2674a6a69..5c147a3b6 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKey.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKey.java @@ -105,11 +105,11 @@ public class ExpectedKey { // The expected output of this key. private final ExpectedKeyOutput mOutput; - public final ExpectedKeyVisual getVisual() { + protected final ExpectedKeyVisual getVisual() { return mVisual; } - public final ExpectedKeyOutput getOutput() { + protected final ExpectedKeyOutput getOutput() { return mOutput; } @@ -162,18 +162,19 @@ public class ExpectedKey { public boolean equalsTo(final Key key) { // This key has no "more keys". - return mVisual.equalsTo(key) && mOutput.equalsTo(key) && key.getMoreKeys() == null; + return mVisual.hasSameKeyVisual(key) && mOutput.hasSameKeyOutput(key) + && key.getMoreKeys() == null; } public boolean equalsTo(final MoreKeySpec moreKeySpec) { - return mVisual.equalsTo(moreKeySpec) && mOutput.equalsTo(moreKeySpec); + return mVisual.hasSameKeyVisual(moreKeySpec) && mOutput.hasSameKeyOutput(moreKeySpec); } @Override public boolean equals(final Object object) { if (object instanceof ExpectedKey) { final ExpectedKey key = (ExpectedKey) object; - return mVisual.equalsTo(key.mVisual) && mOutput.equalsTo(key.mOutput) + return mVisual.hasSameKeyVisual(key.mVisual) && mOutput.hasSameKeyOutput(key.mOutput) && Arrays.equals(getMoreKeys(), key.getMoreKeys()); } return false; @@ -190,7 +191,7 @@ public class ExpectedKey { @Override public String toString() { - if (mVisual.equalsTo(mOutput)) { + if (mVisual.hasSameKeyVisual(mOutput)) { return mVisual.toString(); } return mVisual + "|" + mOutput; @@ -274,7 +275,7 @@ public class ExpectedKey { @Override public boolean equalsTo(final Key key) { - if (getVisual().equalsTo(key) && getOutput().equalsTo(key)) { + if (getVisual().hasSameKeyVisual(key) && getOutput().hasSameKeyOutput(key)) { final MoreKeySpec[] moreKeySpecs = key.getMoreKeys(); final ExpectedKey[] moreKeys = getMoreKeys(); // This key should have at least one "more key". diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyOutput.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyOutput.java index 8b2bb4289..e7b0f091d 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyOutput.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyOutput.java @@ -18,8 +18,8 @@ package com.android.inputmethod.keyboard.layout.expected; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.internal.MoreKeySpec; -import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.utils.StringUtils; +import com.android.inputmethod.latin.common.Constants; +import com.android.inputmethod.latin.common.StringUtils; import java.util.Locale; @@ -43,10 +43,10 @@ abstract class ExpectedKeyOutput { abstract ExpectedKeyOutput toUpperCase(final Locale locale); abstract ExpectedKeyOutput preserveCase(); - abstract boolean equalsTo(final String text); - abstract boolean equalsTo(final Key key); - abstract boolean equalsTo(final MoreKeySpec moreKeySpec); - abstract boolean equalsTo(final ExpectedKeyOutput output); + abstract boolean hasSameKeyOutput(final String text); + abstract boolean hasSameKeyOutput(final Key key); + abstract boolean hasSameKeyOutput(final MoreKeySpec moreKeySpec); + abstract boolean hasSameKeyOutput(final ExpectedKeyOutput output); /** * This class represents an integer code point. @@ -63,8 +63,7 @@ abstract class ExpectedKeyOutput { final String codeString = StringUtils.newSingleCodePointString(mCode); // A letter may have an upper case counterpart that consists of multiple code // points, for instance the upper case of "ß" is "SS". - return newInstance(StringUtils.toUpperCaseOfStringForLocale( - codeString, true /* needsToUpperCase */, locale)); + return newInstance(StringUtils.toTitleCaseOfKeyLabel(codeString, locale)); } // A special negative value has no upper case. return this; @@ -76,22 +75,22 @@ abstract class ExpectedKeyOutput { } @Override - boolean equalsTo(final String text) { + boolean hasSameKeyOutput(final String text) { return StringUtils.codePointCount(text) == 1 && text.codePointAt(0) == mCode; } @Override - boolean equalsTo(final Key key) { + boolean hasSameKeyOutput(final Key key) { return mCode == key.getCode(); } @Override - boolean equalsTo(final MoreKeySpec moreKeySpec) { + boolean hasSameKeyOutput(final MoreKeySpec moreKeySpec) { return mCode == moreKeySpec.mCode; } @Override - boolean equalsTo(final ExpectedKeyOutput output) { + boolean hasSameKeyOutput(final ExpectedKeyOutput output) { return (output instanceof Code) && mCode == ((Code)output).mCode; } @@ -131,24 +130,24 @@ abstract class ExpectedKeyOutput { } @Override - boolean equalsTo(final String text) { + boolean hasSameKeyOutput(final String text) { return text.equals(text); } @Override - boolean equalsTo(final Key key) { + boolean hasSameKeyOutput(final Key key) { return key.getCode() == Constants.CODE_OUTPUT_TEXT && mText.equals(key.getOutputText()); } @Override - boolean equalsTo(final MoreKeySpec moreKeySpec) { + boolean hasSameKeyOutput(final MoreKeySpec moreKeySpec) { return moreKeySpec.mCode == Constants.CODE_OUTPUT_TEXT && mText.equals(moreKeySpec.mOutputText); } @Override - boolean equalsTo(final ExpectedKeyOutput output) { + boolean hasSameKeyOutput(final ExpectedKeyOutput output) { return (output instanceof Text) && mText == ((Text)output).mText; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyVisual.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyVisual.java index 34024a5e0..3f9f12a2b 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyVisual.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyVisual.java @@ -19,7 +19,7 @@ package com.android.inputmethod.keyboard.layout.expected; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; import com.android.inputmethod.keyboard.internal.MoreKeySpec; -import com.android.inputmethod.latin.utils.StringUtils; +import com.android.inputmethod.latin.common.StringUtils; import java.util.Locale; @@ -28,22 +28,24 @@ import java.util.Locale; * * There are two types of expected visual, an integer icon id and a string label. */ -abstract class ExpectedKeyVisual { - static ExpectedKeyVisual newInstance(final String label) { +public abstract class ExpectedKeyVisual { + public static ExpectedKeyVisual newInstance(final String label) { return new Label(label); } - static ExpectedKeyVisual newInstance(final int iconId) { + public static ExpectedKeyVisual newInstance(final int iconId) { return new Icon(iconId); } + public abstract int getIconId(); + public abstract String getLabel(); abstract ExpectedKeyVisual toUpperCase(final Locale locale); abstract ExpectedKeyVisual preserveCase(); - abstract boolean equalsTo(final String text); - abstract boolean equalsTo(final Key key); - abstract boolean equalsTo(final MoreKeySpec moreKeySpec); - abstract boolean equalsTo(final ExpectedKeyOutput output); - abstract boolean equalsTo(final ExpectedKeyVisual visual); + abstract boolean hasSameKeyVisual(final String text); + abstract boolean hasSameKeyVisual(final Key key); + abstract boolean hasSameKeyVisual(final MoreKeySpec moreKeySpec); + abstract boolean hasSameKeyVisual(final ExpectedKeyOutput output); + abstract boolean hasSameKeyVisual(final ExpectedKeyVisual visual); /** * This class represents an integer icon id. @@ -56,6 +58,16 @@ abstract class ExpectedKeyVisual { } @Override + public int getIconId() { + return mIconId; + } + + @Override + public String getLabel() { + return null; + } + + @Override ExpectedKeyVisual toUpperCase(final Locale locale) { return this; } @@ -66,27 +78,32 @@ abstract class ExpectedKeyVisual { } @Override - boolean equalsTo(final String text) { + boolean hasSameKeyVisual(final String text) { return false; } @Override - boolean equalsTo(final Key key) { - return mIconId == key.getIconId(); + boolean hasSameKeyVisual(final Key key) { + // If the actual key has an icon as its visual, a label has to be null. + // See {@link KeyboardView#onDrawKeyTopVisuals(Key,Canvas,Paint,KeyDrawParams). + return mIconId == key.getIconId() && key.getLabel() == null; } @Override - boolean equalsTo(final MoreKeySpec moreKeySpec) { - return mIconId == moreKeySpec.mIconId; + boolean hasSameKeyVisual(final MoreKeySpec moreKeySpec) { + // If the actual more key has an icon as its visual, a label has to be null. + // See {@link KeySpecParser#getIconId(String)} and + // {@link KeySpecParser#getLabel(String)}. + return mIconId == moreKeySpec.mIconId && moreKeySpec.mLabel == null; } @Override - boolean equalsTo(final ExpectedKeyOutput output) { + boolean hasSameKeyVisual(final ExpectedKeyOutput output) { return false; } @Override - boolean equalsTo(final ExpectedKeyVisual visual) { + boolean hasSameKeyVisual(final ExpectedKeyVisual visual) { return (visual instanceof Icon) && mIconId == ((Icon)visual).mIconId; } @@ -102,12 +119,23 @@ abstract class ExpectedKeyVisual { private static class Label extends ExpectedKeyVisual { private final String mLabel; - Label(final String label) { mLabel = label; } + Label(final String label) { + mLabel = label; + } + + @Override + public int getIconId() { + return KeyboardIconsSet.ICON_UNDEFINED; + } + + @Override + public String getLabel() { + return mLabel; + } @Override ExpectedKeyVisual toUpperCase(final Locale locale) { - return new Label(StringUtils.toUpperCaseOfStringForLocale( - mLabel, true /* needsToUpperCase */, locale)); + return new Label(StringUtils.toTitleCaseOfKeyLabel(mLabel, locale)); } @Override @@ -116,27 +144,34 @@ abstract class ExpectedKeyVisual { } @Override - boolean equalsTo(final String text) { + boolean hasSameKeyVisual(final String text) { return mLabel.equals(text); } @Override - boolean equalsTo(final Key key) { - return mLabel.equals(key.getLabel()); + boolean hasSameKeyVisual(final Key key) { + // If the actual key has a label as its visual, an icon has to be undefined. + // See {@link KeyboardView#onDrawKeyTopVisuals(Key,Canvas,Paint,KeyDrawParams). + return mLabel.equals(key.getLabel()) + && key.getIconId() == KeyboardIconsSet.ICON_UNDEFINED; } @Override - boolean equalsTo(final MoreKeySpec moreKeySpec) { - return mLabel.equals(moreKeySpec.mLabel); + boolean hasSameKeyVisual(final MoreKeySpec moreKeySpec) { + // If the actual more key has a label as its visual, an icon has to be undefined. + // See {@link KeySpecParser#getIconId(String)} and + // {@link KeySpecParser#getLabel(String)}. + return mLabel.equals(moreKeySpec.mLabel) + && moreKeySpec.mIconId == KeyboardIconsSet.ICON_UNDEFINED; } @Override - boolean equalsTo(final ExpectedKeyOutput output) { - return output.equalsTo(mLabel); + boolean hasSameKeyVisual(final ExpectedKeyOutput output) { + return output.hasSameKeyOutput(mLabel); } @Override - boolean equalsTo(final ExpectedKeyVisual visual) { + boolean hasSameKeyVisual(final ExpectedKeyVisual visual) { return (visual instanceof Label) && mLabel.equals(((Label)visual).mLabel); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyboardBuilder.java b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyboardBuilder.java index 9b7de88ea..f5531c9e3 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyboardBuilder.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/expected/ExpectedKeyboardBuilder.java @@ -91,7 +91,7 @@ public final class ExpectedKeyboardBuilder extends AbstractKeyboardBuilder<Expec ExpectedKey[] keys = getRowAt(row); for (int columnIndex = 0; columnIndex < keys.length; /* nothing */) { final ExpectedKey currentKey = keys[columnIndex]; - if (!currentKey.getVisual().equalsTo(visual)) { + if (!currentKey.getVisual().hasSameKeyVisual(visual)) { columnIndex++; continue; } diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/KeyboardLayoutSetSubtypesCountTests.java index 6b0652c59..87f2f3011 100644 --- a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetSubtypesCountTests.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/KeyboardLayoutSetSubtypesCountTests.java @@ -14,19 +14,21 @@ * limitations under the License. */ -package com.android.inputmethod.keyboard; +package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import android.view.inputmethod.InputMethodSubtype; +import com.android.inputmethod.keyboard.KeyboardLayoutSetTestsBase; +import com.android.inputmethod.keyboard.KeyboardTheme; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import java.util.ArrayList; @SmallTest public class KeyboardLayoutSetSubtypesCountTests extends KeyboardLayoutSetTestsBase { - private static final int NUMBER_OF_SUBTYPES = 76; - private static final int NUMBER_OF_ASCII_CAPABLE_SUBTYPES = 45; + private static final int NUMBER_OF_SUBTYPES = 81; + private static final int NUMBER_OF_ASCII_CAPABLE_SUBTYPES = 49; private static final int NUMBER_OF_PREDEFINED_ADDITIONAL_SUBTYPES = 2; @Override @@ -52,13 +54,14 @@ public class KeyboardLayoutSetSubtypesCountTests extends KeyboardLayoutSetTestsB public final void testAsciiCapableSubtypesCount() { final ArrayList<InputMethodSubtype> asciiCapableSubtypesList = - getAsciiCapableSubtypesList(); + getSubtypesFilteredBy(FILTER_IS_ASCII_CAPABLE); assertEquals(toString(asciiCapableSubtypesList), NUMBER_OF_ASCII_CAPABLE_SUBTYPES, asciiCapableSubtypesList.size()); } public final void testAdditionalSubtypesCount() { - final ArrayList<InputMethodSubtype> additionalSubtypesList = getAdditionalSubtypesList(); + final ArrayList<InputMethodSubtype> additionalSubtypesList = + getSubtypesFilteredBy(FILTER_IS_ADDITIONAL_SUBTYPE); assertEquals(toString(additionalSubtypesList), NUMBER_OF_PREDEFINED_ADDITIONAL_SUBTYPES, additionalSubtypesList.size()); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java index a22ed60ac..27519ee93 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/LayoutTestsBase.java @@ -54,7 +54,8 @@ abstract class LayoutTestsBase extends KeyboardLayoutSetTestsBase { + (isPhone() ? "phone" : "tablet"); // TODO: Test with language switch key enabled and disabled. mKeyboardLayoutSet = createKeyboardLayoutSet(mSubtype, null /* editorInfo */, - true /* voiceInputKeyEnabled */, true /* languageSwitchKeyEnabled */); + true /* voiceInputKeyEnabled */, true /* languageSwitchKeyEnabled */, + false /* splitLayoutEnabled */); } @Override @@ -119,31 +120,13 @@ abstract class LayoutTestsBase extends KeyboardLayoutSetTestsBase { // TODO: Add phone, phone symbols, number, number password layout tests. - public final void testAlphabet() { + public final void testLayouts() { doKeyboardTests(KeyboardId.ELEMENT_ALPHABET); - } - - public final void testAlphabetAutomaticShifted() { doKeyboardTests(KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED); - } - - public final void testAlphabetManualShifted() { doKeyboardTests(KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED); - } - - public final void testAlphabetShiftLocked() { doKeyboardTests(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED); - } - - public final void testAlphabetShiftLockShifted() { doKeyboardTests(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED); - } - - public final void testSymbols() { doKeyboardTests(KeyboardId.ELEMENT_SYMBOLS); - } - - public final void testSymbolsShifted() { doKeyboardTests(KeyboardId.ELEMENT_SYMBOLS_SHIFTED); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAfrikaans.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAfrikaans.java index cd2259888..f534cd6fc 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAfrikaans.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAfrikaans.java @@ -19,8 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsArabic.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsArabic.java index fd7670827..a9be163d1 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsArabic.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsArabic.java @@ -19,7 +19,6 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Arabic; -import com.android.inputmethod.keyboard.layout.Arabic.ArabicCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public class TestsArabic extends LayoutTestsBase { private static final Locale LOCALE = new Locale("ar"); - private static final LayoutBase LAYOUT = new Arabic(new ArabicCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Arabic(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsArmenianAMPhonetic.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsArmenianAMPhonetic.java index 327e9438f..8ef97d21e 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsArmenianAMPhonetic.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsArmenianAMPhonetic.java @@ -19,7 +19,6 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.ArmenianPhonetic; -import com.android.inputmethod.keyboard.layout.ArmenianPhonetic.ArmenianPhoneticCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import java.util.Locale; @@ -30,8 +29,7 @@ import java.util.Locale; @SmallTest public final class TestsArmenianAMPhonetic extends LayoutTestsBase { private static final Locale LOCALE = new Locale("hy", "AM"); - private static final LayoutBase LAYOUT = new ArmenianPhonetic( - new ArmenianPhoneticCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new ArmenianPhonetic(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAzerbaijaniAZ.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAzerbaijaniAZ.java index f5317e269..a10023c69 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAzerbaijaniAZ.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsAzerbaijaniAZ.java @@ -19,9 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; +import com.android.inputmethod.keyboard.layout.customizer.TurkicCustomizer; import java.util.Locale; @@ -31,58 +30,8 @@ import java.util.Locale; @SmallTest public final class TestsAzerbaijaniAZ extends LayoutTestsBase { private static final Locale LOCALE = new Locale("az", "AZ"); - private static final LayoutBase LAYOUT = new Qwerty(new AzerbaijaniAZCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Qwerty(new TurkicCustomizer(LOCALE)); @Override LayoutBase getLayout() { return LAYOUT; } - - private static final class AzerbaijaniAZCustomizer extends LayoutCustomizer { - public AzerbaijaniAZCustomizer(final Locale locale) { super(locale); } - - @Override - public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { - return builder - // U+0259: "ə" LATIN SMALL LETTER SCHWA - .setMoreKeysOf("e", "\u0259") - // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS - // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX - // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE - // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE - // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON - .setMoreKeysOf("u", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B") - // U+0131: "ı" LATIN SMALL LETTER DOTLESS I - // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX - // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS - // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE - // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE - // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK - // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON - .setMoreKeysOf("i", - "\u0131", "\u00EE", "\u00EF", "\u00EC", "\u00ED", "\u012F", "\u012B") - // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS - // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX - // U+0153: "œ" LATIN SMALL LIGATURE OE - // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE - // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE - // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE - // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE - // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON - .setMoreKeysOf("o", - "\u00F6", "\u00F4", "\u0153", "\u00F2", "\u00F3", "\u00F5", "\u00F8", - "\u014D") - // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX - .setMoreKeysOf("a", "\u00E2") - // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA - // U+00DF: "ß" LATIN SMALL LETTER SHARP S - // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE - // U+0161: "š" LATIN SMALL LETTER S WITH CARON - .setMoreKeysOf("s", "\u015F", "\u00DF", "\u015B", "\u0161") - // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA - // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE - // U+010D: "č" LATIN SMALL LETTER C WITH CARON - .setMoreKeysOf("c", "\u00E7", "\u0107", "\u010D") - // U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE - .setMoreKeysOf("g", "\u011F"); - } - } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBasqueES.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBasqueES.java index bef18c5d5..103fac168 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBasqueES.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBasqueES.java @@ -19,8 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; import com.android.inputmethod.keyboard.layout.Spanish; +import com.android.inputmethod.keyboard.layout.customizer.EuroCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.SpanishCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; @@ -39,7 +40,7 @@ public class TestsBasqueES extends LayoutTestsBase { private static class BasqueESCustomizer extends EuroCustomizer { private final SpanishCustomizer mSpanishCustomizer; - public BasqueESCustomizer(final Locale locale) { + BasqueESCustomizer(final Locale locale) { super(locale); mSpanishCustomizer = new SpanishCustomizer(locale); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBelarusianBY.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBelarusianBY.java index c5238d54f..0b2393363 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBelarusianBY.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBelarusianBY.java @@ -19,9 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.EastSlavic; -import com.android.inputmethod.keyboard.layout.EastSlavic.EastSlavicCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.EastSlavicCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -39,7 +39,7 @@ public final class TestsBelarusianBY extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class BelarusianBYCustomizer extends EastSlavicCustomizer { - public BelarusianBYCustomizer(final Locale locale) { super(locale); } + BelarusianBYCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getDoubleQuoteMoreKeys() { diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliBD.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliBD.java new file mode 100644 index 000000000..2d38c874d --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliBD.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.tests; + +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.inputmethod.keyboard.layout.BengaliAkkhor; +import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.BengaliCustomizer; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; + +import java.util.Locale; + +/** + * bn_BD: Bengali (Bangladesh)/bengali_akkhor + */ +@SmallTest +public final class TestsBengaliBD extends LayoutTestsBase { + private static final Locale LOCALE = new Locale("bn", "BD"); + private static final LayoutBase LAYOUT = new BengaliAkkhor(new BengaliBDCustomzier(LOCALE)); + + @Override + LayoutBase getLayout() { return LAYOUT; } + + private static class BengaliBDCustomzier extends BengaliCustomizer { + BengaliBDCustomzier(final Locale locale) { super(locale); } + + @Override + public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { + return isPhone ? EMPTY_KEYS : EXCLAMATION_AND_QUESTION_MARKS; + } + + @Override + public ExpectedKey[] getSpaceKeys(final boolean isPhone) { + return joinKeys(LANGUAGE_SWITCH_KEY, SPACE_KEY, key(ZWNJ_KEY, ZWJ_KEY)); + } + + @Override + public ExpectedKey getCurrencyKey() { return CURRENCY_RUPEE; } + + // U+09F3: "৳" BENGALI RUPEE SIGN + private static final ExpectedKey CURRENCY_RUPEE = key("\u09F3", + Symbols.CURRENCY_GENERIC_MORE_KEYS); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliIN.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliIN.java index d64263207..022b0850d 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliIN.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBengaliIN.java @@ -19,9 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Bengali; -import com.android.inputmethod.keyboard.layout.Bengali.BengaliCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.BengaliCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import java.util.Locale; @@ -38,7 +38,10 @@ public final class TestsBengaliIN extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class BengaliINCustomzier extends BengaliCustomizer { - public BengaliINCustomzier(final Locale locale) { super(locale); } + BengaliINCustomzier(final Locale locale) { super(locale); } + + @Override + public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) { return EMPTY_KEYS; } @Override public ExpectedKey getCurrencyKey() { return CURRENCY_RUPEE; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBulgarian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBulgarian.java index ded8d7243..15308271c 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBulgarian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBulgarian.java @@ -19,7 +19,6 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Bulgarian; -import com.android.inputmethod.keyboard.layout.Bulgarian.BulgarianCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public final class TestsBulgarian extends LayoutTestsBase { private static final Locale LOCALE = new Locale("bg"); - private static final LayoutBase LAYOUT = new Bulgarian(new BulgarianCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Bulgarian(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBulgarianBds.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBulgarianBds.java index 22b2011ee..558b1d44a 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBulgarianBds.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsBulgarianBds.java @@ -19,7 +19,6 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.BulgarianBds; -import com.android.inputmethod.keyboard.layout.BulgarianBds.BulgarianBdsCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public final class TestsBulgarianBds extends LayoutTestsBase { private static final Locale LOCALE = new Locale("bg"); - private static final LayoutBase LAYOUT = new BulgarianBds(new BulgarianBdsCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new BulgarianBds(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCatalan.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCatalan.java index 151a0a627..a323ffda4 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCatalan.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCatalan.java @@ -19,8 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; import com.android.inputmethod.keyboard.layout.Spanish; +import com.android.inputmethod.keyboard.layout.customizer.EuroCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -38,20 +38,20 @@ public class TestsCatalan extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class CatalanCustomizer extends EuroCustomizer { - public CatalanCustomizer(final Locale locale) { super(locale); } + CatalanCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) { - return isPhone ? PHONE_PUNCTUATION_MORE_KEYS - : TABLET_PUNCTUATION_MORE_KEYS; + return isPhone ? CATALAN_PHONE_PUNCTUATION_MORE_KEYS + : CATALAN_TABLET_PUNCTUATION_MORE_KEYS; } // U+00B7: "·" MIDDLE DOT - private static final ExpectedKey[] PHONE_PUNCTUATION_MORE_KEYS = joinKeys( + private static final ExpectedKey[] CATALAN_PHONE_PUNCTUATION_MORE_KEYS = joinKeys( ",", "?", "!", "\u00B7", "#", ")", "(", "/", ";", "'", "@", ":", "-", "\"", "+", "%", "&"); - private static final ExpectedKey[] TABLET_PUNCTUATION_MORE_KEYS = joinKeys( + private static final ExpectedKey[] CATALAN_TABLET_PUNCTUATION_MORE_KEYS = joinKeys( ",", "'", "\u00B7", "#", ")", "(", "/", ";", "@", ":", "-", "\"", "+", "%", "&"); diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCroatian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCroatian.java index 8575ef219..d8af75bca 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCroatian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCroatian.java @@ -19,9 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Qwertz; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -39,7 +39,7 @@ public final class TestsCroatian extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class CroatianCustomizer extends LayoutCustomizer { - public CroatianCustomizer(final Locale locale) { super(locale); } + CroatianCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_L9R; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCzech.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCzech.java index f4794707f..f05b8ebf2 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCzech.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsCzech.java @@ -19,9 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Qwertz; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -39,7 +39,7 @@ public final class TestsCzech extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class CzechCustomizer extends LayoutCustomizer { - public CzechCustomizer(final Locale locale) { super(locale); } + CzechCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDanish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDanish.java index 85c63a128..fb7338d1b 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDanish.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDanish.java @@ -19,11 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; import com.android.inputmethod.keyboard.layout.Nordic; -import com.android.inputmethod.keyboard.layout.Symbols; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; +import com.android.inputmethod.keyboard.layout.customizer.DanishCustomizer; import java.util.Locale; @@ -37,73 +34,4 @@ public final class TestsDanish extends LayoutTestsBase { @Override LayoutBase getLayout() { return LAYOUT; } - - private static class DanishCustomizer extends EuroCustomizer { - public DanishCustomizer(final Locale locale) { super(locale); } - - @Override - public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; } - - @Override - public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_R9L; } - - @Override - public ExpectedKey[] getDoubleAngleQuoteKeys() { return Symbols.DOUBLE_ANGLE_QUOTES_RL; } - - @Override - public ExpectedKey[] getSingleAngleQuoteKeys() { return Symbols.SINGLE_ANGLE_QUOTES_RL; } - - @Override - public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { - return builder - // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE - // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS - .setMoreKeysOf("e", "\u00E9", "\u00EB") - // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE - // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS - .setMoreKeysOf("y", "\u00FD", "\u00FF") - // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE - // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS - // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX - // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE - // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON - .setMoreKeysOf("u", "\u00FA", "\u00FC", "\u00FB", "\u00F9", "\u016B") - // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE - // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS - .setMoreKeysOf("i", "\u00ED", "\u00EF") - // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE - // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX - // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE - // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE - // U+0153: "œ" LATIN SMALL LIGATURE OE - // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON - .setMoreKeysOf("o", "\u00F3", "\u00F4", "\u00F2", "\u00F5", "\u0153", "\u014D") - // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE - .replaceKeyOfLabel(Nordic.ROW1_11, "\u00E5") - // U+00E6: "æ" LATIN SMALL LETTER AE - // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS - .replaceKeyOfLabel(Nordic.ROW2_10, key("\u00E6", moreKey("\u00E4"))) - // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE - // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS - .replaceKeyOfLabel(Nordic.ROW2_11, key("\u00F8", moreKey("\u00F6"))) - // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE - // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS - // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE - // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX - // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE - // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON - .setMoreKeysOf("a", "\u00E1", "\u00E4", "\u00E0", "\u00E2", "\u00E3", "\u0101") - // U+00DF: "ß" LATIN SMALL LETTER SHARP S - // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE - // U+0161: "š" LATIN SMALL LETTER S WITH CARON - .setMoreKeysOf("s", "\u00DF", "\u015B", "\u0161") - // U+00F0: "ð" LATIN SMALL LETTER ETH - .setMoreKeysOf("d", "\u00F0") - // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE - .setMoreKeysOf("l", "\u0142") - // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE - // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE - .setMoreKeysOf("n", "\u00F1", "\u0144"); - } - } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDanishQwertz.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDanishQwertz.java new file mode 100644 index 000000000..718bf8aec --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDanishQwertz.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.tests; + +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.Qwertz; +import com.android.inputmethod.keyboard.layout.customizer.DanishCustomizer; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +/** + * da: Danish/qwertz + */ +@SmallTest +public final class TestsDanishQwertz extends LayoutTestsBase { + private static final Locale LOCALE = new Locale("da"); + private static final LayoutBase LAYOUT = new Qwertz(new DanishQwertyCustomizer(LOCALE)); + + @Override + LayoutBase getLayout() { return LAYOUT; } + + private static class DanishQwertyCustomizer extends DanishCustomizer { + DanishQwertyCustomizer(final Locale locale) { super(locale); } + + @Override + protected void setNordicKeys(final ExpectedKeyboardBuilder builder) { + // QWERTZ layout doesn't have Nordic keys. + } + + @Override + protected void setMoreKeysOfA(final ExpectedKeyboardBuilder builder) { + builder + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + .setMoreKeysOf("a", "\u00E5", "\u00E6", "\u00E1", "\u00E4", "\u00E0", "\u00E2", + "\u00E3", "\u0101"); + } + + @Override + protected void setMoreKeysOfO(final ExpectedKeyboardBuilder builder) { + builder + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + .setMoreKeysOf("o", "\u00F8", "\u00F6", "\u00F3", "\u00F4", "\u00F2", "\u00F5", + "\u0153", "\u014D"); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutch.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutch.java index 1730f66be..12bd1b176 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutch.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutch.java @@ -19,11 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; -import com.android.inputmethod.keyboard.layout.Symbols; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; +import com.android.inputmethod.keyboard.layout.customizer.DutchCustomizer; import java.util.Locale; @@ -37,70 +34,4 @@ public final class TestsDutch extends LayoutTestsBase { @Override LayoutBase getLayout() { return LAYOUT; } - - static class DutchCustomizer extends EuroCustomizer { - public DutchCustomizer(final Locale locale) { super(locale); } - - @Override - public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_L9R; } - - @Override - public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_L9R; } - - @Override - public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { - return builder - // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE - // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS - // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX - // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE - // U+00E6: "æ" LATIN SMALL LETTER AE - // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE - // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE - // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON - .setMoreKeysOf("a", - "\u00E1", "\u00E4", "\u00E2", "\u00E0", "\u00E6", "\u00E3", "\u00E5", - "\u0101") - // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE - // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS - // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX - // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE - // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK - // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE - // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON - .setMoreKeysOf("e", - "\u00E9", "\u00EB", "\u00EA", "\u00E8", "\u0119", "\u0117", "\u0113") - // U+0133: "ij" LATIN SMALL LIGATURE IJ - .setMoreKeysOf("y", "\u0133") - // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE - // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS - // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX - // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE - // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON - .setMoreKeysOf("u", "\u00FA", "\u00FC", "\u00FB", "\u00F9", "\u016B") - // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE - // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS - // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE - // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX - // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK - // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON - // U+0133: "ij" LATIN SMALL LIGATURE IJ - .setMoreKeysOf("i", - "\u00ED", "\u00EF", "\u00EC", "\u00EE", "\u012F", "\u012B", "\u0133") - // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE - // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS - // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX - // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE - // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE - // U+0153: "œ" LATIN SMALL LIGATURE OE - // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE - // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON - .setMoreKeysOf("o", - "\u00F3", "\u00F6", "\u00F4", "\u00F2", "\u00F5", "\u0153", "\u00F8", - "\u014D") - // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE - // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE - .setMoreKeysOf("n", "\u00F1", "\u0144"); - } - } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutchBE.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutchBE.java index 31adf7a8d..146411858 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutchBE.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDutchBE.java @@ -20,7 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Azerty; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.tests.TestsDutch.DutchCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.DutchCustomizer; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDvorakEmail.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDvorakEmail.java index 37ca09238..3966ebc06 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDvorakEmail.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDvorakEmail.java @@ -25,8 +25,9 @@ import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.keyboard.KeyboardLayoutSet; import com.android.inputmethod.keyboard.layout.Dvorak; import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.customizer.DvorakCustomizer.EnglishDvorakCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; -import com.android.inputmethod.keyboard.layout.tests.TestsEnglishDvorak.EnglishDvorakCustomizer; import java.util.Locale; @@ -44,12 +45,13 @@ public class TestsDvorakEmail extends LayoutTestsBase { @Override protected KeyboardLayoutSet createKeyboardLayoutSet(final InputMethodSubtype subtype, final EditorInfo editorInfo, final boolean voiceInputKeyEnabled, - final boolean languageSwitchKeyEnabled) { + final boolean languageSwitchKeyEnabled, final boolean splitLayoutEnabled) { final EditorInfo emailField = new EditorInfo(); emailField.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS; return super.createKeyboardLayoutSet( - subtype, emailField, voiceInputKeyEnabled, languageSwitchKeyEnabled); + subtype, emailField, voiceInputKeyEnabled, languageSwitchKeyEnabled, + splitLayoutEnabled); } private static class DvorakEmailCustomizer extends EnglishDvorakCustomizer { @@ -59,23 +61,23 @@ public class TestsDvorakEmail extends LayoutTestsBase { @Override public ExpectedKey getEnterKey(final boolean isPhone) { - return isPhone ? LayoutBase.ENTER_KEY : super.getEnterKey(isPhone); + return isPhone ? ENTER_KEY : super.getEnterKey(isPhone); } @Override public ExpectedKey getEmojiKey(final boolean isPhone) { - return LayoutBase.DOMAIN_KEY; + return DOMAIN_KEY; } @Override public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) { return isPhone ? super.getKeysLeftToSpacebar(isPhone) - : joinKeys(key("@", LayoutBase.SETTINGS_KEY)); + : joinKeys(key("@", SETTINGS_KEY)); } } private static class DvorakEmail extends Dvorak { - public DvorakEmail(final LayoutCustomizer customizer) { + DvorakEmail(final LayoutCustomizer customizer) { super(customizer); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDvorakUrl.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDvorakUrl.java index 3bcae0ce4..67e0d91af 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDvorakUrl.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsDvorakUrl.java @@ -25,8 +25,9 @@ import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.keyboard.KeyboardLayoutSet; import com.android.inputmethod.keyboard.layout.Dvorak; import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.customizer.DvorakCustomizer.EnglishDvorakCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; -import com.android.inputmethod.keyboard.layout.tests.TestsEnglishDvorak.EnglishDvorakCustomizer; import java.util.Locale; @@ -44,40 +45,37 @@ public class TestsDvorakUrl extends LayoutTestsBase { @Override protected KeyboardLayoutSet createKeyboardLayoutSet(final InputMethodSubtype subtype, final EditorInfo editorInfo, final boolean voiceInputKeyEnabled, - final boolean languageSwitchKeyEnabled) { + final boolean languageSwitchKeyEnabled, final boolean splitLayoutEnabled) { final EditorInfo emailField = new EditorInfo(); emailField.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI; return super.createKeyboardLayoutSet( - subtype, emailField, voiceInputKeyEnabled, languageSwitchKeyEnabled); + subtype, emailField, voiceInputKeyEnabled, languageSwitchKeyEnabled, + splitLayoutEnabled); } private static class DvorakUrlCustomizer extends EnglishDvorakCustomizer { - DvorakUrlCustomizer(final Locale locale) { - super(locale); - } + DvorakUrlCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getEnterKey(final boolean isPhone) { - return isPhone ? LayoutBase.ENTER_KEY : super.getEnterKey(isPhone); + return isPhone ? ENTER_KEY : super.getEnterKey(isPhone); } @Override public ExpectedKey getEmojiKey(final boolean isPhone) { - return LayoutBase.DOMAIN_KEY; + return DOMAIN_KEY; } @Override public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) { return isPhone ? super.getKeysLeftToSpacebar(isPhone) - : joinKeys(key("/", LayoutBase.SETTINGS_KEY)); + : joinKeys(key("/", SETTINGS_KEY)); } } private static class DvorakEmail extends Dvorak { - public DvorakEmail(final LayoutCustomizer customizer) { - super(customizer); - } + DvorakEmail(final LayoutCustomizer customizer) { super(customizer); } @Override protected ExpectedKey getRow1_1Key(final boolean isPhone, final int elementId) { diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishDvorak.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishDvorak.java index e647f8aea..2b25f813c 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishDvorak.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishDvorak.java @@ -19,9 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Dvorak; -import com.android.inputmethod.keyboard.layout.Dvorak.DvorakCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; +import com.android.inputmethod.keyboard.layout.customizer.DvorakCustomizer.EnglishDvorakCustomizer; import java.util.Locale; @@ -35,18 +34,4 @@ public class TestsEnglishDvorak extends LayoutTestsBase { @Override LayoutBase getLayout() { return LAYOUT; } - - public static class EnglishDvorakCustomizer extends DvorakCustomizer { - private final EnglishCustomizer mEnglishCustomizer; - - EnglishDvorakCustomizer(final Locale locale) { - super(locale); - mEnglishCustomizer = new EnglishCustomizer(locale); - } - - @Override - public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { - return mEnglishCustomizer.setAccentedLetters(builder); - } - } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishIN.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishIN.java index c80b25024..54759cef1 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishIN.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishIN.java @@ -22,6 +22,7 @@ import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Qwerty; import com.android.inputmethod.keyboard.layout.Symbols; import com.android.inputmethod.keyboard.layout.SymbolsShifted; +import com.android.inputmethod.keyboard.layout.customizer.EnglishCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import java.util.Locale; @@ -38,7 +39,7 @@ public final class TestsEnglishIN extends TestsEnglishUS { LayoutBase getLayout() { return LAYOUT; } private static class EnglishINCustomizer extends EnglishCustomizer { - public EnglishINCustomizer(final Locale locale) { super(locale); } + EnglishINCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getCurrencyKey() { return CURRENCY_RUPEE; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUK.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUK.java index c0dcbdc06..714a6001a 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUK.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUK.java @@ -21,6 +21,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Qwerty; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.EnglishCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import java.util.Locale; @@ -37,7 +38,7 @@ public final class TestsEnglishUK extends TestsEnglishUS { LayoutBase getLayout() { return LAYOUT; } private static class EnglishUKCustomizer extends EnglishCustomizer { - public EnglishUKCustomizer(final Locale locale) { super(locale); } + EnglishUKCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getCurrencyKey() { return CURRENCY_POUND; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUS.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUS.java index 6ea8f6000..570ee9d0b 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUS.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEnglishUS.java @@ -20,6 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.EnglishCustomizer; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEsperanto.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEsperanto.java index 6a44187c9..a6792e28e 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEsperanto.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEsperanto.java @@ -19,8 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Spanish; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; @@ -37,7 +37,7 @@ public class TestsEsperanto extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class EsperantoCustomizer extends LayoutCustomizer { - public EsperantoCustomizer(final Locale locale) { super(locale); } + EsperantoCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEstonianEE.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEstonianEE.java index 865e9ea17..8cb67e223 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEstonianEE.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEstonianEE.java @@ -19,11 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; import com.android.inputmethod.keyboard.layout.Nordic; -import com.android.inputmethod.keyboard.layout.Symbols; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; +import com.android.inputmethod.keyboard.layout.customizer.EstonianEECustomizer; import java.util.Locale; @@ -37,121 +34,4 @@ public final class TestsEstonianEE extends LayoutTestsBase { @Override LayoutBase getLayout() { return LAYOUT; } - - private static class EstonianEECustomizer extends EuroCustomizer { - public EstonianEECustomizer(final Locale locale) { - super(locale); - } - - @Override - public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; } - - @Override - public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_R9L; } - - @Override - public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { - return builder - // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON - // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE - // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE - // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE - // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX - // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS - // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK - // U+011B: "ě" LATIN SMALL LETTER E WITH CARON - .setMoreKeysOf("e", - "\u0113", "\u00E8", "\u0117", "\u00E9", "\u00EA", "\u00EB", "\u0119", - "\u011B") - // U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA - // U+0159: "ř" LATIN SMALL LETTER R WITH CARON - // U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE - .setMoreKeysOf("r", "\u0157", "\u0159", "\u0155") - // U+0163: "ţ" LATIN SMALL LETTER T WITH CEDILLA - // U+0165: "ť" LATIN SMALL LETTER T WITH CARON - .setMoreKeysOf("t", "\u0163", "\u0165") - // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE - // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS - .setMoreKeysOf("y", "\u00FD", "\u00FF") - // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS - // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON - // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK - // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE - // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE - // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX - // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE - // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE - .setMoreKeysOf("u", - "\u00FC", "\u016B", "\u0173", "\u00F9", "\u00FA", "\u00FB", "\u016F", - "\u0171") - // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON - // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE - // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK - // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE - // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX - // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS - // U+0131: "ı" LATIN SMALL LETTER DOTLESS I - .setMoreKeysOf("i", - "\u012B", "\u00EC", "\u012F", "\u00ED", "\u00EE", "\u00EF", "\u0131") - // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS - // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE - // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE - // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE - // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX - // U+0153: "œ" LATIN SMALL LIGATURE OE - // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE - // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE - .setMoreKeysOf("o", - "\u00F6", "\u00F5", "\u00F2", "\u00F3", "\u00F4", "\u0153", "\u0151", - "\u00F8") - // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS - .replaceKeyOfLabel(Nordic.ROW1_11, "\u00FC") - // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS - // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE - .replaceKeyOfLabel(Nordic.ROW2_10, key("\u00F6", moreKey("\u00F5"))) - // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS - .replaceKeyOfLabel(Nordic.ROW2_11, "\u00E4") - // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS - // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON - // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE - // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE - // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX - // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE - // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE - // U+00E6: "æ" LATIN SMALL LETTER AE - // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK - .setMoreKeysOf("a", - "\u00E4", "\u0101", "\u00E0", "\u00E1", "\u00E2", "\u00E3", "\u00E5", - "\u00E6", "\u0105") - // U+0161: "š" LATIN SMALL LETTER S WITH CARON - // U+00DF: "ß" LATIN SMALL LETTER SHARP S - // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE - // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA - .setMoreKeysOf("s", "\u0161", "\u00DF", "\u015B", "\u015F") - // U+010F: "ď" LATIN SMALL LETTER D WITH CARON - .setMoreKeysOf("d", "\u010F") - // U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA - // U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE - .setMoreKeysOf("g", "\u0123", "\u011F") - // U+0137: "ķ" LATIN SMALL LETTER K WITH CEDILLA - .setMoreKeysOf("k", "\u0137") - // U+013C: "ļ" LATIN SMALL LETTER L WITH CEDILLA - // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE - // U+013A: "ĺ" LATIN SMALL LETTER L WITH ACUTE - // U+013E: "ľ" LATIN SMALL LETTER L WITH CARON - .setMoreKeysOf("l", "\u013C", "\u0142", "\u013A", "\u013E") - // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON - // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE - // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE - .setMoreKeysOf("z", "\u017E", "\u017C", "\u017A") - // U+010D: "č" LATIN SMALL LETTER C WITH CARON - // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA - // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE - .setMoreKeysOf("c", "\u010D", "\u00E7", "\u0107") - // U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA - // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE - // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE - .setMoreKeysOf("n", "\u0146", "\u00F1", "\u0144"); - } - } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEstonianEEQwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEstonianEEQwerty.java new file mode 100644 index 000000000..fb7c24371 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsEstonianEEQwerty.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.tests; + +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.EstonianEECustomizer; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +/** + * et_EE: Estonian (Estonia)/qwerty + */ +@SmallTest +public final class TestsEstonianEEQwerty extends LayoutTestsBase { + private static final Locale LOCALE = new Locale("et", "EE"); + private static final LayoutBase LAYOUT = new Qwerty(new EstonianEEQwertyCustomizer(LOCALE)); + + @Override + LayoutBase getLayout() { return LAYOUT; } + + private static class EstonianEEQwertyCustomizer extends EstonianEECustomizer { + EstonianEEQwertyCustomizer(final Locale locale) { super(locale); } + + @Override + protected void setNordicKeys(final ExpectedKeyboardBuilder builder) { + // QWERTY layout doesn't have Nordic keys. + } + + @Override + protected void setMoreKeysOfA(final ExpectedKeyboardBuilder builder) { + builder + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK + .setMoreKeysOf("a", "\u00E4", "\u0101", "\u00E0", "\u00E1", "\u00E2", "\u00E3", + "\u00E5", "\u00E6", "\u0105"); + } + + @Override + protected void setMoreKeysOfI(final ExpectedKeyboardBuilder builder, final int elementId) { + // TODO: The upper-case letter of "ı" in Estonian locale is "I". It should be omitted + // from the more keys of "I". + builder + // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON + // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE + // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK + // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS + // U+0131: "ı" LATIN SMALL LETTER DOTLESS I + .setMoreKeysOf("i", + "\u012B", "\u00EC", "\u012F", "\u00ED", "\u00EE", "\u00EF", "\u0131"); + } + + @Override + protected void setMoreKeysOfO(final ExpectedKeyboardBuilder builder) { + builder + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + .setMoreKeysOf("o", "\u00F6", "\u00F5", "\u00F2", "\u00F3", "\u00F4", "\u0153", + "\u0151", "\u00F8"); + } + + @Override + protected void setMoreKeysOfU(final ExpectedKeyboardBuilder builder) { + builder + // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + // U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK + // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE + // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE + // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX + // U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE + // U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE + .setMoreKeysOf("u", "\u00FC", "\u016B", "\u0173", "\u00F9", "\u00FA", "\u00FB", + "\u016F", "\u0171"); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFinnish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFinnish.java index ff32da117..3d42f30fd 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFinnish.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFinnish.java @@ -19,9 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; import com.android.inputmethod.keyboard.layout.Nordic; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; +import com.android.inputmethod.keyboard.layout.customizer.FinnishCustomizer; import java.util.Locale; @@ -35,47 +34,4 @@ public final class TestsFinnish extends LayoutTestsBase { @Override LayoutBase getLayout() { return LAYOUT; } - - private static class FinnishCustomizer extends EuroCustomizer { - public FinnishCustomizer(final Locale locale) { super(locale); } - - @Override - public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { - return builder - // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS - .setMoreKeysOf("u", "\u00FC") - // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE - // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX - // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE - // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE - // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE - // U+0153: "œ" LATIN SMALL LIGATURE OE - // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON - .setMoreKeysOf("o", - "\u00F8", "\u00F4", "\u00F2", "\u00F3", "\u00F5", "\u0153", "\u014D") - // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE - .replaceKeyOfLabel(Nordic.ROW1_11, "\u00E5") - // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS - // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE - .replaceKeyOfLabel(Nordic.ROW2_10, key("\u00F6", moreKey("\u00F8"))) - // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS - // U+00E6: "æ" LATIN SMALL LETTER AE - .replaceKeyOfLabel(Nordic.ROW2_11, key("\u00E4", moreKey("\u00E6"))) - // U+00E6: "æ" LATIN SMALL LETTER AE - // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE - // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE - // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX - // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE - // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON - .setMoreKeysOf("a", "\u00E6", "\u00E0", "\u00E1", "\u00E2", "\u00E3", "\u0101") - // U+0161: "š" LATIN SMALL LETTER S WITH CARON - // U+00DF: "ß" LATIN SMALL LETTER SHARP S - // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE - .setMoreKeysOf("s", "\u0161", "\u00DF", "\u015B") - // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON - // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE - // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE - .setMoreKeysOf("z", "\u017E", "\u017A", "\u017C"); - } - } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFinnishQwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFinnishQwerty.java new file mode 100644 index 000000000..c81b2a2bc --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFinnishQwerty.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.tests; + +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.FinnishCustomizer; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +/** + * fi: Finnish/qwerty + */ +@SmallTest +public final class TestsFinnishQwerty extends LayoutTestsBase { + private static final Locale LOCALE = new Locale("fi"); + private static final LayoutBase LAYOUT = new Qwerty(new FinnishQwertyCustomizer(LOCALE)); + + @Override + LayoutBase getLayout() { return LAYOUT; } + + private static class FinnishQwertyCustomizer extends FinnishCustomizer { + FinnishQwertyCustomizer(final Locale locale) { super(locale); } + + @Override + protected void setNordicKeys(final ExpectedKeyboardBuilder builder) { + // QWERTY layout doesn't have Nordic keys. + } + + @Override + protected void setMoreKeysOfA(final ExpectedKeyboardBuilder builder) { + builder + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + .setMoreKeysOf("a", "\u00E4", "\u00E5", "\u00E6", "\u00E0", "\u00E1", "\u00E2", + "\u00E3", "\u0101"); + } + + @Override + protected void setMoreKeysOfO(final ExpectedKeyboardBuilder builder) { + builder + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + .setMoreKeysOf("o", "\u00F6", "\u00F8", "\u00F4", "\u00F2", "\u00F3", "\u00F5", + "\u0153", "\u014D"); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrench.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrench.java index 7ced1fb7b..ca663f4f6 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrench.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrench.java @@ -20,8 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Azerty; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.keyboard.layout.customizer.FrenchCustomizer.FrenchEuroCustomizer; import java.util.Locale; @@ -35,21 +34,4 @@ public final class TestsFrench extends LayoutTestsBase { @Override LayoutBase getLayout() { return LAYOUT; } - - static final class FrenchEuroCustomizer extends FrenchCustomizer { - private final EuroCustomizer mEuroCustomizer; - - public FrenchEuroCustomizer(final Locale locale) { - super(locale); - mEuroCustomizer = new EuroCustomizer(locale); - } - - @Override - public final ExpectedKey getCurrencyKey() { return mEuroCustomizer.getCurrencyKey(); } - - @Override - public final ExpectedKey[] getOtherCurrencyKeys() { - return mEuroCustomizer.getOtherCurrencyKeys(); - } - } -}
\ No newline at end of file +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCA.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCA.java index 9b3cd1ee2..12c94b141 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCA.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCA.java @@ -20,6 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.FrenchCustomizer; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCH.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCH.java index 2598aa3bf..2461157e6 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCH.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchCH.java @@ -20,6 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Swiss; +import com.android.inputmethod.keyboard.layout.customizer.FrenchCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; @@ -36,7 +37,7 @@ public final class TestsFrenchCH extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class FrenchCHCustomizer extends FrenchCustomizer { - public FrenchCHCustomizer(final Locale locale) { super(locale); } + FrenchCHCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchDvorak.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchDvorak.java index 33d1445a4..40530638b 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchDvorak.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchDvorak.java @@ -19,11 +19,11 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Dvorak; -import com.android.inputmethod.keyboard.layout.Dvorak.DvorakCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.customizer.DvorakCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.FrenchCustomizer.FrenchEuroCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; -import com.android.inputmethod.keyboard.layout.tests.TestsFrench.FrenchEuroCustomizer; import java.util.Locale; @@ -41,7 +41,7 @@ public final class TestsFrenchDvorak extends LayoutTestsBase { private static class FrenchDvorakCustomizer extends DvorakCustomizer { private final FrenchEuroCustomizer mFrenchEuroCustomizer; - public FrenchDvorakCustomizer(final Locale locale) { + FrenchDvorakCustomizer(final Locale locale) { super(locale); mFrenchEuroCustomizer = new FrenchEuroCustomizer(locale); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchQwertz.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchQwertz.java index 6ab28704a..67edacea7 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchQwertz.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsFrenchQwertz.java @@ -20,7 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Qwertz; -import com.android.inputmethod.keyboard.layout.tests.TestsFrench.FrenchEuroCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.FrenchCustomizer.FrenchEuroCustomizer; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGalicianES.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGalicianES.java index 1472828a4..c37fff254 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGalicianES.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGalicianES.java @@ -19,8 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; import com.android.inputmethod.keyboard.layout.Spanish; +import com.android.inputmethod.keyboard.layout.customizer.EuroCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.SpanishCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; @@ -39,7 +40,7 @@ public class TestsGalicianES extends LayoutTestsBase { private static class GalicianESCustomizer extends EuroCustomizer { private final SpanishCustomizer mSpanishCustomizer; - public GalicianESCustomizer(final Locale locale) { + GalicianESCustomizer(final Locale locale) { super(locale); mSpanishCustomizer = new SpanishCustomizer(locale); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGeorgianGE.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGeorgianGE.java index f25942fb5..f6e3080c7 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGeorgianGE.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGeorgianGE.java @@ -19,7 +19,6 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Georgian; -import com.android.inputmethod.keyboard.layout.Georgian.GeorgianCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public final class TestsGeorgianGE extends LayoutTestsBase { private static final Locale LOCALE = new Locale("ka", "GE"); - private static final LayoutBase LAYOUT = new Georgian(new GeorgianCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Georgian(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGerman.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGerman.java index 6f7571197..52c5a0688 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGerman.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGerman.java @@ -19,9 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; import com.android.inputmethod.keyboard.layout.Qwertz; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.keyboard.layout.customizer.GermanCustomizer.GermanEuroCustomizer; import java.util.Locale; @@ -35,21 +34,4 @@ public final class TestsGerman extends LayoutTestsBase { @Override LayoutBase getLayout() { return LAYOUT; } - - static class GermanEuroCustomizer extends GermanCustomizer { - final EuroCustomizer mEuroCustomizer; - - public GermanEuroCustomizer(final Locale locale) { - super(locale); - mEuroCustomizer = new EuroCustomizer(locale); - } - - @Override - public ExpectedKey getCurrencyKey() { return mEuroCustomizer.getCurrencyKey(); } - - @Override - public ExpectedKey[] getOtherCurrencyKeys() { - return mEuroCustomizer.getOtherCurrencyKeys(); - } - } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanCH.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanCH.java index 7deb00bb4..10981d920 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanCH.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanCH.java @@ -20,6 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Swiss; +import com.android.inputmethod.keyboard.layout.customizer.GermanCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; @@ -36,7 +37,7 @@ public final class TestsGermanCH extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class GermanCHCustomizer extends GermanCustomizer { - public GermanCHCustomizer(final Locale locale) { super(locale); } + GermanCHCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanDvorak.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanDvorak.java index b28d5cfcf..36d1cb8c4 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanDvorak.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanDvorak.java @@ -19,10 +19,11 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Dvorak; -import com.android.inputmethod.keyboard.layout.Dvorak.DvorakCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Symbols; import com.android.inputmethod.keyboard.layout.SymbolsShifted; +import com.android.inputmethod.keyboard.layout.customizer.DvorakCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.GermanCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -39,10 +40,10 @@ public final class TestsGermanDvorak extends LayoutTestsBase { @Override LayoutBase getLayout() { return LAYOUT; } - static class GermanDvorakCustomizer extends DvorakCustomizer { - final GermanCustomizer mGermanCustomizer; + private static class GermanDvorakCustomizer extends DvorakCustomizer { + private final GermanCustomizer mGermanCustomizer; - public GermanDvorakCustomizer(final Locale locale) { + GermanDvorakCustomizer(final Locale locale) { super(locale); mGermanCustomizer = new GermanCustomizer(locale); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanQwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanQwerty.java index 19ae5a3f5..6db942f2a 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanQwerty.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGermanQwerty.java @@ -20,7 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Qwerty; -import com.android.inputmethod.keyboard.layout.tests.TestsGerman.GermanEuroCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.GermanCustomizer.GermanEuroCustomizer; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGreek.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGreek.java index 4acb119ac..fd21d522c 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGreek.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsGreek.java @@ -19,7 +19,6 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Greek; -import com.android.inputmethod.keyboard.layout.Greek.GreekCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public class TestsGreek extends LayoutTestsBase { private static final Locale LOCALE = new Locale("el"); - private static final LayoutBase LAYOUT = new Greek(new GreekCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Greek(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHebrew.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHebrew.java index c0243a870..cc6304881 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHebrew.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHebrew.java @@ -19,7 +19,6 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Hebrew; -import com.android.inputmethod.keyboard.layout.Hebrew.HebrewCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public class TestsHebrew extends LayoutTestsBase { private static final Locale LOCALE = new Locale("iw"); - private static final LayoutBase LAYOUT = new Hebrew(new HebrewCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Hebrew(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHindi.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHindi.java index 84053b5be..53652fce0 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHindi.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHindi.java @@ -19,8 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Hindi; -import com.android.inputmethod.keyboard.layout.Hindi.HindiCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.customizer.HindiCustomizer; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHindiCompact.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHindiCompact.java index 2e676df26..cfe3e9ea5 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHindiCompact.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHindiCompact.java @@ -19,7 +19,6 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.HindiCompact; -import com.android.inputmethod.keyboard.layout.HindiCompact.HindiCompactCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public final class TestsHindiCompact extends LayoutTestsBase { private static final Locale LOCALE = new Locale("hi"); - private static final LayoutBase LAYOUT = new HindiCompact(new HindiCompactCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new HindiCompact(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java new file mode 100644 index 000000000..a8e872316 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHinglish.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.tests; + +import android.test.suitebuilder.annotation.Suppress; + +import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.SymbolsShifted; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; + +import java.util.Locale; + +/* + * hi_ZZ: Hinglish/qwerty + */ +@Suppress +public final class TestsHinglish extends LayoutTestsBase { + private static final Locale LOCALE = new Locale("hi", "ZZ"); + private static final LayoutBase LAYOUT = new Qwerty(new HinglishCustomizer(LOCALE)); + + @Override + LayoutBase getLayout() { return LAYOUT; } + + private static class HinglishCustomizer extends LayoutCustomizer { + HinglishCustomizer(final Locale locale) { super(locale); } + + @Override + public ExpectedKey getCurrencyKey() { return CURRENCY_RUPEE; } + + @Override + public ExpectedKey[] getOtherCurrencyKeys() { + return SymbolsShifted.CURRENCIES_OTHER_GENERIC; + } + + // U+20B9: "₹" INDIAN RUPEE SIGN + private static final ExpectedKey CURRENCY_RUPEE = key("\u20B9", + Symbols.CURRENCY_GENERIC_MORE_KEYS); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHungarian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHungarian.java index efc95dcf9..a32e2b551 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHungarian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsHungarian.java @@ -19,9 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Qwertz; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -39,7 +39,7 @@ public final class TestsHungarian extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class HungarianCustomizer extends LayoutCustomizer { - public HungarianCustomizer(final Locale locale) { super(locale); } + HungarianCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_L9R; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsIcelandic.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsIcelandic.java index 62b111e6a..8eabf1815 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsIcelandic.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsIcelandic.java @@ -19,9 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -39,7 +39,7 @@ public final class TestsIcelandic extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class IcelandicCustomizer extends LayoutCustomizer { - public IcelandicCustomizer(final Locale locale) { super(locale); } + IcelandicCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsIndonesian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsIndonesian.java index 9b23bfe2b..83711714d 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsIndonesian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsIndonesian.java @@ -19,8 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalian.java index f3c610c8b..2acc9679b 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalian.java @@ -19,8 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.EuroCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.ItalianCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; @@ -39,7 +40,7 @@ public final class TestsItalian extends LayoutTestsBase { private static class ItalianITCustomizer extends EuroCustomizer { private final ItalianCustomizer mItalianCustomizer; - public ItalianITCustomizer(final Locale locale) { + ItalianITCustomizer(final Locale locale) { super(locale); mItalianCustomizer = new ItalianCustomizer(locale); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalianCH.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalianCH.java index d32f9e957..f98545a50 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalianCH.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsItalianCH.java @@ -20,6 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Swiss; +import com.android.inputmethod.keyboard.layout.customizer.ItalianCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; @@ -36,7 +37,7 @@ public final class TestsItalianCH extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class ItalianCHCustomizer extends ItalianCustomizer { - public ItalianCHCustomizer(final Locale locale) { super(locale); } + ItalianCHCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKannadaIN.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKannadaIN.java index d1866e803..a0ff1d0ac 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKannadaIN.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKannadaIN.java @@ -19,7 +19,6 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Kannada; -import com.android.inputmethod.keyboard.layout.Kannada.KannadaCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public final class TestsKannadaIN extends LayoutTestsBase { private static final Locale LOCALE = new Locale("kn", "IN"); - private static final LayoutBase LAYOUT = new Kannada(new KannadaCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Kannada(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKazakh.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKazakh.java index d255a0fa9..66ece29ee 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKazakh.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKazakh.java @@ -19,8 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.EastSlavic; -import com.android.inputmethod.keyboard.layout.EastSlavic.EastSlavicCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.customizer.EastSlavicCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; @@ -37,7 +37,7 @@ public final class TestsKazakh extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class KazakhCustomizer extends EastSlavicCustomizer { - public KazakhCustomizer(final Locale locale) { super(locale); } + KazakhCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKhmerKH.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKhmerKH.java index df2f40d86..dde9b87f6 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKhmerKH.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKhmerKH.java @@ -19,7 +19,6 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Khmer; -import com.android.inputmethod.keyboard.layout.Khmer.KhmerCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public final class TestsKhmerKH extends LayoutTestsBase { private static final Locale LOCALE = new Locale("km", "KH"); - private static final LayoutBase LAYOUT = new Khmer(new KhmerCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Khmer(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKyrgyz.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKyrgyz.java index 9797b4ba9..3faf2f6be 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKyrgyz.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsKyrgyz.java @@ -19,8 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.EastSlavic; -import com.android.inputmethod.keyboard.layout.EastSlavic.EastSlavicCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.customizer.EastSlavicCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; @@ -37,7 +37,7 @@ public final class TestsKyrgyz extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class KyrgyzCustomizer extends EastSlavicCustomizer { - public KyrgyzCustomizer(final Locale locale) { super(locale); } + KyrgyzCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLaoLA.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLaoLA.java index 34ad1fb7f..ffa337285 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLaoLA.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLaoLA.java @@ -19,7 +19,6 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Lao; -import com.android.inputmethod.keyboard.layout.Lao.LaoCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public final class TestsLaoLA extends LayoutTestsBase { private static final Locale LOCALE = new Locale("lo", "LA"); - private static final LayoutBase LAYOUT = new Lao(new LaoCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Lao(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLatvian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLatvian.java index dc1736c6d..dbab16a12 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLatvian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLatvian.java @@ -19,9 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -39,7 +39,7 @@ public final class TestsLatvian extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class LatvianCustomizer extends LayoutCustomizer { - public LatvianCustomizer(final Locale locale) { super(locale); } + LatvianCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLithuanian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLithuanian.java index 55ac37a37..248014a0d 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLithuanian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsLithuanian.java @@ -19,9 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -39,7 +39,7 @@ public final class TestsLithuanian extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class LithuanianCustomizer extends LayoutCustomizer { - public LithuanianCustomizer(final Locale locale) { super(locale); } + LithuanianCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMacedonian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMacedonian.java index 1d7d85650..46b1c39d5 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMacedonian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMacedonian.java @@ -20,8 +20,8 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.SouthSlavic; -import com.android.inputmethod.keyboard.layout.SouthSlavic.SouthSlavicLayoutCustomizer; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.SouthSlavicLayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -39,7 +39,7 @@ public final class TestsMacedonian extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class MacedonianCustomizer extends SouthSlavicLayoutCustomizer { - public MacedonianCustomizer(final Locale locale) { super(locale); } + MacedonianCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMalayMY.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMalayMY.java index 9792af9d0..a6e6cd50c 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMalayMY.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMalayMY.java @@ -19,8 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMalayalamIN.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMalayalamIN.java index b494ad37b..e3fcb5332 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMalayalamIN.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMalayalamIN.java @@ -20,7 +20,6 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Malayalam; -import com.android.inputmethod.keyboard.layout.Malayalam.MalayalamCustomizer; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public final class TestsMalayalamIN extends LayoutTestsBase { private static final Locale LOCALE = new Locale("ml", "IN"); - private static final LayoutBase LAYOUT = new Malayalam(new MalayalamCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Malayalam(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMarathiIN.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMarathiIN.java index b937629b0..3e54f6e3d 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMarathiIN.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMarathiIN.java @@ -20,7 +20,6 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Marathi; -import com.android.inputmethod.keyboard.layout.Marathi.MarathiCustomizer; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public final class TestsMarathiIN extends LayoutTestsBase { private static final Locale LOCALE = new Locale("mr", "IN"); - private static final LayoutBase LAYOUT = new Marathi(new MarathiCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Marathi(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMongolianMN.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMongolianMN.java index e28e962f9..6dafe7789 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMongolianMN.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMongolianMN.java @@ -20,7 +20,6 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Mongolian; -import com.android.inputmethod.keyboard.layout.Mongolian.MongolianMNCustomizer; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public final class TestsMongolianMN extends LayoutTestsBase { private static final Locale LOCALE = new Locale("mn", "MN"); - private static final LayoutBase LAYOUT = new Mongolian(new MongolianMNCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Mongolian(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNepaliRomanized.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNepaliRomanized.java index 971976aec..f646db379 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNepaliRomanized.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNepaliRomanized.java @@ -20,7 +20,6 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.NepaliRomanized; -import com.android.inputmethod.keyboard.layout.NepaliRomanized.NepaliRomanizedCustomizer; import java.util.Locale; @@ -30,8 +29,7 @@ import java.util.Locale; @SmallTest public final class TestsNepaliRomanized extends LayoutTestsBase { private static final Locale LOCALE = new Locale("ne", "NP"); - private static final LayoutBase LAYOUT = new NepaliRomanized( - new NepaliRomanizedCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new NepaliRomanized(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNepaliTraditional.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNepaliTraditional.java index 724c4304f..99d87b143 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNepaliTraditional.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNepaliTraditional.java @@ -20,7 +20,6 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.NepaliTraditional; -import com.android.inputmethod.keyboard.layout.NepaliTraditional.NepaliTraditionalCustomizer; import java.util.Locale; @@ -30,8 +29,7 @@ import java.util.Locale; @SmallTest public final class TestsNepaliTraditional extends LayoutTestsBase { private static final Locale LOCALE = new Locale("ne", "NP"); - private static final LayoutBase LAYOUT = new NepaliTraditional( - new NepaliTraditionalCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new NepaliTraditional(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguage.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguage.java index 3ed63153a..149d520c7 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguage.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguage.java @@ -20,6 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.NoLanguageCustomizer; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguageColemak.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguageColemak.java index 8d627e3b4..979947f2f 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguageColemak.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguageColemak.java @@ -20,7 +20,8 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Colemak; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.NoLanguageCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; @@ -39,7 +40,7 @@ public final class TestsNoLanguageColemak extends LayoutTestsBase { private static class NoLanguageColemakCustomizer extends LayoutCustomizer { private final NoLanguageCustomizer mNoLanguageCustomizer; - public NoLanguageColemakCustomizer(final Locale locale) { + NoLanguageColemakCustomizer(final Locale locale) { super(locale); mNoLanguageCustomizer = new NoLanguageCustomizer(locale); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguageDvorak.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguageDvorak.java index 9bf47ed42..542319394 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguageDvorak.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguageDvorak.java @@ -19,8 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Dvorak; -import com.android.inputmethod.keyboard.layout.Dvorak.DvorakCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.customizer.DvorakCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.NoLanguageCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; @@ -39,7 +40,7 @@ public final class TestsNoLanguageDvorak extends LayoutTestsBase { private static class NoLanguageDvorakCustomizer extends DvorakCustomizer { private final NoLanguageCustomizer mNoLanguageCustomizer; - public NoLanguageDvorakCustomizer(final Locale locale) { + NoLanguageDvorakCustomizer(final Locale locale) { super(locale); mNoLanguageCustomizer = new NoLanguageCustomizer(locale); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguagePcQwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguagePcQwerty.java index cd8d43ca8..20b587b73 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguagePcQwerty.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNoLanguagePcQwerty.java @@ -20,7 +20,8 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.PcQwerty; -import com.android.inputmethod.keyboard.layout.PcQwerty.PcQwertyCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.NoLanguageCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.PcQwertyCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; @@ -39,7 +40,7 @@ public final class TestsNoLanguagePcQwerty extends LayoutTestsBase { private static class NoLanguagePcQwertyCustomizer extends PcQwertyCustomizer { private final NoLanguageCustomizer mNoLanguageCustomizer; - public NoLanguagePcQwertyCustomizer(final Locale locale) { + NoLanguagePcQwertyCustomizer(final Locale locale) { super(locale); mNoLanguageCustomizer = new NoLanguageCustomizer(locale); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNorwegian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNorwegian.java index 5d220dfa1..910512c98 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNorwegian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNorwegian.java @@ -19,11 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Nordic; -import com.android.inputmethod.keyboard.layout.Symbols; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; +import com.android.inputmethod.keyboard.layout.customizer.NorwegianCustomizer; import java.util.Locale; @@ -37,58 +34,4 @@ public final class TestsNorwegian extends LayoutTestsBase { @Override LayoutBase getLayout() { return LAYOUT; } - - private static class NorwegianCustomizer extends LayoutCustomizer { - public NorwegianCustomizer(final Locale locale) { super(locale); } - - @Override - public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_L9R; } - - @Override - public ExpectedKey[] getSingleQuoteMoreKeys() { return Symbols.SINGLE_QUOTES_L9R; } - - @Override - public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { - return builder - // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE - // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE - // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX - // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS - // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK - // U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE - // U+0113: "ē" LATIN SMALL LETTER E WITH MACRON - .setMoreKeysOf("e", - "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0119", "\u0117", "\u0113") - // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS - // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX - // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE - // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE - // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON - .setMoreKeysOf("u", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B") - // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX - // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE - // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE - // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS - // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE - // U+0153: "œ" LATIN SMALL LIGATURE OE - // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON - .setMoreKeysOf("o", - "\u00F4", "\u00F2", "\u00F3", "\u00F6", "\u00F5", "\u0153", "\u014D") - // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE - .replaceKeyOfLabel(Nordic.ROW1_11, "\u00E5") - // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE - // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS - .replaceKeyOfLabel(Nordic.ROW2_10, key("\u00F8", moreKey("\u00F6"))) - // U+00E6: "æ" LATIN SMALL LETTER AE - // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS - .replaceKeyOfLabel(Nordic.ROW2_11, key("\u00E6", moreKey("\u00E4"))) - // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE - // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS - // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE - // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX - // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE - // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON - .setMoreKeysOf("a", "\u00E0", "\u00E4", "\u00E1", "\u00E2", "\u00E3", "\u0101"); - } - } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNorwegianColemak.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNorwegianColemak.java new file mode 100644 index 000000000..689c38e17 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsNorwegianColemak.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.tests; + +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.inputmethod.keyboard.layout.Colemak; +import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.customizer.NorwegianCustomizer; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +/** + * nb: Norwegian Bokmål/colemak + */ +@SmallTest +public final class TestsNorwegianColemak extends LayoutTestsBase { + private static final Locale LOCALE = new Locale("nb"); + private static final LayoutBase LAYOUT = new Colemak(new NorwegianColemakCustomizer(LOCALE)); + + @Override + LayoutBase getLayout() { return LAYOUT; } + + private static class NorwegianColemakCustomizer extends NorwegianCustomizer { + NorwegianColemakCustomizer(final Locale locale) { super(locale); } + + @Override + protected void setNordicKeys(final ExpectedKeyboardBuilder builder) { + // Colemak layout doesn't have Nordic keys. + } + + @Override + protected void setMoreKeysOfA(final ExpectedKeyboardBuilder builder) { + builder + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON + .setMoreKeysOf("a", "\u00E5", "\u00E6", "\u00E4", "\u00E0", "\u00E1", "\u00E2", + "\u00E3", "\u0101"); + } + + @Override + protected void setMoreKeysOfO(final ExpectedKeyboardBuilder builder) { + builder + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + .setMoreKeysOf("o", "\u00F8", "\u00F6", "\u00F4", "\u00F2", "\u00F3", "\u00F5", + "\u0153", "\u014D"); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPersian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPersian.java index b7d75c9f0..8ea8075c4 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPersian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPersian.java @@ -19,7 +19,6 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.Farsi; -import com.android.inputmethod.keyboard.layout.Farsi.FarsiCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public class TestsPersian extends LayoutTestsBase { private static final Locale LOCALE = new Locale("fa"); - private static final LayoutBase LAYOUT = new Farsi(new FarsiCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Farsi(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPolish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPolish.java index 04f88c3fc..4f1170afe 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPolish.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPolish.java @@ -19,9 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -39,7 +39,7 @@ public final class TestsPolish extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class PolishCustomizer extends LayoutCustomizer { - public PolishCustomizer(final Locale locale) { super(locale); } + PolishCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_L9R; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortugueseBR.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortugueseBR.java index 8a984a765..7fadaac7e 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortugueseBR.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortugueseBR.java @@ -20,6 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.PortugueseCustomizer; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortuguesePT.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortuguesePT.java index e15e811db..5936e8dce 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortuguesePT.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsPortuguesePT.java @@ -19,8 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.EuroCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.PortugueseCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import java.util.Locale; @@ -39,7 +40,7 @@ public final class TestsPortuguesePT extends TestsPortugueseBR { private static class PortuguesePTCustomizer extends PortugueseCustomizer { private final EuroCustomizer mEuroCustomizer; - public PortuguesePTCustomizer(final Locale locale) { + PortuguesePTCustomizer(final Locale locale) { super(locale); mEuroCustomizer = new EuroCustomizer(locale); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsQwertyEmail.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsQwertyEmail.java index 8563d6933..cc204def8 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsQwertyEmail.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsQwertyEmail.java @@ -24,6 +24,7 @@ import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.keyboard.KeyboardLayoutSet; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.EnglishCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import java.util.Locale; @@ -42,32 +43,31 @@ public class TestsQwertyEmail extends LayoutTestsBase { @Override protected KeyboardLayoutSet createKeyboardLayoutSet(final InputMethodSubtype subtype, final EditorInfo editorInfo, final boolean voiceInputKeyEnabled, - final boolean languageSwitchKeyEnabled) { + final boolean languageSwitchKeyEnabled, final boolean splitLayoutEnabled) { final EditorInfo emailField = new EditorInfo(); emailField.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS; return super.createKeyboardLayoutSet( - subtype, emailField, voiceInputKeyEnabled, languageSwitchKeyEnabled); + subtype, emailField, voiceInputKeyEnabled, languageSwitchKeyEnabled, + splitLayoutEnabled); } private static class EnglishEmailCustomizer extends EnglishCustomizer { - EnglishEmailCustomizer(final Locale locale) { - super(locale); - } + EnglishEmailCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getEnterKey(final boolean isPhone) { - return isPhone ? LayoutBase.ENTER_KEY : super.getEnterKey(isPhone); + return isPhone ? ENTER_KEY : super.getEnterKey(isPhone); } @Override public ExpectedKey getEmojiKey(final boolean isPhone) { - return LayoutBase.DOMAIN_KEY; + return DOMAIN_KEY; } @Override public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) { - return joinKeys(key("@", LayoutBase.SETTINGS_KEY)); + return joinKeys(key("@", SETTINGS_KEY)); } } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsQwertyUrl.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsQwertyUrl.java index 1c1a2bbbd..acd09d25a 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsQwertyUrl.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsQwertyUrl.java @@ -24,6 +24,7 @@ import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.keyboard.KeyboardLayoutSet; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.EnglishCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import java.util.Locale; @@ -42,32 +43,31 @@ public class TestsQwertyUrl extends LayoutTestsBase { @Override protected KeyboardLayoutSet createKeyboardLayoutSet(final InputMethodSubtype subtype, final EditorInfo editorInfo, final boolean voiceInputKeyEnabled, - final boolean languageSwitchKeyEnabled) { + final boolean languageSwitchKeyEnabled, final boolean splitLayoutEnabled) { final EditorInfo emailField = new EditorInfo(); emailField.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI; return super.createKeyboardLayoutSet( - subtype, emailField, voiceInputKeyEnabled, languageSwitchKeyEnabled); + subtype, emailField, voiceInputKeyEnabled, languageSwitchKeyEnabled, + splitLayoutEnabled); } private static class EnglishUrlCustomizer extends EnglishCustomizer { - EnglishUrlCustomizer(final Locale locale) { - super(locale); - } + EnglishUrlCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getEnterKey(final boolean isPhone) { - return isPhone ? LayoutBase.ENTER_KEY : super.getEnterKey(isPhone); + return isPhone ? ENTER_KEY : super.getEnterKey(isPhone); } @Override public ExpectedKey getEmojiKey(final boolean isPhone) { - return LayoutBase.DOMAIN_KEY; + return DOMAIN_KEY; } @Override public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) { - return joinKeys(key("/", LayoutBase.SETTINGS_KEY)); + return joinKeys(key("/", SETTINGS_KEY)); } } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRomanian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRomanian.java index 0207f1c22..af4fbca84 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRomanian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRomanian.java @@ -19,9 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -39,7 +39,7 @@ public final class TestsRomanian extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class RomanianCustomizer extends LayoutCustomizer { - public RomanianCustomizer(final Locale locale) { super(locale); } + RomanianCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_L9R; } @@ -59,9 +59,9 @@ public final class TestsRomanian extends LayoutTestsBase { // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON .setMoreKeysOf("i", "\u00EE", "\u00EF", "\u00EC", "\u00ED", "\u012F", "\u012B") + // U+0103: "ă" LATIN SMALL LETTER A WITH BREVE // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE - // U+0103: "ă" LATIN SMALL LETTER A WITH BREVE // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS @@ -69,7 +69,7 @@ public final class TestsRomanian extends LayoutTestsBase { // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE // U+0101: "ā" LATIN SMALL LETTER A WITH MACRON .setMoreKeysOf("a", - "\u00E2", "\u00E3", "\u0103", "\u00E0", "\u00E1", "\u00E4", "\u00E6", + "\u0103", "\u00E2", "\u00E3", "\u00E0", "\u00E1", "\u00E4", "\u00E6", "\u00E5", "\u0101") // U+0219: "ș" LATIN SMALL LETTER S WITH COMMA BELOW // U+00DF: "ß" LATIN SMALL LETTER SHARP S diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRussian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRussian.java index 9919207ed..75ef48154 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRussian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsRussian.java @@ -19,9 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.EastSlavic; -import com.android.inputmethod.keyboard.layout.EastSlavic.EastSlavicCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.EastSlavicCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -39,7 +39,7 @@ public final class TestsRussian extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class RussianCustomizer extends EastSlavicCustomizer { - public RussianCustomizer(final Locale locale) { super(locale); } + RussianCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbian.java index 41f1690f3..9495706b2 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbian.java @@ -20,8 +20,8 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.SouthSlavic; -import com.android.inputmethod.keyboard.layout.SouthSlavic.SouthSlavicLayoutCustomizer; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.SouthSlavicLayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -39,7 +39,7 @@ public final class TestsSerbian extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class SerbianCustomizer extends SouthSlavicLayoutCustomizer { - public SerbianCustomizer(final Locale locale) { super(locale); } + SerbianCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatin.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatin.java new file mode 100644 index 000000000..7490d30ab --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatin.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.tests; + +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.SerbianQwertz; +import com.android.inputmethod.keyboard.layout.customizer.SerbianLatinCustomizer; + +import java.util.Locale; + +/** + * sr_ZZ: Serbian (Latin)/serbian_qwertz + */ +@SmallTest +public final class TestsSerbianLatin extends LayoutTestsBase { + private static final Locale LOCALE = new Locale("sr", "ZZ"); + private static final LayoutBase LAYOUT = new SerbianQwertz(new SerbianLatinCustomizer(LOCALE)); + + @Override + LayoutBase getLayout() { return LAYOUT; } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatinQwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatinQwerty.java new file mode 100644 index 000000000..6d9351c9d --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSerbianLatinQwerty.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.tests; + +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.SerbianLatinCustomizer; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +/** + * sr_ZZ: Serbian (Latin)/qwerty + */ +@SmallTest +public final class TestsSerbianLatinQwerty extends LayoutTestsBase { + private static final Locale LOCALE = new Locale("sr", "ZZ"); + private static final LayoutBase LAYOUT = new Qwerty(new SerbianLatinQwertyCustomizer(LOCALE)); + + @Override + LayoutBase getLayout() { return LAYOUT; } + + private static class SerbianLatinQwertyCustomizer extends SerbianLatinCustomizer { + SerbianLatinQwertyCustomizer(final Locale locale) { super(locale); } + + @Override + public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { + return isPhone ? EMPTY_KEYS + : joinKeys(EXCLAMATION_AND_QUESTION_MARKS, SHIFT_KEY); + } + + @Override + protected void setSerbianKeys(final ExpectedKeyboardBuilder builder) { + // QWERTY layout doesn't have Serbian Latin Keys. + } + + @Override + protected void setMoreKeysOfS(final ExpectedKeyboardBuilder builder) { + builder + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + .setMoreKeysOf("s", "\u0161") + .setAdditionalMoreKeysPositionOf("s", 2); + } + + @Override + protected void setMoreKeysOfC(final ExpectedKeyboardBuilder builder) { + builder + // U+010D: "č" LATIN SMALL LETTER C WITH CARON + // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE + .setMoreKeysOf("c", "\u010D", "\u0107") + .setAdditionalMoreKeysPositionOf("c", 3); + } + + @Override + protected void setMoreKeysOfD(final ExpectedKeyboardBuilder builder) { + builder + // U+0111: "đ" LATIN SMALL LETTER D WITH STROKE + .setMoreKeysOf("d", "\u0111") + .setAdditionalMoreKeysPositionOf("d", 2); + } + + @Override + protected void setMoreKeysOfZ(final ExpectedKeyboardBuilder builder) { + builder + // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON + .setMoreKeysOf("z", "\u017E") + .setAdditionalMoreKeysPositionOf("z", 2); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSinhalaLK.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSinhalaLK.java index 8b861359b..c55c17c53 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSinhalaLK.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSinhalaLK.java @@ -20,7 +20,6 @@ import android.test.suitebuilder.annotation.Suppress; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Sinhala; -import com.android.inputmethod.keyboard.layout.Sinhala.SinhalaCustomizer; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @Suppress public final class TestsSinhalaLK extends LayoutTestsBase { private static final Locale LOCALE = new Locale("si", "LK"); - private static final LayoutBase LAYOUT = new Sinhala(new SinhalaCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Sinhala(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovak.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovak.java index bdaf0cad1..c94471644 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovak.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovak.java @@ -19,9 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.EuroCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -39,7 +39,7 @@ public final class TestsSlovak extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class SlovakCustomizer extends EuroCustomizer { - public SlovakCustomizer(final Locale locale) { super(locale); } + SlovakCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovenian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovenian.java index cdb1beeba..e49a27b94 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovenian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSlovenian.java @@ -19,9 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; import com.android.inputmethod.keyboard.layout.Symbols; +import com.android.inputmethod.keyboard.layout.customizer.EuroCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -39,7 +39,7 @@ public final class TestsSlovenian extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class SlovenianCustomizer extends EuroCustomizer { - public SlovenianCustomizer(final Locale locale) { super(locale); } + SlovenianCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getDoubleQuoteMoreKeys() { return Symbols.DOUBLE_QUOTES_R9L; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanish.java index 12e8676ae..6c8693199 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanish.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanish.java @@ -19,8 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; import com.android.inputmethod.keyboard.layout.Spanish; +import com.android.inputmethod.keyboard.layout.customizer.EuroCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.SpanishCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import java.util.Locale; @@ -39,7 +40,7 @@ public class TestsSpanish extends LayoutTestsBase { private static class SpanishESCustomizer extends SpanishCustomizer { private final EuroCustomizer mEuroCustomizer; - public SpanishESCustomizer(final Locale locale) { + SpanishESCustomizer(final Locale locale) { super(locale); mEuroCustomizer = new EuroCustomizer(locale); } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanish419.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanish419.java index 75aad136f..828f4c4bc 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanish419.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanish419.java @@ -20,6 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Spanish; +import com.android.inputmethod.keyboard.layout.customizer.SpanishCustomizer; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanishUS.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanishUS.java index c3ac0a0c0..b5bfbe47f 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanishUS.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSpanishUS.java @@ -20,6 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Spanish; +import com.android.inputmethod.keyboard.layout.customizer.SpanishCustomizer; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSplitLayoutQwertyEnglishUS.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSplitLayoutQwertyEnglishUS.java new file mode 100644 index 000000000..c401d3d36 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSplitLayoutQwertyEnglishUS.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.tests; + +import android.test.suitebuilder.annotation.SmallTest; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.keyboard.KeyboardLayoutSet; +import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.EnglishCustomizer; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; + +import java.util.Locale; + +/** + * en_US: English (United States)/qwerty - split layout + */ +@SmallTest +public class TestsSplitLayoutQwertyEnglishUS extends LayoutTestsBase { + private static final Locale LOCALE = new Locale("en", "US"); + private static final LayoutBase LAYOUT = new Qwerty(new EnglishSplitCustomizer(LOCALE)); + + @Override + protected KeyboardLayoutSet createKeyboardLayoutSet(final InputMethodSubtype subtype, + final EditorInfo editorInfo, final boolean voiceInputKeyEnabled, + final boolean languageSwitchKeyEnabled, final boolean splitLayoutEnabled) { + return super.createKeyboardLayoutSet(subtype, editorInfo, voiceInputKeyEnabled, + languageSwitchKeyEnabled, true /* splitLayoutEnabled */); + } + + @Override + LayoutBase getLayout() { return LAYOUT; } + + private static class EnglishSplitCustomizer extends EnglishCustomizer { + EnglishSplitCustomizer(Locale locale) { super(locale); } + + @Override + public ExpectedKey[] getSpaceKeys(final boolean isPhone) { + if (isPhone) { + return super.getSpaceKeys(isPhone); + } + return joinKeys(LANGUAGE_SWITCH_KEY, SPACE_KEY, SPACE_KEY); + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwahili.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwahili.java index 13b974194..a8ab966ac 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwahili.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwahili.java @@ -19,8 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; @@ -37,7 +37,7 @@ public final class TestsSwahili extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class SwahiliCustomizer extends LayoutCustomizer { - public SwahiliCustomizer(final Locale locale) { super(locale); } + SwahiliCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwedish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwedish.java index 9b58914a2..061001d49 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwedish.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwedish.java @@ -19,11 +19,8 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; import com.android.inputmethod.keyboard.layout.Nordic; -import com.android.inputmethod.keyboard.layout.Symbols; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; -import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; +import com.android.inputmethod.keyboard.layout.customizer.SwedishCustomizer; import java.util.Locale; @@ -37,88 +34,4 @@ public final class TestsSwedish extends LayoutTestsBase { @Override LayoutBase getLayout() { return LAYOUT; } - - private static class SwedishCustomizer extends EuroCustomizer { - public SwedishCustomizer(final Locale locale) { super(locale); } - - @Override - public ExpectedKey[] getDoubleAngleQuoteKeys() { return Symbols.DOUBLE_ANGLE_QUOTES_RL; } - - @Override - public ExpectedKey[] getSingleAngleQuoteKeys() { return Symbols.SINGLE_ANGLE_QUOTES_RL; } - - @Override - public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { - return builder - // U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE - // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE - // U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX - // U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS - // U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK - .setMoreKeysOf("e", "\u00E9", "\u00E8", "\u00EA", "\u00EB", "\u0119") - // U+0159: "ř" LATIN SMALL LETTER R WITH CARON - .setMoreKeysOf("r", "\u0159") - // U+0165: "ť" LATIN SMALL LETTER T WITH CARON - // U+00FE: "þ" LATIN SMALL LETTER THORN - .setMoreKeysOf("t", "\u0165", "\u00FE") - // U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE - // U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS - .setMoreKeysOf("y", "\u00FD", "\u00FF") - // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS - // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE - // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE - // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX - // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON - .setMoreKeysOf("u", "\u00FC", "\u00FA", "\u00F9", "\u00FB", "\u016B") - // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE - // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE - // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX - // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS - .setMoreKeysOf("i", "\u00ED", "\u00EC", "\u00EE", "\u00EF") - // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE - // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE - // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX - // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE - // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON - .setMoreKeysOf("o", "\u00F3", "\u00F2", "\u00F4", "\u00F5", "\u014D") - // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE - .replaceKeyOfLabel(Nordic.ROW1_11, "\u00E5") - // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS - // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE - // U+0153: "œ" LATIN SMALL LIGATURE OE - .replaceKeyOfLabel(Nordic.ROW2_10, - key("\u00F6", joinMoreKeys("\u00F8", "\u0153"))) - // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS - // U+00E6: "æ" LATIN SMALL LETTER AE - .replaceKeyOfLabel(Nordic.ROW2_11, key("\u00E4", moreKey("\u00E6"))) - // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE - // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE - // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX - // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK - // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE - .setMoreKeysOf("a", "\u00E1", "\u00E0", "\u00E2", "\u0105", "\u00E3") - // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE - // U+0161: "š" LATIN SMALL LETTER S WITH CARON - // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA - // U+00DF: "ß" LATIN SMALL LETTER SHARP S - .setMoreKeysOf("s", "\u015B", "\u0161", "\u015F", "\u00DF") - // U+00F0: "ð" LATIN SMALL LETTER ETH - // U+010F: "ď" LATIN SMALL LETTER D WITH CARON - .setMoreKeysOf("d", "\u00F0", "\u010F") - // U+0142: "ł" LATIN SMALL LETTER L WITH STROKE - .setMoreKeysOf("l", "\u0142") - // U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE - // U+017E: "ž" LATIN SMALL LETTER Z WITH CARON - // U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE - .setMoreKeysOf("z", "\u017A", "\u017E", "\u017C") - // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA - // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE - // U+010D: "č" LATIN SMALL LETTER C WITH CARON - .setMoreKeysOf("c", "\u00E7", "\u0107", "\u010D") - // U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE - // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE - // U+0148: "ň" LATIN SMALL LETTER N WITH CARON - .setMoreKeysOf("n", "\u0144", "\u00F1", "\u0148"); - } - } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwedishPcQwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwedishPcQwerty.java new file mode 100644 index 000000000..dc3d83134 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsSwedishPcQwerty.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard.layout.tests; + +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.PcQwerty; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.PcQwertyCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.SwedishCustomizer; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +/** + * sv: Swedish/pcqwerty + */ +@SmallTest +public final class TestsSwedishPcQwerty extends LayoutTestsBase { + private static final Locale LOCALE = new Locale("sv"); + private static final LayoutBase LAYOUT = new PcQwerty(new SwedishPcQwertyCustomizer(LOCALE)); + + @Override + LayoutBase getLayout() { return LAYOUT; } + + private static class SwedishPcQwertyCustomizer extends SwedishCustomizer { + private final LayoutCustomizer mPcQwertyCustomizer; + + SwedishPcQwertyCustomizer(final Locale locale) { + super(locale); + mPcQwertyCustomizer = new PcQwertyCustomizer(locale); + } + + @Override + public ExpectedKey getCurrencyKey() { + return mPcQwertyCustomizer.getCurrencyKey(); + } + + @Override + public ExpectedKey[] getOtherCurrencyKeys() { + return mPcQwertyCustomizer.getOtherCurrencyKeys(); + } + + @Override + public int getNumberOfRows() { + return mPcQwertyCustomizer.getNumberOfRows(); + } + + @Override + public ExpectedKey[] getLeftShiftKeys(final boolean isPhone) { + return mPcQwertyCustomizer.getLeftShiftKeys(isPhone); + } + + @Override + public ExpectedKey[] getRightShiftKeys(final boolean isPhone) { + return mPcQwertyCustomizer.getRightShiftKeys(isPhone); + } + + @Override + public ExpectedKey[] getKeysLeftToSpacebar(final boolean isPhone) { + return mPcQwertyCustomizer.getKeysLeftToSpacebar(isPhone); + } + + @Override + public ExpectedKey[] getKeysRightToSpacebar(final boolean isPhone) { + return mPcQwertyCustomizer.getKeysRightToSpacebar(isPhone); + } + + @Override + protected void setNordicKeys(final ExpectedKeyboardBuilder builder) { + // PC QWERTY layout doesn't have Nordic keys. + } + + @Override + protected void setMoreKeysOfA(final ExpectedKeyboardBuilder builder) { + builder + // U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS + // U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE + // U+00E6: "æ" LATIN SMALL LETTER AE + // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX + // U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK + // U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE + .setMoreKeysOf("a", "\u00E4", "\u00E5", "\u00E6", "\u00E1", "\u00E0", "\u00E2", + "\u0105", "\u00E3"); + } + + @Override + protected void setMoreKeysOfO(final ExpectedKeyboardBuilder builder) { + builder + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE + // U+0153: "œ" LATIN SMALL LIGATURE OE + // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE + // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE + // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX + // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE + // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON + .setMoreKeysOf("o", "\u00F6", "\u00F8", "\u0153", "\u00F3", "\u00F2", "\u00F4", + "\u00F5", "\u014D"); + } + + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTagalog.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTagalog.java index 38d5364e5..ecef2d79e 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTagalog.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTagalog.java @@ -20,6 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Spanish; +import com.android.inputmethod.keyboard.layout.customizer.SpanishCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import java.util.Locale; @@ -36,15 +37,11 @@ public class TestsTagalog extends TestsSpanish { LayoutBase getLayout() { return LAYOUT; } private static class TagalogCustomizer extends SpanishCustomizer { - - public TagalogCustomizer(final Locale locale) { - super(locale); - } + TagalogCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey[] getPunctuationMoreKeys(final boolean isPhone) { - return isPhone ? LayoutBase.PHONE_PUNCTUATION_MORE_KEYS - : LayoutBase.TABLET_PUNCTUATION_MORE_KEYS; + return isPhone ? PHONE_PUNCTUATION_MORE_KEYS : TABLET_PUNCTUATION_MORE_KEYS; } } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTamilIN.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTamilIN.java index 31df53c0b..3297d399f 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTamilIN.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTamilIN.java @@ -22,7 +22,7 @@ import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Symbols; import com.android.inputmethod.keyboard.layout.SymbolsShifted; import com.android.inputmethod.keyboard.layout.Tamil; -import com.android.inputmethod.keyboard.layout.Tamil.TamilCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.TamilCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import java.util.Locale; @@ -39,7 +39,7 @@ public final class TestsTamilIN extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class TamilINCustomizer extends TamilCustomizer { - public TamilINCustomizer(final Locale locale) { super(locale); } + TamilINCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getCurrencyKey() { return CURRENCY_RUPEE; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTamilLK.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTamilLK.java index 65ec0b036..72872ba66 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTamilLK.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTamilLK.java @@ -22,7 +22,7 @@ import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Symbols; import com.android.inputmethod.keyboard.layout.SymbolsShifted; import com.android.inputmethod.keyboard.layout.Tamil; -import com.android.inputmethod.keyboard.layout.Tamil.TamilCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.TamilCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import java.util.Locale; @@ -39,7 +39,7 @@ public final class TestsTamilLK extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class TamilLKCustomizer extends TamilCustomizer { - public TamilLKCustomizer(final Locale locale) { super(locale); } + TamilLKCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getCurrencyKey() { return CURRENCY_RUPEE; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTamilSG.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTamilSG.java index ade7abaf9..a7a041b61 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTamilSG.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTamilSG.java @@ -20,7 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Tamil; -import com.android.inputmethod.keyboard.layout.Tamil.TamilCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.TamilCustomizer; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTeluguIN.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTeluguIN.java index 04996d9aa..2b202a91d 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTeluguIN.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTeluguIN.java @@ -20,7 +20,6 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Telugu; -import com.android.inputmethod.keyboard.layout.Telugu.TeluguCustomizer; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public final class TestsTeluguIN extends LayoutTestsBase { private static final Locale LOCALE = new Locale("te", "IN"); - private static final LayoutBase LAYOUT = new Telugu(new TeluguCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Telugu(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsThai.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsThai.java index 3c8727290..2c1a29efc 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsThai.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsThai.java @@ -20,7 +20,6 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Thai; -import com.android.inputmethod.keyboard.layout.Thai.ThaiCustomizer; import java.util.Locale; @@ -30,7 +29,7 @@ import java.util.Locale; @SmallTest public final class TestsThai extends LayoutTestsBase { private static final Locale LOCALE = new Locale("th"); - private static final LayoutBase LAYOUT = new Thai(new ThaiCustomizer(LOCALE)); + private static final LayoutBase LAYOUT = new Thai(LOCALE); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTurkish.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTurkish.java index b35f8850a..95f86e461 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTurkish.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsTurkish.java @@ -19,8 +19,9 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.EuroCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.EuroCustomizer; +import com.android.inputmethod.keyboard.layout.customizer.TurkicCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; import java.util.Locale; @@ -37,50 +38,16 @@ public final class TestsTurkish extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class TurkishCustomizer extends EuroCustomizer { - public TurkishCustomizer(final Locale locale) { super(locale); } + private final TurkicCustomizer mTurkicCustomizer; + + TurkishCustomizer(final Locale locale) { + super(locale); + mTurkicCustomizer = new TurkicCustomizer(locale); + } @Override public ExpectedKeyboardBuilder setAccentedLetters(final ExpectedKeyboardBuilder builder) { - return builder - // U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS - // U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX - // U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE - // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE - // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON - .setMoreKeysOf("u", "\u00FC", "\u00FB", "\u00F9", "\u00FA", "\u016B") - // U+0131: "ı" LATIN SMALL LETTER DOTLESS I - // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX - // U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS - // U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE - // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE - // U+012F: "į" LATIN SMALL LETTER I WITH OGONEK - // U+012B: "ī" LATIN SMALL LETTER I WITH MACRON - .setMoreKeysOf("i", - "\u0131", "\u00EE", "\u00EF", "\u00EC", "\u00ED", "\u012F", "\u012B") - // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS - // U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX - // U+0153: "œ" LATIN SMALL LIGATURE OE - // U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE - // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE - // U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE - // U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE - // U+014D: "ō" LATIN SMALL LETTER O WITH MACRON - .setMoreKeysOf("o", - "\u00F6", "\u00F4", "\u0153", "\u00F2", "\u00F3", "\u00F5", "\u00F8", - "\u014D") - // U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX - .setMoreKeysOf("a", "\u00E2") - // U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA - // U+00DF: "ß" LATIN SMALL LETTER SHARP S - // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE - // U+0161: "š" LATIN SMALL LETTER S WITH CARON - .setMoreKeysOf("s", "\u015F", "\u00DF", "\u015B", "\u0161") - // U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE - .setMoreKeysOf("g", "\u011F") - // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA - // U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE - // U+010D: "č" LATIN SMALL LETTER C WITH CARON - .setMoreKeysOf("c", "\u00E7", "\u0107", "\u010D"); + return mTurkicCustomizer.setAccentedLetters(builder); } } } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUkrainian.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUkrainian.java index a6bcacc9e..da93d6c3b 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUkrainian.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUkrainian.java @@ -19,10 +19,10 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.EastSlavic; -import com.android.inputmethod.keyboard.layout.EastSlavic.EastSlavicCustomizer; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Symbols; import com.android.inputmethod.keyboard.layout.SymbolsShifted; +import com.android.inputmethod.keyboard.layout.customizer.EastSlavicCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -40,7 +40,7 @@ public final class TestsUkrainian extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class UkrainianCustomizer extends EastSlavicCustomizer { - public UkrainianCustomizer(final Locale locale) { super(locale); } + UkrainianCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getCurrencyKey() { return CURRENCY_HRYVNIA; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMyanmarMM.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUzbek.java index a0bd50c9a..fd12a6a82 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsMyanmarMM.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUzbek.java @@ -16,21 +16,21 @@ package com.android.inputmethod.keyboard.layout.tests; -import android.test.suitebuilder.annotation.Suppress; +import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.Myanmar; -import com.android.inputmethod.keyboard.layout.Myanmar.MyanmarCustomizer; +import com.android.inputmethod.keyboard.layout.Uzbek; +import com.android.inputmethod.keyboard.layout.customizer.UzbekCustomizer; import java.util.Locale; /** - * my_MM: Myanmar (Myanmar)/myanmar + * uz_UZ: Uzbek (Uzbekistan)/uzbek */ -@Suppress -public final class TestsMyanmarMM extends LayoutTestsBase { - private static final Locale LOCALE = new Locale("my", "MM"); - private static final LayoutBase LAYOUT = new Myanmar(new MyanmarCustomizer(LOCALE)); +@SmallTest +public final class TestsUzbek extends LayoutTestsBase { + private static final Locale LOCALE = new Locale("uz", "UZ"); + private static final LayoutBase LAYOUT = new Uzbek(new UzbekCustomizer(LOCALE)); @Override LayoutBase getLayout() { return LAYOUT; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUzbekQwerty.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUzbekQwerty.java new file mode 100644 index 000000000..4c33a8cc1 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsUzbekQwerty.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.keyboard.layout.tests; + +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.inputmethod.keyboard.layout.LayoutBase; +import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.UzbekCustomizer; +import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; + +import java.util.Locale; + +/** + * uz_UZ: Uzbek (Uzbekistan)/qwerty + */ +@SmallTest +public final class TestsUzbekQwerty extends LayoutTestsBase { + private static final Locale LOCALE = new Locale("uz", "UZ"); + private static final LayoutBase LAYOUT = new Qwerty(new UzbekQwertyCustomizer(LOCALE)); + + @Override + LayoutBase getLayout() { return LAYOUT; } + + private static class UzbekQwertyCustomizer extends UzbekCustomizer { + UzbekQwertyCustomizer(final Locale locale) { super(locale); } + + @Override + protected void setUzbekKeys(final ExpectedKeyboardBuilder builder) { + // QWERTY layout doesn't have Uzebk keys. + } + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsVietnamese.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsVietnamese.java index 83d86ac4d..356b04296 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsVietnamese.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsVietnamese.java @@ -19,10 +19,10 @@ package com.android.inputmethod.keyboard.layout.tests; import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; -import com.android.inputmethod.keyboard.layout.LayoutBase.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.Qwerty; import com.android.inputmethod.keyboard.layout.Symbols; import com.android.inputmethod.keyboard.layout.SymbolsShifted; +import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer; import com.android.inputmethod.keyboard.layout.expected.ExpectedKey; import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder; @@ -40,9 +40,7 @@ public final class TestsVietnamese extends LayoutTestsBase { LayoutBase getLayout() { return LAYOUT; } private static class VietnameseCustomizer extends LayoutCustomizer { - public VietnameseCustomizer(final Locale locale) { - super(locale); - } + VietnameseCustomizer(final Locale locale) { super(locale); } @Override public ExpectedKey getCurrencyKey() { return CURRENCY_DONG; } diff --git a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsZulu.java b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsZulu.java index e048e92c2..abf3cad9c 100644 --- a/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsZulu.java +++ b/tests/src/com/android/inputmethod/keyboard/layout/tests/TestsZulu.java @@ -20,6 +20,7 @@ import android.test.suitebuilder.annotation.SmallTest; import com.android.inputmethod.keyboard.layout.LayoutBase; import com.android.inputmethod.keyboard.layout.Qwerty; +import com.android.inputmethod.keyboard.layout.customizer.EnglishCustomizer; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java deleted file mode 100644 index ae184268c..000000000 --- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java +++ /dev/null @@ -1,692 +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.LargeTest; -import android.util.Pair; - -import com.android.inputmethod.latin.PrevWordsInfo.WordInfo; -import com.android.inputmethod.latin.makedict.BinaryDictIOUtils; -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.BinaryDictionaryUtils; -import com.android.inputmethod.latin.utils.FileUtils; -import com.android.inputmethod.latin.utils.LocaleUtils; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -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"; - private static final int DUMMY_PROBABILITY = 0; - private static final int[] DICT_FORMAT_VERSIONS = - new int[] { FormatSpec.VERSION4, FormatSpec.VERSION4_DEV }; - - private int mCurrentTime = 0; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mCurrentTime = 0; - } - - @Override - protected void tearDown() throws Exception { - stopTestModeInNativeCode(); - super.tearDown(); - } - - private static boolean supportsBeginningOfSentence(final int formatVersion) { - return formatVersion > FormatSpec.VERSION401; - } - - private void addUnigramWord(final BinaryDictionary binaryDictionary, final String word, - final int probability) { - binaryDictionary.addUnigramEntry(word, probability, "" /* shortcutTarget */, - BinaryDictionary.NOT_A_PROBABILITY /* shortcutProbability */, - false /* isBeginningOfSentence */, false /* isNotAWord */, - false /* isBlacklisted */, mCurrentTime /* timestamp */); - } - - private void addBigramWords(final BinaryDictionary binaryDictionary, final String word0, - final String word1, final int probability) { - binaryDictionary.addNgramEntry(new PrevWordsInfo(new WordInfo(word0)), word1, probability, - mCurrentTime /* timestamp */); - } - - private static boolean isValidBigram(final BinaryDictionary binaryDictionary, - final String word0, final String word1) { - return binaryDictionary.isValidNgram(new PrevWordsInfo(new WordInfo(word0)), word1); - } - - private void forcePassingShortTime(final BinaryDictionary binaryDictionary) { - // 30 days. - final int timeToElapse = (int)TimeUnit.SECONDS.convert(30, TimeUnit.DAYS); - mCurrentTime += timeToElapse; - setCurrentTimeForTestMode(mCurrentTime); - binaryDictionary.flushWithGC(); - } - - private void forcePassingLongTime(final BinaryDictionary binaryDictionary) { - // 365 days. - final int timeToElapse = (int)TimeUnit.SECONDS.convert(365, TimeUnit.DAYS); - mCurrentTime += timeToElapse; - setCurrentTimeForTestMode(mCurrentTime); - binaryDictionary.flushWithGC(); - } - - private File createEmptyDictionaryAndGetFile(final String dictId, - final int formatVersion) throws IOException { - if (formatVersion == FormatSpec.VERSION4 - || formatVersion == FormatSpec.VERSION4_ONLY_FOR_TESTING - || formatVersion == FormatSpec.VERSION4_DEV) { - return createEmptyVer4DictionaryAndGetFile(dictId, formatVersion); - } else { - throw new IOException("Dictionary format version " + formatVersion - + " is not supported."); - } - } - - private File createEmptyVer4DictionaryAndGetFile(final String dictId, final int formatVersion) - throws IOException { - final File file = File.createTempFile(dictId, TEST_DICT_FILE_EXTENSION, - getContext().getCacheDir()); - FileUtils.deleteRecursively(file); - Map<String, String> attributeMap = new HashMap<>(); - 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 (BinaryDictionaryUtils.createEmptyDictFile(file.getAbsolutePath(), formatVersion, - LocaleUtils.constructLocaleFromString(TEST_LOCALE), attributeMap)) { - return file; - } else { - throw new IOException("Empty dictionary " + file.getAbsolutePath() - + " cannot be created. Foramt version: " + formatVersion); - } - } - - private static int setCurrentTimeForTestMode(final int currentTime) { - return BinaryDictionaryUtils.setCurrentTimeForTest(currentTime); - } - - private static int stopTestModeInNativeCode() { - return BinaryDictionaryUtils.setCurrentTimeForTest(-1); - } - - public void testReadDictInJavaSide() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testReadDictInJavaSide(formatVersion); - } - } - - 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 = - BinaryDictIOUtils.getDictDecoder(dictFile, 0, dictFile.length()); - 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() { - 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() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddValidAndInvalidWords(formatVersion); - } - } - - private void testAddValidAndInvalidWords(final int formatVersion) { - 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", Dictionary.NOT_A_PROBABILITY); - assertFalse(binaryDictionary.isValidWord("a")); - addUnigramWord(binaryDictionary, "a", Dictionary.NOT_A_PROBABILITY); - addUnigramWord(binaryDictionary, "a", Dictionary.NOT_A_PROBABILITY); - assertTrue(binaryDictionary.isValidWord("a")); - - addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY); - assertTrue(binaryDictionary.isValidWord("b")); - - addBigramWords(binaryDictionary, "a", "b", Dictionary.NOT_A_PROBABILITY); - assertFalse(isValidBigram(binaryDictionary, "a", "b")); - addBigramWords(binaryDictionary, "a", "b", Dictionary.NOT_A_PROBABILITY); - assertTrue(isValidBigram(binaryDictionary, "a", "b")); - - addUnigramWord(binaryDictionary, "c", DUMMY_PROBABILITY); - addBigramWords(binaryDictionary, "a", "c", DUMMY_PROBABILITY); - assertTrue(isValidBigram(binaryDictionary, "a", "c")); - - // Add bigrams of not valid unigrams. - addBigramWords(binaryDictionary, "x", "y", Dictionary.NOT_A_PROBABILITY); - assertFalse(isValidBigram(binaryDictionary, "x", "y")); - addBigramWords(binaryDictionary, "x", "y", DUMMY_PROBABILITY); - assertFalse(isValidBigram(binaryDictionary, "x", "y")); - - binaryDictionary.close(); - dictFile.delete(); - } - - public void testDecayingProbability() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testDecayingProbability(formatVersion); - } - } - - private void testDecayingProbability(final int formatVersion) { - 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); - assertTrue(binaryDictionary.isValidWord("a")); - forcePassingShortTime(binaryDictionary); - assertFalse(binaryDictionary.isValidWord("a")); - - 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")); - - addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY); - addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY); - addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY); - assertTrue(isValidBigram(binaryDictionary, "a", "b")); - forcePassingShortTime(binaryDictionary); - assertFalse(isValidBigram(binaryDictionary, "a", "b")); - - 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(isValidBigram(binaryDictionary, "a", "b")); - forcePassingShortTime(binaryDictionary); - assertTrue(isValidBigram(binaryDictionary, "a", "b")); - forcePassingLongTime(binaryDictionary); - assertFalse(isValidBigram(binaryDictionary, "a", "b")); - - binaryDictionary.close(); - dictFile.delete(); - } - - public void testAddManyUnigramsToDecayingDict() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddManyUnigramsToDecayingDict(formatVersion); - } - } - - private void testAddManyUnigramsToDecayingDict(final int formatVersion) { - final int unigramCount = 30000; - final int unigramTypedCount = 100000; - 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<>(); - - for (int i = 0; i < unigramCount; i++) { - final String word = CodePointUtils.generateWord(random, codePointSet); - words.add(word); - } - - final int maxUnigramCount = Integer.parseInt( - binaryDictionary.getPropertyForTest(BinaryDictionary.MAX_UNIGRAM_COUNT_QUERY)); - for (int i = 0; i < unigramTypedCount; i++) { - final String word = words.get(random.nextInt(words.size())); - addUnigramWord(binaryDictionary, word, DUMMY_PROBABILITY); - - if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { - final int unigramCountBeforeGC = - Integer.parseInt(binaryDictionary.getPropertyForTest( - BinaryDictionary.UNIGRAM_COUNT_QUERY)); - while (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { - forcePassingShortTime(binaryDictionary); - } - final int unigramCountAfterGC = - Integer.parseInt(binaryDictionary.getPropertyForTest( - BinaryDictionary.UNIGRAM_COUNT_QUERY)); - assertTrue(unigramCountBeforeGC > unigramCountAfterGC); - } - } - - assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTest( - BinaryDictionary.UNIGRAM_COUNT_QUERY)) > 0); - 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() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testOverflowUnigrams(formatVersion); - } - } - - private void testOverflowUnigrams(final int formatVersion) { - final int unigramCount = 20000; - final int eachUnigramTypedCount = 2; - 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() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddManyBigramsToDecayingDict(formatVersion); - } - } - - private void testAddManyBigramsToDecayingDict(final int formatVersion) { - final int unigramCount = 5000; - final int bigramCount = 30000; - final int bigramTypedCount = 100000; - 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<>(); - final ArrayList<Pair<String, String>> bigrams = new ArrayList<>(); - - for (int i = 0; i < unigramCount; ++i) { - final String word = CodePointUtils.generateWord(random, codePointSet); - words.add(word); - } - for (int i = 0; i < bigramCount; ++i) { - final int word0Index = random.nextInt(words.size()); - int word1Index = random.nextInt(words.size() - 1); - if (word1Index >= word0Index) { - word1Index += 1; - } - final String word0 = words.get(word0Index); - final String word1 = words.get(word1Index); - final Pair<String, String> bigram = new Pair<>(word0, word1); - bigrams.add(bigram); - } - - final int maxBigramCount = Integer.parseInt( - 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())); - 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.getPropertyForTest( - BinaryDictionary.BIGRAM_COUNT_QUERY)); - while (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { - forcePassingShortTime(binaryDictionary); - } - final int bigramCountAfterGC = - Integer.parseInt(binaryDictionary.getPropertyForTest( - BinaryDictionary.BIGRAM_COUNT_QUERY)); - assertTrue(bigramCountBeforeGC > bigramCountAfterGC); - } - } - - assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTest( - BinaryDictionary.BIGRAM_COUNT_QUERY)) > 0); - 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() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testOverflowBigrams(formatVersion); - } - } - - private void testOverflowBigrams(final int formatVersion) { - final int bigramCount = 20000; - final int unigramCount = 1000; - final int unigramTypedCount = 20; - final int eachBigramTypedCount = 2; - 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<>(); - 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(isValidBigram(binaryDictionary, strong, target)); - assertTrue(isValidBigram(binaryDictionary, 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(isValidBigram(binaryDictionary, strong, target)); - assertFalse(isValidBigram(binaryDictionary, weak, target)); - break; - } - } - } - - public void testDictMigration() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testDictMigration(FormatSpec.VERSION4_ONLY_FOR_TESTING, formatVersion); - } - } - - private void testDictMigration(final int fromFormatVersion, final int toFormatVersion) { - setCurrentTimeForTestMode(mCurrentTime); - File dictFile = null; - try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", fromFormatVersion); - } 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 */); - addUnigramWord(binaryDictionary, "aaa", DUMMY_PROBABILITY); - assertTrue(binaryDictionary.isValidWord("aaa")); - addUnigramWord(binaryDictionary, "bbb", Dictionary.NOT_A_PROBABILITY); - assertFalse(binaryDictionary.isValidWord("bbb")); - addUnigramWord(binaryDictionary, "ccc", DUMMY_PROBABILITY); - addUnigramWord(binaryDictionary, "ccc", DUMMY_PROBABILITY); - addUnigramWord(binaryDictionary, "ccc", DUMMY_PROBABILITY); - addUnigramWord(binaryDictionary, "ccc", DUMMY_PROBABILITY); - addUnigramWord(binaryDictionary, "ccc", DUMMY_PROBABILITY); - addUnigramWord(binaryDictionary, "abc", DUMMY_PROBABILITY); - addBigramWords(binaryDictionary, "aaa", "abc", DUMMY_PROBABILITY); - assertTrue(isValidBigram(binaryDictionary, "aaa", "abc")); - addBigramWords(binaryDictionary, "aaa", "bbb", Dictionary.NOT_A_PROBABILITY); - assertFalse(isValidBigram(binaryDictionary, "aaa", "bbb")); - - assertEquals(fromFormatVersion, binaryDictionary.getFormatVersion()); - assertTrue(binaryDictionary.migrateTo(toFormatVersion)); - assertTrue(binaryDictionary.isValidDictionary()); - assertEquals(toFormatVersion, binaryDictionary.getFormatVersion()); - assertTrue(binaryDictionary.isValidWord("aaa")); - assertFalse(binaryDictionary.isValidWord("bbb")); - assertTrue(binaryDictionary.getFrequency("aaa") < binaryDictionary.getFrequency("ccc")); - addUnigramWord(binaryDictionary, "bbb", Dictionary.NOT_A_PROBABILITY); - assertTrue(binaryDictionary.isValidWord("bbb")); - assertTrue(isValidBigram(binaryDictionary, "aaa", "abc")); - assertFalse(isValidBigram(binaryDictionary, "aaa", "bbb")); - addBigramWords(binaryDictionary, "aaa", "bbb", Dictionary.NOT_A_PROBABILITY); - assertTrue(isValidBigram(binaryDictionary, "aaa", "bbb")); - binaryDictionary.close(); - dictFile.delete(); - } - - public void testBeginningOfSentence() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - if (supportsBeginningOfSentence(formatVersion)) { - testBeginningOfSentence(formatVersion); - } - } - } - - private void testBeginningOfSentence(final int formatVersion) { - setCurrentTimeForTestMode(mCurrentTime); - 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 */); - - binaryDictionary.addUnigramEntry("", DUMMY_PROBABILITY, "" /* shortcutTarget */, - BinaryDictionary.NOT_A_PROBABILITY /* shortcutProbability */, - true /* isBeginningOfSentence */, true /* isNotAWord */, false /* isBlacklisted */, - mCurrentTime); - final PrevWordsInfo prevWordsInfoStartOfSentence = PrevWordsInfo.BEGINNING_OF_SENTENCE; - addUnigramWord(binaryDictionary, "aaa", DUMMY_PROBABILITY); - binaryDictionary.addNgramEntry(prevWordsInfoStartOfSentence, "aaa", DUMMY_PROBABILITY, - mCurrentTime); - assertTrue(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "aaa")); - binaryDictionary.addNgramEntry(prevWordsInfoStartOfSentence, "aaa", DUMMY_PROBABILITY, - mCurrentTime); - addUnigramWord(binaryDictionary, "bbb", DUMMY_PROBABILITY); - binaryDictionary.addNgramEntry(prevWordsInfoStartOfSentence, "bbb", DUMMY_PROBABILITY, - mCurrentTime); - assertTrue(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "aaa")); - assertTrue(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "bbb")); - - forcePassingLongTime(binaryDictionary); - assertFalse(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "aaa")); - assertFalse(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "bbb")); - - addUnigramWord(binaryDictionary, "aaa", DUMMY_PROBABILITY); - binaryDictionary.addNgramEntry(prevWordsInfoStartOfSentence, "aaa", DUMMY_PROBABILITY, - mCurrentTime); - addUnigramWord(binaryDictionary, "bbb", DUMMY_PROBABILITY); - binaryDictionary.addNgramEntry(prevWordsInfoStartOfSentence, "bbb", DUMMY_PROBABILITY, - mCurrentTime); - assertTrue(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "aaa")); - assertTrue(binaryDictionary.isValidNgram(prevWordsInfoStartOfSentence, "bbb")); - binaryDictionary.close(); - dictFile.delete(); - } -} diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java index 6ba18d665..e96c934cb 100644 --- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java +++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java @@ -21,14 +21,14 @@ import android.test.suitebuilder.annotation.LargeTest; import android.text.TextUtils; import android.util.Pair; -import com.android.inputmethod.latin.PrevWordsInfo.WordInfo; -import com.android.inputmethod.latin.makedict.CodePointUtils; +import com.android.inputmethod.latin.NgramContext.WordInfo; +import com.android.inputmethod.latin.common.CodePointUtils; +import com.android.inputmethod.latin.common.FileUtils; +import com.android.inputmethod.latin.makedict.DictionaryHeader; import com.android.inputmethod.latin.makedict.FormatSpec; import com.android.inputmethod.latin.makedict.WeightedString; import com.android.inputmethod.latin.makedict.WordProperty; import com.android.inputmethod.latin.utils.BinaryDictionaryUtils; -import com.android.inputmethod.latin.utils.FileUtils; -import com.android.inputmethod.latin.utils.LanguageModelParam; import java.io.File; import java.io.IOException; @@ -36,103 +36,100 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; 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"; - private static final int[] DICT_FORMAT_VERSIONS = - new int[] { FormatSpec.VERSION4, FormatSpec.VERSION4_DEV }; + private static final String DICTIONARY_ID = "TestBinaryDictionary"; - private static boolean canCheckBigramProbability(final int formatVersion) { - return formatVersion > FormatSpec.VERSION401; + private HashSet<File> mDictFilesToBeDeleted = new HashSet<>(); + + @Override + protected void setUp() throws Exception { + super.setUp(); + mDictFilesToBeDeleted.clear(); + } + + @Override + protected void tearDown() throws Exception { + for (final File dictFile : mDictFilesToBeDeleted) { + dictFile.delete(); + } + mDictFilesToBeDeleted.clear(); + super.tearDown(); } - private static boolean supportsBeginningOfSentence(final int formatVersion) { - return formatVersion > FormatSpec.VERSION401; + private File createEmptyDictionaryAndGetFile(final int formatVersion) { + return createEmptyDictionaryWithAttributesAndGetFile(formatVersion, + new HashMap<String, String>()); } - private File createEmptyDictionaryAndGetFile(final String dictId, - final int formatVersion) throws IOException { - if (formatVersion == FormatSpec.VERSION4 - || formatVersion == FormatSpec.VERSION4_ONLY_FOR_TESTING - || formatVersion == FormatSpec.VERSION4_DEV) { - return createEmptyVer4DictionaryAndGetFile(dictId, formatVersion); - } else { - throw new IOException("Dictionary format version " + formatVersion - + " is not supported."); + private File createEmptyDictionaryWithAttributesAndGetFile(final int formatVersion, + final HashMap<String, String> attributeMap) { + try { + final File dictFile = createEmptyVer4DictionaryAndGetFile(formatVersion, + attributeMap); + mDictFilesToBeDeleted.add(dictFile); + return dictFile; + } catch (final IOException e) { + fail(e.toString()); } + return null; } - private File createEmptyVer4DictionaryAndGetFile(final String dictId, - final int formatVersion) throws IOException { - final File file = File.createTempFile(dictId, TEST_DICT_FILE_EXTENSION, + private File createEmptyVer4DictionaryAndGetFile(final int formatVersion, + final HashMap<String, String> attributeMap) throws IOException { + final File file = File.createTempFile(DICTIONARY_ID, TEST_DICT_FILE_EXTENSION, getContext().getCacheDir()); file.delete(); file.mkdir(); - Map<String, String> attributeMap = new HashMap<>(); if (BinaryDictionaryUtils.createEmptyDictFile(file.getAbsolutePath(), formatVersion, Locale.ENGLISH, attributeMap)) { return file; - } else { - throw new IOException("Empty dictionary " + file.getAbsolutePath() - + " cannot be created. Format version: " + formatVersion); } + throw new IOException("Empty dictionary " + file.getAbsolutePath() + + " cannot be created. Format version: " + formatVersion); } - public void testIsValidDictionary() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testIsValidDictionary(formatVersion); - } + private static BinaryDictionary getBinaryDictionary(final File dictFile) { + return new BinaryDictionary(dictFile.getAbsolutePath(), + 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, + Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); } - private void testIsValidDictionary(final int formatVersion) { - 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(), + private BinaryDictionary getEmptyBinaryDictionary(final int formatVersion) { + final File dictFile = createEmptyDictionaryAndGetFile(formatVersion); + return new BinaryDictionary(dictFile.getAbsolutePath(), 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + } + + public void testIsValidDictionary() { + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); + BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); assertTrue("binaryDictionary must be valid for existing valid dictionary file.", binaryDictionary.isValidDictionary()); binaryDictionary.close(); assertFalse("binaryDictionary must be invalid after closing.", binaryDictionary.isValidDictionary()); FileUtils.deleteRecursively(dictFile); - binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), 0 /* offset */, - dictFile.length(), true /* useFullEditDistance */, Locale.getDefault(), - TEST_LOCALE, true /* isUpdatable */); + binaryDictionary = getBinaryDictionary(dictFile); assertFalse("binaryDictionary must be invalid for not existing dictionary file.", binaryDictionary.isValidDictionary()); binaryDictionary.close(); } public void testConstructingDictionaryOnMemory() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testConstructingDictionaryOnMemory(formatVersion); - } - } - - private void testConstructingDictionaryOnMemory(final int formatVersion) { - File dictFile = null; - try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); - } catch (IOException e) { - fail("IOException while writing an initial dictionary : " + e); - } + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); FileUtils.deleteRecursively(dictFile); assertFalse(dictFile.exists()); - BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), - true /* useFullEditDistance */, Locale.getDefault(), TEST_LOCALE, formatVersion, - new HashMap<String, String>()); + final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), + true /* useFullEditDistance */, Locale.getDefault(), TEST_LOCALE, + FormatSpec.VERSION403, new HashMap<String, String>()); assertTrue(binaryDictionary.isValidDictionary()); - assertEquals(formatVersion, binaryDictionary.getFormatVersion()); + assertEquals(FormatSpec.VERSION403, binaryDictionary.getFormatVersion()); final int probability = 100; addUnigramWord(binaryDictionary, "word", probability); assertEquals(probability, binaryDictionary.getFrequency("word")); @@ -140,31 +137,15 @@ public class BinaryDictionaryTests extends AndroidTestCase { binaryDictionary.flush(); assertTrue(dictFile.exists()); assertTrue(binaryDictionary.isValidDictionary()); - assertEquals(formatVersion, binaryDictionary.getFormatVersion()); + assertEquals(FormatSpec.VERSION403, binaryDictionary.getFormatVersion()); assertEquals(probability, binaryDictionary.getFrequency("word")); binaryDictionary.close(); - dictFile.delete(); } public void testAddTooLongWord() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddTooLongWord(formatVersion); - } - } - - 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 BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final StringBuffer stringBuilder = new StringBuffer(); - for (int i = 0; i < Constants.DICTIONARY_MAX_WORD_LENGTH; i++) { + for (int i = 0; i < BinaryDictionary.DICTIONARY_MAX_WORD_LENGTH; i++) { stringBuilder.append('a'); } final String validLongWord = stringBuilder.toString(); @@ -175,9 +156,8 @@ public class BinaryDictionaryTests extends AndroidTestCase { addUnigramWord(binaryDictionary, validLongWord, probability); addUnigramWord(binaryDictionary, invalidLongWord, probability); // Too long short cut. - binaryDictionary.addUnigramEntry("a", probability, invalidLongWord, - 10 /* shortcutProbability */, false /* isBeginningOfSentence */, - false /* isNotAWord */, false /* isBlacklisted */, + binaryDictionary.addUnigramEntry("a", probability, false /* isBeginningOfSentence */, + false /* isNotAWord */, false /* isPossiblyOffensive */, BinaryDictionary.NOT_A_VALID_TIMESTAMP); addUnigramWord(binaryDictionary, "abc", probability); final int updatedProbability = 200; @@ -188,58 +168,49 @@ public class BinaryDictionaryTests extends AndroidTestCase { assertEquals(probability, binaryDictionary.getFrequency("aaa")); assertEquals(updatedProbability, binaryDictionary.getFrequency(validLongWord)); - assertEquals(BinaryDictionary.NOT_A_PROBABILITY, - binaryDictionary.getFrequency(invalidLongWord)); + assertEquals(Dictionary.NOT_A_PROBABILITY, binaryDictionary.getFrequency(invalidLongWord)); assertEquals(updatedProbability, binaryDictionary.getFrequency("abc")); - dictFile.delete(); } private static void addUnigramWord(final BinaryDictionary binaryDictionary, final String word, final int probability) { - binaryDictionary.addUnigramEntry(word, probability, "" /* shortcutTarget */, - BinaryDictionary.NOT_A_PROBABILITY /* shortcutProbability */, + binaryDictionary.addUnigramEntry(word, probability, false /* isBeginningOfSentence */, false /* isNotAWord */, - false /* isBlacklisted */, BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); + false /* isPossiblyOffensive */, + BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); } private static void addBigramWords(final BinaryDictionary binaryDictionary, final String word0, final String word1, final int probability) { - binaryDictionary.addNgramEntry(new PrevWordsInfo(new WordInfo(word0)), word1, probability, + binaryDictionary.addNgramEntry(new NgramContext(new WordInfo(word0)), word1, probability, BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); } - private static boolean isValidBigram(final BinaryDictionary binaryDictionary, - final String word0, final String word1) { - return binaryDictionary.isValidNgram(new PrevWordsInfo(new WordInfo(word0)), word1); + private static void addTrigramEntry(final BinaryDictionary binaryDictionary, final String word0, + final String word1, final String word2, final int probability) { + binaryDictionary.addNgramEntry( + new NgramContext(new WordInfo(word1), new WordInfo(word0)), word2, + probability, BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); } - private static void removeBigramEntry(final BinaryDictionary binaryDictionary, + private static boolean isValidBigram(final BinaryDictionary binaryDictionary, final String word0, final String word1) { - binaryDictionary.removeNgramEntry(new PrevWordsInfo(new WordInfo(word0)), word1); + return binaryDictionary.isValidNgram(new NgramContext(new WordInfo(word0)), word1); } private static int getBigramProbability(final BinaryDictionary binaryDictionary, final String word0, final String word1) { - return binaryDictionary.getNgramProbability(new PrevWordsInfo(new WordInfo(word0)), word1); + return binaryDictionary.getNgramProbability(new NgramContext(new WordInfo(word0)), word1); } - public void testAddUnigramWord() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddUnigramWord(formatVersion); - } + private static int getTrigramProbability(final BinaryDictionary binaryDictionary, + final String word0, final String word1, final String word2) { + return binaryDictionary.getNgramProbability( + new NgramContext(new WordInfo(word1), new WordInfo(word0)), word2); } - private void testAddUnigramWord(final int formatVersion) { - 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 */); - + public void testAddUnigramWord() { + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final int probability = 100; addUnigramWord(binaryDictionary, "aaa", probability); // Reallocate and create. @@ -263,30 +234,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { assertEquals(probability, binaryDictionary.getFrequency("aaaa")); assertEquals(probability, binaryDictionary.getFrequency("a")); assertEquals(updatedProbability, binaryDictionary.getFrequency("aaa")); - - dictFile.delete(); } public void testRandomlyAddUnigramWord() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testRandomlyAddUnigramWord(formatVersion); - } - } - - 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", 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 */); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final HashMap<String, Integer> probabilityMap = new HashMap<>(); // Test a word that isn't contained within the dictionary. @@ -302,25 +256,10 @@ public class BinaryDictionaryTests extends AndroidTestCase { for (String word : probabilityMap.keySet()) { assertEquals(word, (int)probabilityMap.get(word), binaryDictionary.getFrequency(word)); } - dictFile.delete(); } public void testAddBigramWords() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddBigramWords(formatVersion); - } - } - - private void testAddBigramWords(final int formatVersion) { - 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 */); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final int unigramProbability = 100; final int bigramProbability = 150; @@ -337,18 +276,14 @@ public class BinaryDictionaryTests extends AndroidTestCase { assertTrue(isValidBigram(binaryDictionary, "aaa", "bcc")); assertTrue(isValidBigram(binaryDictionary, "abb", "aaa")); assertTrue(isValidBigram(binaryDictionary, "abb", "bcc")); - if (canCheckBigramProbability(formatVersion)) { - assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "abb")); - assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "bcc")); - assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "aaa")); - assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "bcc")); - } + assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "abb")); + assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "bcc")); + assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "aaa")); + assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "bcc")); addBigramWords(binaryDictionary, "aaa", "abb", updatedBigramProbability); - if (canCheckBigramProbability(formatVersion)) { - assertEquals(updatedBigramProbability, - getBigramProbability(binaryDictionary, "aaa", "abb")); - } + assertEquals(updatedBigramProbability, + getBigramProbability(binaryDictionary, "aaa", "abb")); assertFalse(isValidBigram(binaryDictionary, "bcc", "aaa")); assertFalse(isValidBigram(binaryDictionary, "bcc", "bbc")); @@ -368,43 +303,21 @@ public class BinaryDictionaryTests extends AndroidTestCase { addUnigramWord(binaryDictionary, "abc", unigramProbability); addUnigramWord(binaryDictionary, "f", unigramProbability); - if (canCheckBigramProbability(formatVersion)) { - assertEquals(bigramProbability, - getBigramProbability(binaryDictionary, "abcde", "fghij")); - } + assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abcde", "fghij")); assertEquals(Dictionary.NOT_A_PROBABILITY, getBigramProbability(binaryDictionary, "abcde", "fgh")); addBigramWords(binaryDictionary, "abcde", "fghij", updatedBigramProbability); - if (canCheckBigramProbability(formatVersion)) { - assertEquals(updatedBigramProbability, - getBigramProbability(binaryDictionary, "abcde", "fghij")); - } - - dictFile.delete(); + assertEquals(updatedBigramProbability, + getBigramProbability(binaryDictionary, "abcde", "fghij")); } public void testRandomlyAddBigramWords() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testRandomlyAddBigramWords(formatVersion); - } - } - - private void testRandomlyAddBigramWords(final int formatVersion) { final int wordCount = 100; final int bigramCount = 1000; 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 */); + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final ArrayList<String> words = new ArrayList<>(); final ArrayList<Pair<String, String>> bigramWords = new ArrayList<>(); @@ -439,83 +352,40 @@ public class BinaryDictionaryTests extends AndroidTestCase { final int bigramProbability = bigramProbabilities.get(bigram); assertEquals(bigramProbability != Dictionary.NOT_A_PROBABILITY, isValidBigram(binaryDictionary, bigram.first, bigram.second)); - if (canCheckBigramProbability(formatVersion)) { - assertEquals(bigramProbability, - getBigramProbability(binaryDictionary, bigram.first, bigram.second)); - } - } - - dictFile.delete(); - } - - public void testRemoveBigramWords() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testRemoveBigramWords(formatVersion); + assertEquals(bigramProbability, + getBigramProbability(binaryDictionary, bigram.first, bigram.second)); } } - private void testRemoveBigramWords(final int formatVersion) { - 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 */); + public void testAddTrigramWords() { + final BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final int unigramProbability = 100; - final int bigramProbability = 150; + final int trigramProbability = 150; + final int updatedTrigramProbability = 200; 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); - - assertTrue(isValidBigram(binaryDictionary, "aaa", "abb")); - assertTrue(isValidBigram(binaryDictionary, "aaa", "bcc")); - assertTrue(isValidBigram(binaryDictionary, "abb", "aaa")); - assertTrue(isValidBigram(binaryDictionary, "abb", "bcc")); - - removeBigramEntry(binaryDictionary, "aaa", "abb"); - assertFalse(isValidBigram(binaryDictionary, "aaa", "abb")); - addBigramWords(binaryDictionary, "aaa", "abb", bigramProbability); - assertTrue(isValidBigram(binaryDictionary, "aaa", "abb")); + addBigramWords(binaryDictionary, "abb", "bcc", 10); + addBigramWords(binaryDictionary, "abb", "aaa", 10); - removeBigramEntry(binaryDictionary, "aaa", "bcc"); - assertFalse(isValidBigram(binaryDictionary, "aaa", "bcc")); - removeBigramEntry(binaryDictionary, "abb", "aaa"); - assertFalse(isValidBigram(binaryDictionary, "abb", "aaa")); - removeBigramEntry(binaryDictionary, "abb", "bcc"); - assertFalse(isValidBigram(binaryDictionary, "abb", "bcc")); + addTrigramEntry(binaryDictionary, "aaa", "abb", "bcc", trigramProbability); + addTrigramEntry(binaryDictionary, "bcc", "abb", "aaa", trigramProbability); - removeBigramEntry(binaryDictionary, "aaa", "abb"); - // Test remove non-existing bigram operation. - removeBigramEntry(binaryDictionary, "aaa", "abb"); - removeBigramEntry(binaryDictionary, "bcc", "aaa"); + assertEquals(trigramProbability, + getTrigramProbability(binaryDictionary, "aaa", "abb", "bcc")); + assertEquals(trigramProbability, + getTrigramProbability(binaryDictionary, "bcc", "abb", "aaa")); + assertFalse(isValidBigram(binaryDictionary, "aaa", "abb")); - dictFile.delete(); + addTrigramEntry(binaryDictionary, "bcc", "abb", "aaa", updatedTrigramProbability); + assertEquals(updatedTrigramProbability, + getTrigramProbability(binaryDictionary, "bcc", "abb", "aaa")); } public void testFlushDictionary() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testFlushDictionary(formatVersion); - } - } - - private void testFlushDictionary(final int formatVersion) { - 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 */); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); + BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); final int probability = 100; addUnigramWord(binaryDictionary, "aaa", probability); @@ -535,42 +405,21 @@ public class BinaryDictionaryTests extends AndroidTestCase { binaryDictionary.flush(); binaryDictionary.close(); - binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), - 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, - Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); - + binaryDictionary = getBinaryDictionary(dictFile); assertEquals(probability, binaryDictionary.getFrequency("aaa")); assertEquals(probability, binaryDictionary.getFrequency("abcd")); addUnigramWord(binaryDictionary, "bcde", probability); binaryDictionary.flush(); binaryDictionary.close(); - binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), - 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, - Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + binaryDictionary = getBinaryDictionary(dictFile); assertEquals(probability, binaryDictionary.getFrequency("bcde")); binaryDictionary.close(); - - dictFile.delete(); } public void testFlushWithGCDictionary() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testFlushWithGCDictionary(formatVersion); - } - } - - private void testFlushWithGCDictionary(final int formatVersion) { - 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 */); - + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); + BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); final int unigramProbability = 100; final int bigramProbability = 150; addUnigramWord(binaryDictionary, "aaa", unigramProbability); @@ -583,51 +432,30 @@ public class BinaryDictionaryTests extends AndroidTestCase { binaryDictionary.flushWithGC(); binaryDictionary.close(); - binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), - 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, - Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + binaryDictionary = getBinaryDictionary(dictFile); assertEquals(unigramProbability, binaryDictionary.getFrequency("aaa")); assertEquals(unigramProbability, binaryDictionary.getFrequency("abb")); assertEquals(unigramProbability, binaryDictionary.getFrequency("bcc")); - if (canCheckBigramProbability(formatVersion)) { - assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "abb")); - assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "bcc")); - assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "aaa")); - assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "bcc")); - } + assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "abb")); + assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "bcc")); + assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "aaa")); + assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "abb", "bcc")); assertFalse(isValidBigram(binaryDictionary, "bcc", "aaa")); assertFalse(isValidBigram(binaryDictionary, "bcc", "bbc")); assertFalse(isValidBigram(binaryDictionary, "aaa", "aaa")); binaryDictionary.flushWithGC(); binaryDictionary.close(); - - dictFile.delete(); } public void testAddBigramWordsAndFlashWithGC() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddBigramWordsAndFlashWithGC(formatVersion); - } - } - - // TODO: Evaluate performance of GC - private void testAddBigramWordsAndFlashWithGC(final int formatVersion) { final int wordCount = 100; final int bigramCount = 1000; final int codePointSetSize = 30; 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 */); + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); + BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); final ArrayList<String> words = new ArrayList<>(); final ArrayList<Pair<String, String>> bigramWords = new ArrayList<>(); @@ -660,52 +488,37 @@ public class BinaryDictionaryTests extends AndroidTestCase { binaryDictionary.flushWithGC(); binaryDictionary.close(); - binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), - 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, - Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); - + binaryDictionary = getBinaryDictionary(dictFile); for (final Pair<String, String> bigram : bigramWords) { final int bigramProbability = bigramProbabilities.get(bigram); assertEquals(bigramProbability != Dictionary.NOT_A_PROBABILITY, isValidBigram(binaryDictionary, bigram.first, bigram.second)); - if (canCheckBigramProbability(formatVersion)) { - assertEquals(bigramProbability, - getBigramProbability(binaryDictionary, bigram.first, bigram.second)); - } + assertEquals(bigramProbability, + getBigramProbability(binaryDictionary, bigram.first, bigram.second)); } - - dictFile.delete(); } public void testRandomOperationsAndFlashWithGC() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testRandomOperationsAndFlashWithGC(formatVersion); - } - } + final int maxUnigramCount = 5000; + final int maxBigramCount = 10000; + final HashMap<String, String> attributeMap = new HashMap<>(); + attributeMap.put(DictionaryHeader.MAX_UNIGRAM_COUNT_KEY, String.valueOf(maxUnigramCount)); + attributeMap.put(DictionaryHeader.MAX_BIGRAM_COUNT_KEY, String.valueOf(maxBigramCount)); - private void testRandomOperationsAndFlashWithGC(final int formatVersion) { final int flashWithGCIterationCount = 50; final int operationCountInEachIteration = 200; final int initialUnigramCount = 100; final float addUnigramProb = 0.5f; final float addBigramProb = 0.8f; - final float removeBigramProb = 0.2f; final int codePointSetSize = 30; final long seed = System.currentTimeMillis(); final Random random = new Random(seed); + final File dictFile = createEmptyDictionaryWithAttributesAndGetFile(FormatSpec.VERSION403, + attributeMap); + BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); - 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 */); final ArrayList<String> words = new ArrayList<>(); final ArrayList<Pair<String, String>> bigramWords = new ArrayList<>(); final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); @@ -722,9 +535,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { binaryDictionary.close(); for (int gcCount = 0; gcCount < flashWithGCIterationCount; gcCount++) { - binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), - 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, - Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + binaryDictionary = getBinaryDictionary(dictFile); for (int opCount = 0; opCount < operationCountInEachIteration; opCount++) { // Add unigram. if (random.nextFloat() < addUnigramProb) { @@ -754,14 +565,6 @@ public class BinaryDictionaryTests extends AndroidTestCase { bigramProbabilities.put(bigram, bigramProbability); addBigramWords(binaryDictionary, word0, word1, bigramProbability); } - // Remove bigram. - if (random.nextFloat() < removeBigramProb && !bigramWords.isEmpty()) { - final int bigramIndex = random.nextInt(bigramWords.size()); - final Pair<String, String> bigram = bigramWords.get(bigramIndex); - bigramWords.remove(bigramIndex); - bigramProbabilities.remove(bigram); - removeBigramEntry(binaryDictionary, bigram.first, bigram.second); - } } // Test whether the all unigram operations are collectlly handled. @@ -775,45 +578,29 @@ public class BinaryDictionaryTests extends AndroidTestCase { final Pair<String, String> bigram = bigramWords.get(i); final int probability; if (bigramProbabilities.containsKey(bigram)) { - final int bigramProbability = bigramProbabilities.get(bigram); - probability = bigramProbability; + probability = bigramProbabilities.get(bigram); } else { probability = Dictionary.NOT_A_PROBABILITY; } - if (canCheckBigramProbability(formatVersion)) { - assertEquals(probability, - getBigramProbability(binaryDictionary, bigram.first, bigram.second)); - } + assertEquals(probability, + getBigramProbability(binaryDictionary, bigram.first, bigram.second)); assertEquals(probability != Dictionary.NOT_A_PROBABILITY, isValidBigram(binaryDictionary, bigram.first, bigram.second)); } binaryDictionary.flushWithGC(); binaryDictionary.close(); } - - dictFile.delete(); } public void testAddManyUnigramsAndFlushWithGC() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddManyUnigramsAndFlushWithGC(formatVersion); - } - } - - private void testAddManyUnigramsAndFlushWithGC(final int formatVersion) { final int flashWithGCIterationCount = 3; 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); - } + final File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); final ArrayList<String> words = new ArrayList<>(); final HashMap<String, Integer> unigramProbabilities = new HashMap<>(); @@ -821,9 +608,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { BinaryDictionary binaryDictionary; for (int i = 0; i < flashWithGCIterationCount; i++) { - binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), - 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, - Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + binaryDictionary = getBinaryDictionary(dictFile); while(!binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { final String word = CodePointUtils.generateWord(random, codePointSet); words.add(word); @@ -841,30 +626,23 @@ public class BinaryDictionaryTests extends AndroidTestCase { binaryDictionary.flushWithGC(); binaryDictionary.close(); } - - dictFile.delete(); } public void testUnigramAndBigramCount() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testUnigramAndBigramCount(formatVersion); - } - } + final int maxUnigramCount = 5000; + final int maxBigramCount = 10000; + final HashMap<String, String> attributeMap = new HashMap<>(); + attributeMap.put(DictionaryHeader.MAX_UNIGRAM_COUNT_KEY, String.valueOf(maxUnigramCount)); + attributeMap.put(DictionaryHeader.MAX_BIGRAM_COUNT_KEY, String.valueOf(maxBigramCount)); - private void testUnigramAndBigramCount(final int formatVersion) { final int flashWithGCIterationCount = 10; final int codePointSetSize = 50; final int unigramCountPerIteration = 1000; final int bigramCountPerIteration = 2000; 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 File dictFile = createEmptyDictionaryWithAttributesAndGetFile(FormatSpec.VERSION403, + attributeMap); final ArrayList<String> words = new ArrayList<>(); final HashSet<Pair<String, String>> bigrams = new HashSet<>(); @@ -872,9 +650,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { BinaryDictionary binaryDictionary; for (int i = 0; i < flashWithGCIterationCount; i++) { - binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), - 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, - Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + binaryDictionary = getBinaryDictionary(dictFile); for (int j = 0; j < unigramCountPerIteration; j++) { final String word = CodePointUtils.generateWord(random, codePointSet); words.add(word); @@ -892,108 +668,31 @@ public class BinaryDictionaryTests extends AndroidTestCase { addBigramWords(binaryDictionary, word0, word1, bigramProbability); } assertEquals(new HashSet<>(words).size(), Integer.parseInt( - binaryDictionary.getPropertyForTest(BinaryDictionary.UNIGRAM_COUNT_QUERY))); + binaryDictionary.getPropertyForGettingStats( + BinaryDictionary.UNIGRAM_COUNT_QUERY))); assertEquals(new HashSet<>(bigrams).size(), Integer.parseInt( - binaryDictionary.getPropertyForTest(BinaryDictionary.BIGRAM_COUNT_QUERY))); + binaryDictionary.getPropertyForGettingStats( + BinaryDictionary.BIGRAM_COUNT_QUERY))); binaryDictionary.flushWithGC(); assertEquals(new HashSet<>(words).size(), Integer.parseInt( - binaryDictionary.getPropertyForTest(BinaryDictionary.UNIGRAM_COUNT_QUERY))); + binaryDictionary.getPropertyForGettingStats( + BinaryDictionary.UNIGRAM_COUNT_QUERY))); assertEquals(new HashSet<>(bigrams).size(), Integer.parseInt( - binaryDictionary.getPropertyForTest(BinaryDictionary.BIGRAM_COUNT_QUERY))); + binaryDictionary.getPropertyForGettingStats( + BinaryDictionary.BIGRAM_COUNT_QUERY))); binaryDictionary.close(); } - - dictFile.delete(); - } - - public void testAddMultipleDictionaryEntries() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddMultipleDictionaryEntries(formatVersion); - } - } - - 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<>(); - final HashMap<Pair<String, String>, Integer> bigramProbabilities = new HashMap<>(); - - 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 = probability + random.nextInt(0xFF - probability); - 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<>(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 bigramProbability = entry.getValue(); - assertEquals(bigramProbability != Dictionary.NOT_A_PROBABILITY, - isValidBigram(binaryDictionary, word0, word1)); - if (canCheckBigramProbability(formatVersion)) { - assertEquals(bigramProbability, - getBigramProbability(binaryDictionary, word0, word1)); - } - } } public void testGetWordProperties() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testGetWordProperties(formatVersion); - } - } - - 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 File dictFile = createEmptyDictionaryAndGetFile(FormatSpec.VERSION403); + final BinaryDictionary binaryDictionary = getBinaryDictionary(dictFile); final WordProperty invalidWordProperty = binaryDictionary.getWordProperty("dummyWord", false /* isBeginningOfSentence */); @@ -1008,11 +707,10 @@ public class BinaryDictionaryTests extends AndroidTestCase { final String word = CodePointUtils.generateWord(random, codePointSet); final int unigramProbability = random.nextInt(0xFF); final boolean isNotAWord = random.nextBoolean(); - final boolean isBlacklisted = random.nextBoolean(); + final boolean isPossiblyOffensive = random.nextBoolean(); // TODO: Add tests for historical info. binaryDictionary.addUnigramEntry(word, unigramProbability, - null /* shortcutTarget */, BinaryDictionary.NOT_A_PROBABILITY, - false /* isBeginningOfSentence */, isNotAWord, isBlacklisted, + false /* isBeginningOfSentence */, isNotAWord, isPossiblyOffensive, BinaryDictionary.NOT_A_VALID_TIMESTAMP); if (binaryDictionary.needsToRunGC(false /* mindsBlockByGC */)) { binaryDictionary.flushWithGC(); @@ -1024,11 +722,9 @@ public class BinaryDictionaryTests extends AndroidTestCase { assertEquals(word, wordProperty.mWord); assertTrue(wordProperty.isValid()); assertEquals(isNotAWord, wordProperty.mIsNotAWord); - assertEquals(isBlacklisted, wordProperty.mIsBlacklistEntry); - assertEquals(false, wordProperty.mHasBigrams); - assertEquals(false, wordProperty.mHasShortcuts); + assertEquals(isPossiblyOffensive, wordProperty.mIsPossiblyOffensive); + assertEquals(false, wordProperty.mHasNgrams); assertEquals(unigramProbability, wordProperty.mProbabilityInfo.mProbability); - assertTrue(wordProperty.mShortcutTargets.isEmpty()); } for (int i = 0; i < BIGRAM_COUNT; i++) { @@ -1062,41 +758,25 @@ public class BinaryDictionaryTests extends AndroidTestCase { final HashSet<String> bigramWord1s = bigrams.get(word0); final WordProperty wordProperty = binaryDictionary.getWordProperty(word0, false /* isBeginningOfSentence */); - assertEquals(bigramWord1s.size(), wordProperty.mBigrams.size()); - for (int j = 0; j < wordProperty.mBigrams.size(); j++) { - final String word1 = wordProperty.mBigrams.get(j).mWord; + assertEquals(bigramWord1s.size(), wordProperty.mNgrams.size()); + // TODO: Support ngram. + for (final WeightedString bigramTarget : wordProperty.getBigrams()) { + final String word1 = bigramTarget.mWord; assertTrue(bigramWord1s.contains(word1)); - if (canCheckBigramProbability(formatVersion)) { - final int bigramProbability = bigramProbabilities.get(new Pair<>(word0, word1)); - assertEquals(bigramProbability, wordProperty.mBigrams.get(j).getProbability()); - } + final int bigramProbability = bigramProbabilities.get(new Pair<>(word0, word1)); + assertEquals(bigramProbability, bigramTarget.getProbability()); } } } public void testIterateAllWords() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testIterateAllWords(formatVersion); - } - } - - 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 BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final WordProperty invalidWordProperty = binaryDictionary.getWordProperty("dummyWord", false /* isBeginningOfSentence */); @@ -1155,15 +835,16 @@ public class BinaryDictionaryTests extends AndroidTestCase { 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 Pair<String, String> bigram = new Pair<>(word0, word1); - if (canCheckBigramProbability(formatVersion)) { + // TODO: Support ngram. + if (wordProperty.mHasNgrams) { + for (final WeightedString bigramTarget : wordProperty.getBigrams()) { + final String word1 = bigramTarget.mWord; + assertTrue(bigramWord1s.contains(word1)); + final Pair<String, String> bigram = new Pair<>(word0, word1); final int bigramProbability = bigramProbabilitiesToCheckLater.get(bigram); - assertEquals(bigramProbability, wordProperty.mBigrams.get(j).getProbability()); + assertEquals(bigramProbability, bigramTarget.getProbability()); + bigramSet.remove(bigram); } - bigramSet.remove(bigram); } token = result.mNextToken; } while (token != 0); @@ -1171,346 +852,33 @@ public class BinaryDictionaryTests extends AndroidTestCase { assertTrue(bigramSet.isEmpty()); } - public void testAddShortcuts() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddShortcuts(formatVersion); - } - } - - 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.addUnigramEntry("aaa", unigramProbability, "zzz", - shortcutProbability, false /* isBeginningOfSentence */, - false /* isNotAWord */, false /* isBlacklisted */, 0 /* timestamp */); - WordProperty wordProperty = binaryDictionary.getWordProperty("aaa", - false /* isBeginningOfSentence */); - assertEquals(1, wordProperty.mShortcutTargets.size()); - assertEquals("zzz", wordProperty.mShortcutTargets.get(0).mWord); - assertEquals(shortcutProbability, wordProperty.mShortcutTargets.get(0).getProbability()); - final int updatedShortcutProbability = 2; - binaryDictionary.addUnigramEntry("aaa", unigramProbability, "zzz", - updatedShortcutProbability, false /* isBeginningOfSentence */, - false /* isNotAWord */, false /* isBlacklisted */, 0 /* timestamp */); - wordProperty = binaryDictionary.getWordProperty("aaa", - false /* isBeginningOfSentence */); - assertEquals(1, wordProperty.mShortcutTargets.size()); - assertEquals("zzz", wordProperty.mShortcutTargets.get(0).mWord); - assertEquals(updatedShortcutProbability, - wordProperty.mShortcutTargets.get(0).getProbability()); - binaryDictionary.addUnigramEntry("aaa", unigramProbability, "yyy", - shortcutProbability, false /* isBeginningOfSentence */, false /* isNotAWord */, - false /* isBlacklisted */, 0 /* timestamp */); - final HashMap<String, Integer> shortcutTargets = new HashMap<>(); - shortcutTargets.put("zzz", updatedShortcutProbability); - shortcutTargets.put("yyy", shortcutProbability); - wordProperty = binaryDictionary.getWordProperty("aaa", - false /* isBeginningOfSentence */); - 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", - false /* isBeginningOfSentence */); - 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() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testAddManyShortcuts(formatVersion); - } - } - - 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<>(); - final HashMap<String, Integer> unigramProbabilities = new HashMap<>(); - final HashMap<String, HashMap<String, Integer>> shortcutTargets = new HashMap<>(); - - 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.addUnigramEntry(word, unigramProbability, shortcutTarget, - shortcutProbability, false /* isBeginningOfSentence */, 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<>(); - 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, - false /* isBeginningOfSentence */); - 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()); - } - } - } - - public void testDictMigration() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testDictMigration(FormatSpec.VERSION4_ONLY_FOR_TESTING, formatVersion); - } - } - - private void testDictMigration(final int fromFormatVersion, final int toFormatVersion) { - File dictFile = null; - try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", fromFormatVersion); - } 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; - addUnigramWord(binaryDictionary, "aaa", unigramProbability); - addUnigramWord(binaryDictionary, "bbb", unigramProbability); - final int bigramProbability = 150; - addBigramWords(binaryDictionary, "aaa", "bbb", bigramProbability); - final int shortcutProbability = 10; - binaryDictionary.addUnigramEntry("ccc", unigramProbability, "xxx", shortcutProbability, - false /* isBeginningOfSentence */, false /* isNotAWord */, - false /* isBlacklisted */, 0 /* timestamp */); - binaryDictionary.addUnigramEntry("ddd", unigramProbability, null /* shortcutTarget */, - Dictionary.NOT_A_PROBABILITY, false /* isBeginningOfSentence */, - true /* isNotAWord */, true /* isBlacklisted */, 0 /* timestamp */); - binaryDictionary.addNgramEntry(PrevWordsInfo.BEGINNING_OF_SENTENCE, - "aaa", bigramProbability, 0 /* timestamp */); - assertEquals(unigramProbability, binaryDictionary.getFrequency("aaa")); - assertEquals(unigramProbability, binaryDictionary.getFrequency("bbb")); - assertTrue(isValidBigram(binaryDictionary, "aaa", "bbb")); - assertEquals(fromFormatVersion, binaryDictionary.getFormatVersion()); - assertTrue(binaryDictionary.migrateTo(toFormatVersion)); - assertTrue(binaryDictionary.isValidDictionary()); - assertEquals(toFormatVersion, binaryDictionary.getFormatVersion()); - assertEquals(unigramProbability, binaryDictionary.getFrequency("aaa")); - assertEquals(unigramProbability, binaryDictionary.getFrequency("bbb")); - if (canCheckBigramProbability(toFormatVersion)) { - assertEquals(bigramProbability, getBigramProbability(binaryDictionary, "aaa", "bbb")); - assertEquals(bigramProbability, binaryDictionary.getNgramProbability( - PrevWordsInfo.BEGINNING_OF_SENTENCE, "aaa")); - } - assertTrue(isValidBigram(binaryDictionary, "aaa", "bbb")); - WordProperty wordProperty = binaryDictionary.getWordProperty("ccc", - false /* isBeginningOfSentence */); - assertEquals(1, wordProperty.mShortcutTargets.size()); - assertEquals("xxx", wordProperty.mShortcutTargets.get(0).mWord); - wordProperty = binaryDictionary.getWordProperty("ddd", - false /* isBeginningOfSentence */); - assertTrue(wordProperty.mIsBlacklistEntry); - assertTrue(wordProperty.mIsNotAWord); - } - - public void testLargeDictMigration() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testLargeDictMigration(FormatSpec.VERSION4_ONLY_FOR_TESTING, formatVersion); - } - } - - private void testLargeDictMigration(final int fromFormatVersion, final int toFormatVersion) { - final int UNIGRAM_COUNT = 3000; - final int BIGRAM_COUNT = 3000; - final int codePointSetSize = 50; - final long seed = System.currentTimeMillis(); - final Random random = new Random(seed); - - File dictFile = null; - try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", fromFormatVersion); - } 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 ArrayList<String> words = new ArrayList<>(); - final ArrayList<Pair<String, String>> bigrams = new ArrayList<>(); - final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); - final HashMap<String, Integer> unigramProbabilities = new HashMap<>(); - final HashMap<Pair<String, String>, Integer> bigramProbabilities = new HashMap<>(); - - 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(true /* mindsBlockByGC */)) { - binaryDictionary.flushWithGC(); - } - words.add(word); - unigramProbabilities.put(word, unigramProbability); - } - - for (int i = 0; i < BIGRAM_COUNT; i++) { - final int word0Index = random.nextInt(words.size()); - final int word1Index = random.nextInt(words.size()); - if (word0Index == word1Index) { - continue; - } - final String word0 = words.get(word0Index); - final String word1 = words.get(word1Index); - final int unigramProbability = unigramProbabilities.get(word1); - final int bigramProbability = - random.nextInt(0xFF - unigramProbability) + unigramProbability; - addBigramWords(binaryDictionary, word0, word1, bigramProbability); - if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { - binaryDictionary.flushWithGC(); - } - final Pair<String, String> bigram = new Pair<>(word0, word1); - bigrams.add(bigram); - bigramProbabilities.put(bigram, bigramProbability); - } - assertTrue(binaryDictionary.migrateTo(toFormatVersion)); - - for (final String word : words) { - assertEquals((int)unigramProbabilities.get(word), binaryDictionary.getFrequency(word)); - } - assertEquals(unigramProbabilities.size(), Integer.parseInt( - binaryDictionary.getPropertyForTest(BinaryDictionary.UNIGRAM_COUNT_QUERY))); - - for (final Pair<String, String> bigram : bigrams) { - if (canCheckBigramProbability(toFormatVersion)) { - assertEquals((int)bigramProbabilities.get(bigram), - getBigramProbability(binaryDictionary, bigram.first, bigram.second)); - } - assertTrue(isValidBigram(binaryDictionary, bigram.first, bigram.second)); - } - assertEquals(bigramProbabilities.size(), Integer.parseInt( - binaryDictionary.getPropertyForTest(BinaryDictionary.BIGRAM_COUNT_QUERY))); + public void testPossiblyOffensiveAttributeMaintained() { + final BinaryDictionary binaryDictionary = + getEmptyBinaryDictionary(FormatSpec.VERSION403); + binaryDictionary.addUnigramEntry("ddd", 100, false, true, true, 0); + WordProperty wordProperty = binaryDictionary.getWordProperty("ddd", false); + assertEquals(true, wordProperty.mIsPossiblyOffensive); } public void testBeginningOfSentence() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - if (supportsBeginningOfSentence(formatVersion)) { - testBeginningOfSentence(formatVersion); - } - } - } - - private void testBeginningOfSentence(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 BinaryDictionary binaryDictionary = getEmptyBinaryDictionary(FormatSpec.VERSION403); final int dummyProbability = 0; - final PrevWordsInfo prevWordsInfoBeginningOfSentence = PrevWordsInfo.BEGINNING_OF_SENTENCE; + final NgramContext beginningOfSentenceContext = NgramContext.BEGINNING_OF_SENTENCE; final int bigramProbability = 200; addUnigramWord(binaryDictionary, "aaa", dummyProbability); - binaryDictionary.addNgramEntry(prevWordsInfoBeginningOfSentence, "aaa", bigramProbability, + binaryDictionary.addNgramEntry(beginningOfSentenceContext, "aaa", bigramProbability, BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); assertEquals(bigramProbability, - binaryDictionary.getNgramProbability(prevWordsInfoBeginningOfSentence, "aaa")); - binaryDictionary.addNgramEntry(prevWordsInfoBeginningOfSentence, "aaa", bigramProbability, + binaryDictionary.getNgramProbability(beginningOfSentenceContext, "aaa")); + binaryDictionary.addNgramEntry(beginningOfSentenceContext, "aaa", bigramProbability, BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); addUnigramWord(binaryDictionary, "bbb", dummyProbability); - binaryDictionary.addNgramEntry(prevWordsInfoBeginningOfSentence, "bbb", bigramProbability, + binaryDictionary.addNgramEntry(beginningOfSentenceContext, "bbb", bigramProbability, BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); binaryDictionary.flushWithGC(); assertEquals(bigramProbability, - binaryDictionary.getNgramProbability(prevWordsInfoBeginningOfSentence, "aaa")); + binaryDictionary.getNgramProbability(beginningOfSentenceContext, "aaa")); assertEquals(bigramProbability, - binaryDictionary.getNgramProbability(prevWordsInfoBeginningOfSentence, "bbb")); - } - - public void testGetMaxFrequencyOfExactMatches() { - for (final int formatVersion : DICT_FORMAT_VERSIONS) { - testGetMaxFrequencyOfExactMatches(formatVersion); - } - } - - private void testGetMaxFrequencyOfExactMatches(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 */); - addUnigramWord(binaryDictionary, "abc", 10); - addUnigramWord(binaryDictionary, "aBc", 15); - assertEquals(15, binaryDictionary.getMaxFrequencyOfExactMatches("abc")); - addUnigramWord(binaryDictionary, "ab'c", 20); - assertEquals(20, binaryDictionary.getMaxFrequencyOfExactMatches("abc")); - addUnigramWord(binaryDictionary, "a-b-c", 25); - assertEquals(25, binaryDictionary.getMaxFrequencyOfExactMatches("abc")); - addUnigramWord(binaryDictionary, "ab-'-'-'-c", 30); - assertEquals(30, binaryDictionary.getMaxFrequencyOfExactMatches("abc")); - addUnigramWord(binaryDictionary, "ab c", 255); - assertEquals(30, binaryDictionary.getMaxFrequencyOfExactMatches("abc")); + binaryDictionary.getNgramProbability(beginningOfSentenceContext, "bbb")); } } diff --git a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java index 6e894decf..afb94ef05 100644 --- a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java +++ b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java @@ -20,6 +20,8 @@ import android.test.suitebuilder.annotation.LargeTest; import android.text.style.SuggestionSpan; import android.text.style.UnderlineSpan; +import com.android.inputmethod.latin.common.Constants; + @LargeTest public class BlueUnderlineTests extends InputTestsBase { @@ -28,7 +30,7 @@ public class BlueUnderlineTests extends InputTestsBase { final int EXPECTED_SPAN_START = 0; final int EXPECTED_SPAN_END = 4; type(STRING_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); final SpanGetter span = new SpanGetter(mEditText.getText(), SuggestionSpan.class); assertEquals("show blue underline, span start", EXPECTED_SPAN_START, span.mStart); @@ -37,12 +39,12 @@ public class BlueUnderlineTests extends InputTestsBase { } public void testBlueUnderlineDisappears() { - final String STRING_1_TO_TYPE = "tgis"; - final String STRING_2_TO_TYPE = "q"; + final String STRING_1_TO_TYPE = "tqis"; + final String STRING_2_TO_TYPE = "g"; final int EXPECTED_SPAN_START = 0; final int EXPECTED_SPAN_END = 5; type(STRING_1_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); type(STRING_2_TO_TYPE); // We haven't have time to look into the dictionary yet, so the line should still be @@ -51,7 +53,7 @@ public class BlueUnderlineTests extends InputTestsBase { assertEquals("extend blue underline, span start", EXPECTED_SPAN_START, spanBefore.mStart); assertEquals("extend blue underline, span end", EXPECTED_SPAN_END, spanBefore.mEnd); assertTrue("extend blue underline, span color", spanBefore.isAutoCorrectionIndicator()); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); // Now we have been able to re-evaluate the word, there shouldn't be an auto-correction span final SpanGetter spanAfter = new SpanGetter(mEditText.getText(), SuggestionSpan.class); @@ -61,22 +63,21 @@ 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; + final int EXPECTED_UNDERLINE_SPAN_END = 3; type(STRING_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); 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); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); type(Constants.CODE_DELETE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); type(Constants.CODE_DELETE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); final SpanGetter suggestionSpan = new SpanGetter(mEditText.getText(), SuggestionSpan.class); assertFalse("show no blue underline after backspace, span should not be the auto-" @@ -93,7 +94,7 @@ public class BlueUnderlineTests extends InputTestsBase { final int typedLength = STRING_TO_TYPE.length(); final int NEW_CURSOR_POSITION = 0; type(STRING_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); // Simulate the onUpdateSelection() event mLatinIME.onUpdateSelection(0, 0, typedLength, typedLength, -1, -1); runMessages(); @@ -103,7 +104,7 @@ public class BlueUnderlineTests extends InputTestsBase { mInputConnection.setSelection(NEW_CURSOR_POSITION, NEW_CURSOR_POSITION); mLatinIME.onUpdateSelection(typedLength, typedLength, NEW_CURSOR_POSITION, NEW_CURSOR_POSITION, -1, -1); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); final SpanGetter span = new SpanGetter(mEditText.getText(), SuggestionSpan.class); assertFalse("blue underline removed when cursor is moved", @@ -113,7 +114,7 @@ public class BlueUnderlineTests extends InputTestsBase { public void testComposingStopsOnSpace() { final String STRING_TO_TYPE = "this "; type(STRING_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); // Simulate the onUpdateSelection() event mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1); runMessages(); diff --git a/tests/src/com/android/inputmethod/latin/ContactsContentObserverTest.java b/tests/src/com/android/inputmethod/latin/ContactsContentObserverTest.java new file mode 100644 index 000000000..f90a18bf1 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/ContactsContentObserverTest.java @@ -0,0 +1,94 @@ +/* + * 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; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.validateMockitoUsage; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.provider.ContactsContract.Contacts; +import android.test.suitebuilder.annotation.SmallTest; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.ArrayList; + +/** + * Tests for {@link ContactsContentObserver}. + */ +@SmallTest +public class ContactsContentObserverTest { + private static final int UPDATED_CONTACT_COUNT = 10; + private static final int STALE_CONTACT_COUNT = 8; + private static final ArrayList<String> STALE_NAMES_LIST = new ArrayList<>(); + private static final ArrayList<String> UPDATED_NAMES_LIST = new ArrayList<>(); + + static { + STALE_NAMES_LIST.add("Larry Page"); + STALE_NAMES_LIST.add("Roger Federer"); + UPDATED_NAMES_LIST.add("Larry Page"); + UPDATED_NAMES_LIST.add("Roger Federer"); + UPDATED_NAMES_LIST.add("Barak Obama"); + } + + @Mock private ContactsManager mMockManager; + @Mock private Context mContext; + + private ContactsContentObserver mObserver; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mObserver = new ContactsContentObserver(mMockManager, mContext); + } + + @After + public void tearDown() { + validateMockitoUsage(); + } + + @Test + public void testHaveContentsChanged_NoChange() { + when(mMockManager.getContactCount()).thenReturn(STALE_CONTACT_COUNT); + when(mMockManager.getContactCountAtLastRebuild()).thenReturn(STALE_CONTACT_COUNT); + when(mMockManager.getValidNames(eq(Contacts.CONTENT_URI))).thenReturn(STALE_NAMES_LIST); + when(mMockManager.getHashCodeAtLastRebuild()).thenReturn(STALE_NAMES_LIST.hashCode()); + assertFalse(mObserver.haveContentsChanged()); + } + @Test + public void testHaveContentsChanged_UpdatedCount() { + when(mMockManager.getContactCount()).thenReturn(UPDATED_CONTACT_COUNT); + when(mMockManager.getContactCountAtLastRebuild()).thenReturn(STALE_CONTACT_COUNT); + assertTrue(mObserver.haveContentsChanged()); + } + + @Test + public void testHaveContentsChanged_HashUpdate() { + when(mMockManager.getContactCount()).thenReturn(STALE_CONTACT_COUNT); + when(mMockManager.getContactCountAtLastRebuild()).thenReturn(STALE_CONTACT_COUNT); + when(mMockManager.getValidNames(eq(Contacts.CONTENT_URI))).thenReturn(UPDATED_NAMES_LIST); + when(mMockManager.getHashCodeAtLastRebuild()).thenReturn(STALE_NAMES_LIST.hashCode()); + assertTrue(mObserver.haveContentsChanged()); + } +} diff --git a/tests/src/com/android/inputmethod/latin/ContactsDictionaryUtilsTest.java b/tests/src/com/android/inputmethod/latin/ContactsDictionaryUtilsTest.java new file mode 100644 index 000000000..9b49f1abb --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/ContactsDictionaryUtilsTest.java @@ -0,0 +1,61 @@ +/* + * 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.test.suitebuilder.annotation.SmallTest; + +import org.junit.Test; + +import java.util.Locale; + +/** + * Tests for {@link ContactsDictionaryUtils} + */ +@SmallTest +public class ContactsDictionaryUtilsTest { + + @Test + public void testGetWordEndPosition() { + final String testString1 = "Larry Page"; + assertEquals(5, ContactsDictionaryUtils.getWordEndPosition( + testString1, testString1.length(), 0 /* startIndex */)); + + assertEquals(10, ContactsDictionaryUtils.getWordEndPosition( + testString1, testString1.length(), 6 /* startIndex */)); + + final String testString2 = "Larry-Page"; + assertEquals(10, ContactsDictionaryUtils.getWordEndPosition( + testString2, testString1.length(), 0 /* startIndex */)); + + final String testString3 = "Larry'Page"; + assertEquals(10, ContactsDictionaryUtils.getWordEndPosition( + testString3, testString1.length(), 0 /* startIndex */)); + } + + @Test + public void testUseFirstLastBigramsForLocale() { + assertTrue(ContactsDictionaryUtils.useFirstLastBigramsForLocale(Locale.ENGLISH)); + assertTrue(ContactsDictionaryUtils.useFirstLastBigramsForLocale(Locale.US)); + assertTrue(ContactsDictionaryUtils.useFirstLastBigramsForLocale(Locale.UK)); + assertFalse(ContactsDictionaryUtils.useFirstLastBigramsForLocale(Locale.CHINA)); + assertFalse(ContactsDictionaryUtils.useFirstLastBigramsForLocale(Locale.GERMAN)); + } +} diff --git a/tests/src/com/android/inputmethod/latin/ContactsManagerTest.java b/tests/src/com/android/inputmethod/latin/ContactsManagerTest.java new file mode 100644 index 000000000..6326b3b0f --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/ContactsManagerTest.java @@ -0,0 +1,127 @@ +/* + * 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; + +import android.content.ContentResolver; +import android.content.Context; +import android.database.Cursor; +import android.database.MatrixCursor; +import android.net.Uri; +import android.provider.ContactsContract; +import android.provider.ContactsContract.Contacts; +import android.test.AndroidTestCase; +import android.test.RenamingDelegatingContext; +import android.test.mock.MockContentProvider; +import android.test.mock.MockContentResolver; +import android.test.suitebuilder.annotation.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * Tests for {@link ContactsManager} + */ +@SmallTest +public class ContactsManagerTest extends AndroidTestCase { + + private ContactsManager mManager; + private FakeContactsContentProvider mFakeContactsContentProvider; + private MatrixCursor mMatrixCursor; + + @Before + @Override + public void setUp() throws Exception { + // Fake content provider + mFakeContactsContentProvider = new FakeContactsContentProvider(); + mMatrixCursor = new MatrixCursor(ContactsDictionaryConstants.PROJECTION); + // Add the fake content provider to fake content resolver. + final MockContentResolver contentResolver = new MockContentResolver(); + contentResolver.addProvider(ContactsContract.AUTHORITY, mFakeContactsContentProvider); + // Add the fake content resolver to a fake context. + final ContextWithMockContentResolver context = new ContextWithMockContentResolver(mContext); + context.setContentResolver(contentResolver); + + mManager = new ContactsManager(context); + } + + @Test + public void testGetValidNames() { + final String contactName1 = "firstname lastname"; + final String contactName2 = "larry"; + mMatrixCursor.addRow(new Object[] { 1, contactName1 }); + mMatrixCursor.addRow(new Object[] { 2, null /* null name */ }); + mMatrixCursor.addRow(new Object[] { 3, contactName2 }); + mMatrixCursor.addRow(new Object[] { 4, "floopy@example.com" /* invalid name */ }); + mFakeContactsContentProvider.addQueryResult(Contacts.CONTENT_URI, mMatrixCursor); + + final ArrayList<String> validNames = mManager.getValidNames(Contacts.CONTENT_URI); + assertEquals(2, validNames.size()); + assertEquals(contactName1, validNames.get(0)); + assertEquals(contactName2, validNames.get(1)); + } + + @Test + public void testGetCount() { + mMatrixCursor.addRow(new Object[] { 1, "firstname" }); + mMatrixCursor.addRow(new Object[] { 2, null /* null name */ }); + mMatrixCursor.addRow(new Object[] { 3, "larry" }); + mMatrixCursor.addRow(new Object[] { 4, "floopy@example.com" /* invalid name */ }); + mFakeContactsContentProvider.addQueryResult(Contacts.CONTENT_URI, mMatrixCursor); + + assertEquals(4, mManager.getContactCount()); + } + + + static class ContextWithMockContentResolver extends RenamingDelegatingContext { + private ContentResolver contentResolver; + + public void setContentResolver(final ContentResolver contentResolver) { + this.contentResolver = contentResolver; + } + + public ContextWithMockContentResolver(final Context targetContext) { + super(targetContext, "test"); + } + + @Override + public ContentResolver getContentResolver() { + return contentResolver; + } + } + + static class FakeContactsContentProvider extends MockContentProvider { + private final HashMap<String, MatrixCursor> mQueryCursorMapForTestExpectations = + new HashMap<>(); + + @Override + public Cursor query(final Uri uri, final String[] projection, final String selection, + final String[] selectionArgs, final String sortOrder) { + return mQueryCursorMapForTestExpectations.get(uri.toString()); + } + + public void reset() { + mQueryCursorMapForTestExpectations.clear(); + } + + public void addQueryResult(final Uri uri, final MatrixCursor cursor) { + mQueryCursorMapForTestExpectations.put(uri.toString(), cursor); + } + } +} diff --git a/tests/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCacheTests.java b/tests/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCacheTests.java new file mode 100644 index 000000000..6b0bbc279 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCacheTests.java @@ -0,0 +1,42 @@ +/* + * 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; + +import java.util.Locale; + +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.LargeTest; + +@LargeTest +public class DictionaryFacilitatorLruCacheTests extends AndroidTestCase { + public void testGetFacilitator() { + final DictionaryFacilitatorLruCache cache = + new DictionaryFacilitatorLruCache(getContext(), ""); + + final DictionaryFacilitator dictionaryFacilitatorEnUs = cache.get(Locale.US); + assertNotNull(dictionaryFacilitatorEnUs); + assertTrue(dictionaryFacilitatorEnUs.isForLocale(Locale.US)); + + final DictionaryFacilitator dictionaryFacilitatorFr = cache.get(Locale.FRENCH); + assertNotNull(dictionaryFacilitatorEnUs); + assertTrue(dictionaryFacilitatorFr.isForLocale(Locale.FRENCH)); + + final DictionaryFacilitator dictionaryFacilitatorDe = cache.get(Locale.GERMANY); + assertNotNull(dictionaryFacilitatorDe); + assertTrue(dictionaryFacilitatorDe.isForLocale(Locale.GERMANY)); + } +} diff --git a/tests/src/com/android/inputmethod/latin/DistracterFilterTest.java b/tests/src/com/android/inputmethod/latin/DistracterFilterTest.java deleted file mode 100644 index e6fb28260..000000000 --- a/tests/src/com/android/inputmethod/latin/DistracterFilterTest.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * 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; - -import java.util.ArrayList; -import java.util.Locale; - -import android.content.Context; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; -import android.view.inputmethod.InputMethodSubtype; - -import com.android.inputmethod.latin.utils.DistracterFilterCheckingExactMatchesAndSuggestions; - -/** - * Unit test for DistracterFilter - */ -@LargeTest -public class DistracterFilterTest extends AndroidTestCase { - private DistracterFilterCheckingExactMatchesAndSuggestions mDistracterFilter; - - @Override - protected void setUp() throws Exception { - super.setUp(); - final Context context = getContext(); - mDistracterFilter = new DistracterFilterCheckingExactMatchesAndSuggestions(context); - RichInputMethodManager.init(context); - final RichInputMethodManager richImm = RichInputMethodManager.getInstance(); - final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>(); - subtypes.add(richImm.findSubtypeByLocaleAndKeyboardLayoutSet( - Locale.US.toString(), "qwerty")); - subtypes.add(richImm.findSubtypeByLocaleAndKeyboardLayoutSet( - Locale.FRENCH.toString(), "azerty")); - subtypes.add(richImm.findSubtypeByLocaleAndKeyboardLayoutSet( - Locale.GERMAN.toString(), "qwertz")); - mDistracterFilter.updateEnabledSubtypes(subtypes); - } - - public void testIsDistractorToWordsInDictionaries() { - final PrevWordsInfo EMPTY_PREV_WORDS_INFO = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; - - final Locale localeEnUs = new Locale("en", "US"); - String typedWord; - - typedWord = "Bill"; - // For this test case, we consider "Bill" is a distracter to "bill". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "nOt"; - // For this test case, we consider "nOt" is a distracter to "not". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "youre"; - // For this test case, we consider "youre" is a distracter to "you're". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "Banana"; - // For this test case, we consider "Banana" is a distracter to "banana". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "orange"; - // For this test case, we consider "orange" is not a distracter to any word in dictionaries. - assertFalse(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "Orange"; - // For this test case, we consider "Orange" is a distracter to "orange". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "café"; - // For this test case, we consider "café" is a distracter to "cafe". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "cafe"; - // For this test case, we consider "cafe" is not a distracter to any word in dictionaries. - assertFalse(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "I'll"; - // For this test case, we consider "I'll" is not a distracter to any word in dictionaries. - assertFalse(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "ill"; - // For this test case, we consider "ill" is a distracter to "I'll" - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "asdfd"; - // For this test case, we consider "asdfd" is not a distracter to any word in dictionaries. - assertFalse( - mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "thank"; - // For this test case, we consider "thank" is not a distracter to any other word - // in dictionaries. - assertFalse(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "thabk"; - // For this test case, we consider "thabk" is a distracter to "thank" - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "thanks"; - // For this test case, we consider "thanks" is not a distracter to any other word - // in dictionaries. - assertFalse(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "thabks"; - // For this test case, we consider "thabks" is a distracter to "thanks" - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "think"; - // For this test case, we consider "think" is not a distracter to any other word - // in dictionaries. - assertFalse(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "thibk"; - // For this test case, we consider "thibk" is a distracter to "think" - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - typedWord = "tgis"; - // For this test case, we consider "tgis" is a distracter to "this" - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeEnUs)); - - final Locale localeDeDe = new Locale("de"); - - typedWord = "fUEr"; - // For this test case, we consider "fUEr" is a distracter to "für". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeDeDe)); - - typedWord = "fuer"; - // For this test case, we consider "fuer" is a distracter to "für". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeDeDe)); - - typedWord = "fur"; - // For this test case, we consider "fur" is a distracter to "für". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeDeDe)); - - final Locale localeFrFr = new Locale("fr"); - - typedWord = "a"; - // For this test case, we consider "a" is a distracter to "à". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeFrFr)); - - typedWord = "à"; - // For this test case, we consider "à" is not a distracter to any word in dictionaries. - assertFalse(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeFrFr)); - - typedWord = "etre"; - // For this test case, we consider "etre" is a distracter to "être". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeFrFr)); - - typedWord = "États-unis"; - // For this test case, we consider "États-unis" is a distracter to "États-Unis". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeFrFr)); - - typedWord = "ÉtatsUnis"; - // For this test case, we consider "ÉtatsUnis" is a distracter to "États-Unis". - assertTrue(mDistracterFilter.isDistracterToWordsInDictionaries( - EMPTY_PREV_WORDS_INFO, typedWord, localeFrFr)); - } -} diff --git a/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java b/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java deleted file mode 100644 index 09309bcc0..000000000 --- a/tests/src/com/android/inputmethod/latin/FusionDictionaryTests.java +++ /dev/null @@ -1,52 +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; - -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions; -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; - -/** - * Unit test for FusionDictionary - */ -@SmallTest -public class FusionDictionaryTests extends AndroidTestCase { - public void testFindWordInTree() { - FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - new DictionaryOptions(new HashMap<String,String>())); - - dict.add("abc", new ProbabilityInfo(10), null, false /* isNotAWord */); - assertNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "aaa")); - assertNotNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "abc")); - - dict.add("aa", new ProbabilityInfo(10), null, false /* isNotAWord */); - assertNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "aaa")); - assertNotNull(FusionDictionary.findWordInTree(dict.mRootNodeArray, "aa")); - - 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 59b858dbd..02cd21c8d 100644 --- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java +++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java @@ -16,15 +16,33 @@ package com.android.inputmethod.latin; +import static android.test.MoreAsserts.assertNotEqual; + import android.test.suitebuilder.annotation.LargeTest; import android.text.TextUtils; import android.view.inputmethod.BaseInputConnection; +import com.android.inputmethod.latin.common.Constants; +import com.android.inputmethod.latin.define.DecoderSpecificConstants; import com.android.inputmethod.latin.settings.Settings; @LargeTest public class InputLogicTests extends InputTestsBase { + private boolean mNextWordPrediction; + + @Override + public void setUp() throws Exception { + super.setUp(); + mNextWordPrediction = getBooleanPreference(Settings.PREF_BIGRAM_PREDICTIONS, true); + } + + @Override + public void tearDown() throws Exception { + setBooleanPreference(Settings.PREF_BIGRAM_PREDICTIONS, mNextWordPrediction, true); + super.tearDown(); + } + public void testTypeWord() { final String WORD_TO_TYPE = "abcd"; type(WORD_TO_TYPE); @@ -36,7 +54,7 @@ public class InputLogicTests extends InputTestsBase { final String EXPECTED_RESULT = "thi"; type(WORD_TO_TYPE); pickSuggestionManually(WORD_TO_TYPE); - mLatinIME.onUpdateSelection(0, 0, WORD_TO_TYPE.length(), WORD_TO_TYPE.length(), -1, -1); + sendUpdateForCursorMoveTo(WORD_TO_TYPE.length()); type(Constants.CODE_DELETE); assertEquals("press suggestion then backspace", EXPECTED_RESULT, mEditText.getText().toString()); @@ -49,7 +67,7 @@ public class InputLogicTests extends InputTestsBase { type(WORD_TO_TYPE); // Choose the auto-correction. For "tgis", the auto-correction should be "this". pickSuggestionManually(WORD_TO_PICK); - mLatinIME.onUpdateSelection(0, 0, WORD_TO_TYPE.length(), WORD_TO_TYPE.length(), -1, -1); + sendUpdateForCursorMoveTo(WORD_TO_TYPE.length()); assertEquals("pick typed word over auto-correction then backspace", WORD_TO_PICK, mEditText.getText().toString()); type(Constants.CODE_DELETE); @@ -63,7 +81,7 @@ public class InputLogicTests extends InputTestsBase { type(WORD_TO_TYPE); // Choose the typed word. pickSuggestionManually(WORD_TO_TYPE); - mLatinIME.onUpdateSelection(0, 0, WORD_TO_TYPE.length(), WORD_TO_TYPE.length(), -1, -1); + sendUpdateForCursorMoveTo(WORD_TO_TYPE.length()); assertEquals("pick typed word over auto-correction then backspace", WORD_TO_TYPE, mEditText.getText().toString()); type(Constants.CODE_DELETE); @@ -78,7 +96,7 @@ public class InputLogicTests extends InputTestsBase { type(WORD_TO_TYPE); // Choose the second suggestion, which should be "thus" when "tgis" is typed. pickSuggestionManually(WORD_TO_PICK); - mLatinIME.onUpdateSelection(0, 0, WORD_TO_TYPE.length(), WORD_TO_TYPE.length(), -1, -1); + sendUpdateForCursorMoveTo(WORD_TO_TYPE.length()); assertEquals("pick different suggestion then backspace", WORD_TO_PICK, mEditText.getText().toString()); type(Constants.CODE_DELETE); @@ -93,7 +111,8 @@ public class InputLogicTests extends InputTestsBase { final int SELECTION_END = 19; final String EXPECTED_RESULT = "some text some text"; type(STRING_TO_TYPE); - // There is no IMF to call onUpdateSelection for us so we must do it by hand. + // Don't use the sendUpdateForCursorMove* family of methods here because they + // don't handle selections. // Send once to simulate the cursor actually responding to the move caused by typing. // This is necessary because LatinIME is bookkeeping to avoid confusing a real cursor // move with a move triggered by LatinIME inputting stuff. @@ -113,7 +132,8 @@ public class InputLogicTests extends InputTestsBase { final int SELECTION_END = 19; final String EXPECTED_RESULT = "some text some text"; type(STRING_TO_TYPE); - // There is no IMF to call onUpdateSelection for us so we must do it by hand. + // Don't use the sendUpdateForCursorMove* family of methods here because they + // don't handle selections. // Send once to simulate the cursor actually responding to the move caused by typing. // This is necessary because LatinIME is bookkeeping to avoid confusing a real cursor // move with a move triggered by LatinIME inputting stuff. @@ -152,49 +172,90 @@ public class InputLogicTests extends InputTestsBase { final String STRING_TO_TYPE = "tgis."; final String EXPECTED_RESULT = "tgis."; type(STRING_TO_TYPE); - mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1); + sendUpdateForCursorMoveTo(STRING_TO_TYPE.length()); type(Constants.CODE_DELETE); assertEquals("auto-correct with period then revert", EXPECTED_RESULT, mEditText.getText().toString()); } public void testAutoCorrectWithSpaceThenRevert() { + // Backspacing to cancel the "tgis"->"this" autocorrection should result in + // a "phantom space": if the user presses space immediately after, + // only one space will be inserted in total. final String STRING_TO_TYPE = "tgis "; - final String EXPECTED_RESULT = "tgis "; + final String EXPECTED_RESULT = "tgis"; type(STRING_TO_TYPE); - mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1); + sendUpdateForCursorMoveTo(STRING_TO_TYPE.length()); type(Constants.CODE_DELETE); assertEquals("auto-correct with space then revert", EXPECTED_RESULT, mEditText.getText().toString()); } + public void testAutoCorrectWithSpaceThenRevertThenTypeMore() { + final String STRING_TO_TYPE_FIRST = "tgis "; + final String STRING_TO_TYPE_SECOND = "a"; + final String EXPECTED_RESULT = "tgis a"; + type(STRING_TO_TYPE_FIRST); + sendUpdateForCursorMoveTo(STRING_TO_TYPE_FIRST.length()); + type(Constants.CODE_DELETE); + + type(STRING_TO_TYPE_SECOND); + sendUpdateForCursorMoveTo(STRING_TO_TYPE_FIRST.length() - 1 + + STRING_TO_TYPE_SECOND.length()); + assertEquals("auto-correct with space then revert then type more", EXPECTED_RESULT, + mEditText.getText().toString()); + } + public void testAutoCorrectToSelfDoesNotRevert() { final String STRING_TO_TYPE = "this "; final String EXPECTED_RESULT = "this"; type(STRING_TO_TYPE); - mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1); + sendUpdateForCursorMoveTo(STRING_TO_TYPE.length()); type(Constants.CODE_DELETE); assertEquals("auto-correct with space does not revert", EXPECTED_RESULT, mEditText.getText().toString()); } public void testDoubleSpace() { - // Set default pref just in case - setBooleanPreference(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true, true); // U+1F607 is an emoji final String[] STRINGS_TO_TYPE = new String[] { "this ", "a+ ", "\u1F607 ", ".. ", ") ", "( ", "% " }; final String[] EXPECTED_RESULTS = new String[] { "this. ", "a+. ", "\u1F607. ", ".. ", "). ", "( ", "%. " }; - for (int i = 0; i < STRINGS_TO_TYPE.length; ++i) { + verifyDoubleSpace(STRINGS_TO_TYPE, EXPECTED_RESULTS); + } + + public void testDoubleSpaceHindi() { + changeLanguage("hi"); + // U+1F607 is an emoji + final String[] STRINGS_TO_TYPE = + new String[] { "this ", "a+ ", "\u1F607 ", "|| ", ") ", "( ", "% " }; + final String[] EXPECTED_RESULTS = + new String[] { "this| ", "a+| ", "\u1F607| ", "|| ", ")| ", "( ", "%| " }; + verifyDoubleSpace(STRINGS_TO_TYPE, EXPECTED_RESULTS); + } + + private void verifyDoubleSpace(String[] stringsToType, String[] expectedResults) { + // Set default pref just in case + setBooleanPreference(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true, true); + for (int i = 0; i < stringsToType.length; ++i) { mEditText.setText(""); - type(STRINGS_TO_TYPE[i]); - assertEquals("double space processing", EXPECTED_RESULTS[i], + type(stringsToType[i]); + assertEquals("double space processing", expectedResults[i], mEditText.getText().toString()); } } - public void testCancelDoubleSpace() { + public void testCancelDoubleSpaceEnglish() { + final String STRING_TO_TYPE = "this "; + final String EXPECTED_RESULT = "this "; + type(STRING_TO_TYPE); + type(Constants.CODE_DELETE); + assertEquals("double space make a period", EXPECTED_RESULT, mEditText.getText().toString()); + } + + public void testCancelDoubleSpaceHindi() { + changeLanguage("hi"); final String STRING_TO_TYPE = "this "; final String EXPECTED_RESULT = "this "; type(STRING_TO_TYPE); @@ -243,9 +304,9 @@ public class InputLogicTests extends InputTestsBase { public void testDoubleSpacePeriod() { // Reset settings to default, else these tests will go flaky. setBooleanPreference(Settings.PREF_SHOW_SUGGESTIONS, true, true); - setStringPreference(Settings.PREF_AUTO_CORRECTION_THRESHOLD, "1", "1"); + setBooleanPreference(Settings.PREF_AUTO_CORRECTION, true, true); setBooleanPreference(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true, true); - testDoubleSpacePeriodWithSettings(true /* expectsPeriod */); + testDoubleSpacePeriodWithSettings(true); // "Suggestion visibility" to off testDoubleSpacePeriodWithSettings(true, Settings.PREF_SHOW_SUGGESTIONS, false); // "Suggestion visibility" to on @@ -255,18 +316,16 @@ public class InputLogicTests extends InputTestsBase { testDoubleSpacePeriodWithSettings(false, Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, false); // "Auto-correction" to "off" - testDoubleSpacePeriodWithSettings(true, Settings.PREF_AUTO_CORRECTION_THRESHOLD, "0"); - // "Auto-correction" to "modest" - testDoubleSpacePeriodWithSettings(true, Settings.PREF_AUTO_CORRECTION_THRESHOLD, "1"); - // "Auto-correction" to "very aggressive" - testDoubleSpacePeriodWithSettings(true, Settings.PREF_AUTO_CORRECTION_THRESHOLD, "3"); + testDoubleSpacePeriodWithSettings(true, Settings.PREF_AUTO_CORRECTION, false); + // "Auto-correction" to "on" + testDoubleSpacePeriodWithSettings(true, Settings.PREF_AUTO_CORRECTION, true); // "Suggestion visibility" to "always hide" and "Auto-correction" to "off" testDoubleSpacePeriodWithSettings(true, Settings.PREF_SHOW_SUGGESTIONS, false, - Settings.PREF_AUTO_CORRECTION_THRESHOLD, "0"); + Settings.PREF_AUTO_CORRECTION, false); // "Suggestion visibility" to "always hide" and "Auto-correction" to "off" testDoubleSpacePeriodWithSettings(false, Settings.PREF_SHOW_SUGGESTIONS, false, - Settings.PREF_AUTO_CORRECTION_THRESHOLD, "0", + Settings.PREF_AUTO_CORRECTION, false, Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, false); } @@ -276,10 +335,9 @@ public class InputLogicTests extends InputTestsBase { final String EXPECTED_RESULT = "this "; final int NEW_CURSOR_POSITION = 0; type(STRING_TO_TYPE); - mLatinIME.onUpdateSelection(0, 0, typedLength, typedLength, -1, -1); + sendUpdateForCursorMoveTo(typedLength); mInputConnection.setSelection(NEW_CURSOR_POSITION, NEW_CURSOR_POSITION); - mLatinIME.onUpdateSelection(typedLength, typedLength, - NEW_CURSOR_POSITION, NEW_CURSOR_POSITION, -1, -1); + sendUpdateForCursorMoveTo(NEW_CURSOR_POSITION); type(Constants.CODE_DELETE); assertEquals("auto correct then move cursor to start of line then backspace", EXPECTED_RESULT, mEditText.getText().toString()); @@ -291,10 +349,9 @@ public class InputLogicTests extends InputTestsBase { final String EXPECTED_RESULT = "andthis "; final int NEW_CURSOR_POSITION = STRING_TO_TYPE.indexOf('t'); type(STRING_TO_TYPE); - mLatinIME.onUpdateSelection(0, 0, typedLength, typedLength, -1, -1); + sendUpdateForCursorMoveTo(typedLength); mInputConnection.setSelection(NEW_CURSOR_POSITION, NEW_CURSOR_POSITION); - mLatinIME.onUpdateSelection(typedLength, typedLength, - NEW_CURSOR_POSITION, NEW_CURSOR_POSITION, -1, -1); + sendUpdateForCursorMoveTo(NEW_CURSOR_POSITION); type(Constants.CODE_DELETE); assertEquals("auto correct then move cursor then backspace", EXPECTED_RESULT, mEditText.getText().toString()); @@ -329,8 +386,8 @@ public class InputLogicTests extends InputTestsBase { assertEquals("manual pick then separator", EXPECTED_RESULT, mEditText.getText().toString()); } - // This test matches the one in InputLogicTestsNonEnglish. In some non-English languages, - // ! and ? are clustering punctuation signs. + // This test matches testClusteringPunctuationForFrench. + // In some non-English languages, ! and ? are clustering punctuation signs. public void testClusteringPunctuation() { final String WORD1_TO_TYPE = "test"; final String WORD2_TO_TYPE = "!!?!:!"; @@ -394,7 +451,7 @@ public class InputLogicTests extends InputTestsBase { BaseInputConnection.getComposingSpanStart(mEditText.getText())); assertEquals("resume suggestion on backspace", -1, BaseInputConnection.getComposingSpanEnd(mEditText.getText())); - mLatinIME.onUpdateSelection(0, 0, typedLength, typedLength, -1, -1); + sendUpdateForCursorMoveTo(typedLength); type(Constants.CODE_DELETE); assertEquals("resume suggestion on backspace", 4, BaseInputConnection.getComposingSpanStart(mEditText.getText())); @@ -429,44 +486,25 @@ public class InputLogicTests extends InputTestsBase { type(" "); 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 = 1; - 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("qpmz"); 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); + + int startIndex = mEditText.getText().length(); + type("qpmx"); type(Constants.CODE_SPACE); - endIndex = mEditText.getText().length(); + int endIndex = mEditText.getText().length(); assertEquals("auto-corrected by user history", - CORRECTED_RESULT, mEditText.getText().subSequence(startIndex, endIndex).toString()); + "qpmz ", 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); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); // Test the first prediction is displayed final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); @@ -476,24 +514,19 @@ public class InputLogicTests extends InputTestsBase { public void testPredictionsWithDoubleSpaceToPeriod() { mLatinIME.clearPersonalizedDictionariesForTest(); - final String WORD_TO_TYPE = "Barack "; + final String WORD_TO_TYPE = "Barack "; type(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); - // No need to test here, testPredictionsAfterSpace is testing it already - type(" "); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); - runMessages(); - // Test the predictions have been cleared - SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); - assertEquals("predictions cleared after double-space-to-period", suggestedWords.size(), 0); + type(Constants.CODE_DELETE); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); - // Test the first prediction is displayed + + SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); suggestedWords = mLatinIME.getSuggestedWordsForTest(); assertEquals("predictions after cancel double-space-to-period", "Obama", - suggestedWords.size() > 0 ? suggestedWords.getWord(0) : null); + mLatinIME.getSuggestedWordsForTest().getWord(0)); } public void testPredictionsAfterManualPick() { @@ -501,7 +534,7 @@ public class InputLogicTests extends InputTestsBase { type(WORD_TO_TYPE); // Choose the auto-correction. For "Barack", the auto-correction should be "Barack". pickSuggestionManually(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); // Test the first prediction is displayed final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); @@ -513,17 +546,11 @@ public class InputLogicTests extends InputTestsBase { mLatinIME.clearPersonalizedDictionariesForTest(); final String WORD_TO_TYPE = "Barack. "; type(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); - SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); - assertEquals("No prediction after period after inputting once.", 0, suggestedWords.size()); - type(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); - runMessages(); - suggestedWords = mLatinIME.getSuggestedWordsForTest(); - assertEquals("Beginning-of-Sentence prediction after inputting 2 times.", "Barack", - suggestedWords.size() > 0 ? suggestedWords.getWord(0) : null); + SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); + assertFalse(mLatinIME.getSuggestedWordsForTest().isEmpty()); } public void testPredictionsAfterRecorrection() { @@ -535,27 +562,23 @@ public class InputLogicTests extends InputTestsBase { 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); + sendUpdateForCursorMoveTo(endOfPrefix); type(WORD_TO_TYPE); pickSuggestionManually(FIRST_NON_TYPED_SUGGESTION); - mLatinIME.onUpdateSelection(endOfPrefix, endOfPrefix, endOfSuggestion, endOfSuggestion, - -1, -1); + sendUpdateForCursorMoveTo(endOfSuggestion); runMessages(); type(" "); - mLatinIME.onUpdateSelection(endOfSuggestion, endOfSuggestion, - endOfSuggestion + 1, endOfSuggestion + 1, -1, -1); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sendUpdateForCursorMoveBy(1); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); 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); + sendUpdateForCursorMoveTo(indexForManualCursor); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); pickSuggestionManually(WORD_TO_TYPE); - mLatinIME.onUpdateSelection(indexForManualCursor, indexForManualCursor, - endOfWord, endOfWord, -1, -1); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sendUpdateForCursorMoveTo(endOfWord); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); // Test the first prediction is displayed final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); @@ -603,7 +626,7 @@ public class InputLogicTests extends InputTestsBase { for (int i = 0; i < WORD_TO_TYPE.length(); ++i) { type(WORD_TO_TYPE.substring(i, i+1)); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); } assertEquals("type many trailing single quotes one by one", EXPECTED_RESULT, @@ -615,26 +638,148 @@ public class InputLogicTests extends InputTestsBase { final String EXPECTED_RESULT = WORD_TO_TYPE; for (int i = 0; i < WORD_TO_TYPE.length(); ++i) { type(WORD_TO_TYPE.substring(i, i+1)); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); } assertEquals("type words letter by letter", EXPECTED_RESULT, mEditText.getText().toString()); } - public void testSwitchLanguages() { - final String WORD_TO_TYPE_FIRST_PART = "com"; - final String WORD_TO_TYPE_SECOND_PART = "md"; - final String EXPECTED_RESULT = "comme"; - changeLanguage("en"); - type(WORD_TO_TYPE_FIRST_PART); + public void testBasicGesture() { + gesture("this"); + assertEquals("this", mEditText.getText().toString()); + } + + public void testGestureGesture() { + gesture("got"); + gesture("milk"); + assertEquals("got milk", mEditText.getText().toString()); + } + + public void testGestureBackspaceGestureAgain() { + gesture("this"); + type(Constants.CODE_DELETE); + assertEquals("gesture then backspace", "", mEditText.getText().toString()); + gesture("this"); + if (DecoderSpecificConstants.SHOULD_REMOVE_PREVIOUSLY_REJECTED_SUGGESTION) { + assertNotEqual("this", mEditText.getText().toString()); + } else { + assertEquals("this", mEditText.getText().toString()); + } + } + + private void typeOrGestureWordAndPutCursorInside(final boolean gesture, final String word, + final int startPos) { + final int END_OF_WORD = startPos + word.length(); + final int NEW_CURSOR_POSITION = startPos + word.length() / 2; + if (gesture) { + gesture(word); + } else { + type(word); + } + sendUpdateForCursorMoveTo(END_OF_WORD); + runMessages(); + sendUpdateForCursorMoveTo(NEW_CURSOR_POSITION); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); + runMessages(); + } + + private void typeWordAndPutCursorInside(final String word, final int startPos) { + typeOrGestureWordAndPutCursorInside(false /* gesture */, word, startPos); + } + + private void gestureWordAndPutCursorInside(final String word, final int startPos) { + typeOrGestureWordAndPutCursorInside(true /* gesture */, word, startPos); + } + + private void ensureComposingSpanPos(final String message, final int from, final int to) { + assertEquals(message, from, BaseInputConnection.getComposingSpanStart(mEditText.getText())); + assertEquals(message, to, BaseInputConnection.getComposingSpanEnd(mEditText.getText())); + } + + public void testTypeWithinComposing() { + final String WORD_TO_TYPE = "something"; + final String EXPECTED_RESULT = "some thing"; + typeWordAndPutCursorInside(WORD_TO_TYPE, 0 /* startPos */); + type(" "); + ensureComposingSpanPos("space while in the middle of a word cancels composition", -1, -1); + assertEquals("space in the middle of a composing word", EXPECTED_RESULT, + mEditText.getText().toString()); + int cursorPos = sendUpdateForCursorMoveToEndOfLine(); + runMessages(); + type(" "); + assertEquals("mbo", "some thing ", mEditText.getText().toString()); + typeWordAndPutCursorInside(WORD_TO_TYPE, cursorPos + 1 /* startPos */); + type(Constants.CODE_DELETE); + ensureComposingSpanPos("delete while in the middle of a word cancels composition", -1, -1); + } + + public void testTypeWithinGestureComposing() { + final String WORD_TO_TYPE = "something"; + final String EXPECTED_RESULT = "some thing"; + gestureWordAndPutCursorInside(WORD_TO_TYPE, 0 /* startPos */); + type(" "); + ensureComposingSpanPos("space while in the middle of a word cancels composition", -1, -1); + assertEquals("space in the middle of a composing word", EXPECTED_RESULT, + mEditText.getText().toString()); + int cursorPos = sendUpdateForCursorMoveToEndOfLine(); + runMessages(); + type(" "); + typeWordAndPutCursorInside(WORD_TO_TYPE, cursorPos + 1 /* startPos */); + type(Constants.CODE_DELETE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); + ensureComposingSpanPos("delete while in the middle of a word cancels composition", -1, -1); + } + + public void testManualPickThenSeparatorForFrench() { + final String WORD1_TO_TYPE = "test"; + final String WORD2_TO_TYPE = "!"; + final String EXPECTED_RESULT = "test !"; changeLanguage("fr"); + type(WORD1_TO_TYPE); + pickSuggestionManually(WORD1_TO_TYPE); + type(WORD2_TO_TYPE); + assertEquals("manual pick then separator for French", EXPECTED_RESULT, + mEditText.getText().toString()); + } + + public void testClusteringPunctuationForFrench() { + final String WORD1_TO_TYPE = "test"; + final String WORD2_TO_TYPE = "!!?!:!"; + // In English, the expected result would be "test!!?!:!" + final String EXPECTED_RESULT = "test !!?! : !"; + changeLanguage("fr"); + type(WORD1_TO_TYPE); + pickSuggestionManually(WORD1_TO_TYPE); + type(WORD2_TO_TYPE); + assertEquals("clustering punctuation for French", EXPECTED_RESULT, + mEditText.getText().toString()); + } + + public void testWordThenSpaceThenPunctuationFromStripTwice() { + setBooleanPreference(Settings.PREF_BIGRAM_PREDICTIONS, false, true); + + final String WORD_TO_TYPE = "test "; + final String PUNCTUATION_FROM_STRIP = "!"; + final String EXPECTED_RESULT = "test!! "; + type(WORD_TO_TYPE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); - type(WORD_TO_TYPE_SECOND_PART); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + assertTrue("type word then type space should display punctuation strip", + mLatinIME.getSuggestedWordsForTest().isPunctuationSuggestions()); + pickSuggestionManually(PUNCTUATION_FROM_STRIP); + pickSuggestionManually(PUNCTUATION_FROM_STRIP); + assertEquals(EXPECTED_RESULT, mEditText.getText().toString()); + } + + public void testWordThenSpaceDisplaysPredictions() { + final String WORD_TO_TYPE = "Barack "; + final String EXPECTED_RESULT = "Obama"; + type(WORD_TO_TYPE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); - assertEquals("Suggestions updated after switching languages", - EXPECTED_RESULT, suggestedWords.size() > 0 ? suggestedWords.getWord(1) : null); + assertEquals("type word then type space yields predictions for French", + EXPECTED_RESULT, suggestedWords.size() > 0 ? suggestedWords.getWord(0) : null); } } diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTestsDeadKeys.java b/tests/src/com/android/inputmethod/latin/InputLogicTestsDeadKeys.java new file mode 100644 index 000000000..4b44138a7 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/InputLogicTestsDeadKeys.java @@ -0,0 +1,216 @@ +/* + * 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; + +import android.test.suitebuilder.annotation.LargeTest; + +import com.android.inputmethod.event.Event; +import com.android.inputmethod.latin.common.Constants; + +import java.util.ArrayList; + +@LargeTest +public class InputLogicTestsDeadKeys extends InputTestsBase { + // A helper class for readability + static class EventList extends ArrayList<Event> { + public EventList addCodePoint(final int codePoint, final boolean isDead) { + final Event event; + if (isDead) { + event = Event.createDeadEvent(codePoint, Event.NOT_A_KEY_CODE, null /* next */); + } else { + event = Event.createSoftwareKeypressEvent(codePoint, Event.NOT_A_KEY_CODE, + Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, + false /* isKeyRepeat */); + } + add(event); + return this; + } + + public EventList addKey(final int keyCode) { + add(Event.createSoftwareKeypressEvent(Event.NOT_A_CODE_POINT, keyCode, + Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, + false /* isKeyRepeat */)); + return this; + } + } + + public void testDeadCircumflexSimple() { + final int MODIFIER_LETTER_CIRCUMFLEX_ACCENT = 0x02C6; + final String EXPECTED_RESULT = "aê"; + final EventList events = new EventList() + .addCodePoint('a', false) + .addCodePoint(MODIFIER_LETTER_CIRCUMFLEX_ACCENT, true) + .addCodePoint('e', false); + for (final Event event : events) { + mLatinIME.onEvent(event); + } + assertEquals("simple dead circumflex", EXPECTED_RESULT, mEditText.getText().toString()); + } + + public void testDeadCircumflexBackspace() { + final int MODIFIER_LETTER_CIRCUMFLEX_ACCENT = 0x02C6; + final String EXPECTED_RESULT = "ae"; + final EventList events = new EventList() + .addCodePoint('a', false) + .addCodePoint(MODIFIER_LETTER_CIRCUMFLEX_ACCENT, true) + .addKey(Constants.CODE_DELETE) + .addCodePoint('e', false); + for (final Event event : events) { + mLatinIME.onEvent(event); + } + assertEquals("dead circumflex backspace", EXPECTED_RESULT, mEditText.getText().toString()); + } + + public void testDeadCircumflexFeedback() { + final int MODIFIER_LETTER_CIRCUMFLEX_ACCENT = 0x02C6; + final String EXPECTED_RESULT = "a\u02C6"; + final EventList events = new EventList() + .addCodePoint('a', false) + .addCodePoint(MODIFIER_LETTER_CIRCUMFLEX_ACCENT, true); + for (final Event event : events) { + mLatinIME.onEvent(event); + } + assertEquals("dead circumflex gives feedback", EXPECTED_RESULT, + mEditText.getText().toString()); + } + + public void testDeadDiaeresisSpace() { + final int MODIFIER_LETTER_DIAERESIS = 0xA8; + final String EXPECTED_RESULT = "a\u00A8e\u00A8i"; + final EventList events = new EventList() + .addCodePoint('a', false) + .addCodePoint(MODIFIER_LETTER_DIAERESIS, true) + .addCodePoint(Constants.CODE_SPACE, false) + .addCodePoint('e', false) + .addCodePoint(MODIFIER_LETTER_DIAERESIS, true) + .addCodePoint(Constants.CODE_ENTER, false) + .addCodePoint('i', false); + for (final Event event : events) { + mLatinIME.onEvent(event); + } + assertEquals("dead diaeresis space commits the dead char", EXPECTED_RESULT, + mEditText.getText().toString()); + } + + public void testDeadAcuteLetterBackspace() { + final int MODIFIER_LETTER_ACUTE = 0xB4; + final String EXPECTED_RESULT1 = "aá"; + final String EXPECTED_RESULT2 = "a"; + final EventList events = new EventList() + .addCodePoint('a', false) + .addCodePoint(MODIFIER_LETTER_ACUTE, true) + .addCodePoint('a', false); + for (final Event event : events) { + mLatinIME.onEvent(event); + } + assertEquals("dead acute on a typed", EXPECTED_RESULT1, mEditText.getText().toString()); + mLatinIME.onEvent(Event.createSoftwareKeypressEvent(Event.NOT_A_CODE_POINT, + Constants.CODE_DELETE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, + false /* isKeyRepeat */)); + assertEquals("a with acute deleted", EXPECTED_RESULT2, mEditText.getText().toString()); + } + + public void testFinnishStroke() { + final int MODIFIER_LETTER_STROKE = '-'; + final String EXPECTED_RESULT = "x\u0110\u0127"; + final EventList events = new EventList() + .addCodePoint('x', false) + .addCodePoint(MODIFIER_LETTER_STROKE, true) + .addCodePoint('D', false) + .addCodePoint(MODIFIER_LETTER_STROKE, true) + .addCodePoint('h', false); + for (final Event event : events) { + mLatinIME.onEvent(event); + } + assertEquals("Finnish dead stroke", EXPECTED_RESULT, + mEditText.getText().toString()); + } + + public void testDoubleDeadOgonek() { + final int MODIFIER_LETTER_OGONEK = 0x02DB; + final String EXPECTED_RESULT = "txǫs\u02DBfk"; + final EventList events = new EventList() + .addCodePoint('t', false) + .addCodePoint('x', false) + .addCodePoint(MODIFIER_LETTER_OGONEK, true) + .addCodePoint('o', false) + .addCodePoint('s', false) + .addCodePoint(MODIFIER_LETTER_OGONEK, true) + .addCodePoint(MODIFIER_LETTER_OGONEK, true) + .addCodePoint('f', false) + .addCodePoint(MODIFIER_LETTER_OGONEK, true) + .addCodePoint(MODIFIER_LETTER_OGONEK, true) + .addKey(Constants.CODE_DELETE) + .addCodePoint('k', false); + for (final Event event : events) { + mLatinIME.onEvent(event); + } + assertEquals("double dead ogonek, and backspace", EXPECTED_RESULT, + mEditText.getText().toString()); + } + + public void testDeadCircumflexDeadDiaeresis() { + final int MODIFIER_LETTER_CIRCUMFLEX_ACCENT = 0x02C6; + final int MODIFIER_LETTER_DIAERESIS = 0xA8; + final String EXPECTED_RESULT = "r̂̈"; + + final EventList events = new EventList() + .addCodePoint(MODIFIER_LETTER_CIRCUMFLEX_ACCENT, true) + .addCodePoint(MODIFIER_LETTER_DIAERESIS, true) + .addCodePoint('r', false); + for (final Event event : events) { + mLatinIME.onEvent(event); + } + assertEquals("both circumflex and diaeresis on r", EXPECTED_RESULT, + mEditText.getText().toString()); + } + + public void testDeadCircumflexDeadDiaeresisBackspace() { + final int MODIFIER_LETTER_CIRCUMFLEX_ACCENT = 0x02C6; + final int MODIFIER_LETTER_DIAERESIS = 0xA8; + final String EXPECTED_RESULT = "û"; + + final EventList events = new EventList() + .addCodePoint(MODIFIER_LETTER_CIRCUMFLEX_ACCENT, true) + .addCodePoint(MODIFIER_LETTER_DIAERESIS, true) + .addKey(Constants.CODE_DELETE) + .addCodePoint('u', false); + for (final Event event : events) { + mLatinIME.onEvent(event); + } + assertEquals("dead circumflex, dead diaeresis, backspace, u", EXPECTED_RESULT, + mEditText.getText().toString()); + } + + public void testDeadCircumflexDoubleDeadDiaeresisBackspace() { + final int MODIFIER_LETTER_CIRCUMFLEX_ACCENT = 0x02C6; + final int MODIFIER_LETTER_DIAERESIS = 0xA8; + final String EXPECTED_RESULT = "\u02C6u"; + + final EventList events = new EventList() + .addCodePoint(MODIFIER_LETTER_CIRCUMFLEX_ACCENT, true) + .addCodePoint(MODIFIER_LETTER_DIAERESIS, true) + .addCodePoint(MODIFIER_LETTER_DIAERESIS, true) + .addKey(Constants.CODE_DELETE) + .addCodePoint('u', false); + for (final Event event : events) { + mLatinIME.onEvent(event); + } + assertEquals("dead circumflex, double dead diaeresis, backspace, u", EXPECTED_RESULT, + mEditText.getText().toString()); + } +} diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTestsLanguageWithoutSpaces.java b/tests/src/com/android/inputmethod/latin/InputLogicTestsLanguageWithoutSpaces.java index 2560407dc..12461c96e 100644 --- a/tests/src/com/android/inputmethod/latin/InputLogicTestsLanguageWithoutSpaces.java +++ b/tests/src/com/android/inputmethod/latin/InputLogicTestsLanguageWithoutSpaces.java @@ -19,6 +19,8 @@ package com.android.inputmethod.latin; import android.test.suitebuilder.annotation.LargeTest; import android.view.inputmethod.BaseInputConnection; +import com.android.inputmethod.latin.common.Constants; + @LargeTest public class InputLogicTestsLanguageWithoutSpaces extends InputTestsBase { public void testAutoCorrectForLanguageWithoutSpaces() { @@ -74,7 +76,7 @@ public class InputLogicTestsLanguageWithoutSpaces extends InputTestsBase { mInputConnection.setSelection(CURSOR_POS, CURSOR_POS); mLatinIME.onUpdateSelection(typedLength, typedLength, CURSOR_POS, CURSOR_POS, -1, -1); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); assertEquals("start composing inside text", -1, BaseInputConnection.getComposingSpanStart(mEditText.getText())); @@ -87,11 +89,39 @@ public class InputLogicTestsLanguageWithoutSpaces extends InputTestsBase { BaseInputConnection.getComposingSpanEnd(mEditText.getText())); } + public void testMovingCursorInsideWordAndType() { + final String WORD_TO_TYPE = "abcdefgh"; + final int typedLength = WORD_TO_TYPE.length(); + final int CURSOR_POS = 4; + changeKeyboardLocaleAndDictLocale("th", "en_US"); + type(WORD_TO_TYPE); + mLatinIME.onUpdateSelection(0, 0, typedLength, typedLength, 0, typedLength); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); + runMessages(); + mInputConnection.setSelection(CURSOR_POS, CURSOR_POS); + mLatinIME.onUpdateSelection(typedLength, typedLength, + CURSOR_POS, CURSOR_POS, 0, typedLength); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); + runMessages(); + assertEquals("move cursor inside text", 0, + BaseInputConnection.getComposingSpanStart(mEditText.getText())); + assertEquals("move cursor inside text", typedLength, + BaseInputConnection.getComposingSpanEnd(mEditText.getText())); + type("x"); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); + runMessages(); + assertEquals("start typing while cursor inside composition", CURSOR_POS, + BaseInputConnection.getComposingSpanStart(mEditText.getText())); + assertEquals("start typing while cursor inside composition", CURSOR_POS + 1, + BaseInputConnection.getComposingSpanEnd(mEditText.getText())); + } + public void testPredictions() { final String WORD_TO_TYPE = "Barack "; changeKeyboardLocaleAndDictLocale("th", "en_US"); type(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); // Make sure there is no space assertEquals("predictions in lang without spaces", "Barack", diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTestsNonEnglish.java b/tests/src/com/android/inputmethod/latin/InputLogicTestsNonEnglish.java deleted file mode 100644 index 866f8894c..000000000 --- a/tests/src/com/android/inputmethod/latin/InputLogicTestsNonEnglish.java +++ /dev/null @@ -1,124 +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; - -import android.test.suitebuilder.annotation.LargeTest; - -@LargeTest -public class InputLogicTestsNonEnglish extends InputTestsBase { - final String NEXT_WORD_PREDICTION_OPTION = "next_word_prediction"; - - public void testAutoCorrectForFrench() { - final String STRING_TO_TYPE = "irq "; - final String EXPECTED_RESULT = "ira "; - changeLanguage("fr"); - type(STRING_TO_TYPE); - assertEquals("simple auto-correct for French", EXPECTED_RESULT, - mEditText.getText().toString()); - } - - public void testManualPickThenSeparatorForFrench() { - final String WORD1_TO_TYPE = "test"; - final String WORD2_TO_TYPE = "!"; - final String EXPECTED_RESULT = "test !"; - changeLanguage("fr"); - type(WORD1_TO_TYPE); - pickSuggestionManually(WORD1_TO_TYPE); - type(WORD2_TO_TYPE); - assertEquals("manual pick then separator for French", EXPECTED_RESULT, - mEditText.getText().toString()); - } - - public void testClusteringPunctuationForFrench() { - final String WORD1_TO_TYPE = "test"; - final String WORD2_TO_TYPE = "!!?!:!"; - // In English, the expected result would be "test!!?!:!" - final String EXPECTED_RESULT = "test !!?! : !"; - changeLanguage("fr"); - type(WORD1_TO_TYPE); - pickSuggestionManually(WORD1_TO_TYPE); - type(WORD2_TO_TYPE); - assertEquals("clustering punctuation for French", EXPECTED_RESULT, - mEditText.getText().toString()); - } - - public void testWordThenSpaceThenPunctuationFromStripTwiceForFrench() { - final String WORD_TO_TYPE = "test "; - final String PUNCTUATION_FROM_STRIP = "!"; - final String EXPECTED_RESULT = "test !!"; - final boolean defaultNextWordPredictionOption = - mLatinIME.getResources().getBoolean(R.bool.config_default_next_word_prediction); - final boolean previousNextWordPredictionOption = - setBooleanPreference(NEXT_WORD_PREDICTION_OPTION, false, - defaultNextWordPredictionOption); - try { - changeLanguage("fr"); - type(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); - runMessages(); - assertTrue("type word then type space should display punctuation strip", - mLatinIME.getSuggestedWordsForTest().isPunctuationSuggestions()); - pickSuggestionManually(PUNCTUATION_FROM_STRIP); - pickSuggestionManually(PUNCTUATION_FROM_STRIP); - assertEquals("type word then type space then punctuation from strip twice for French", - EXPECTED_RESULT, mEditText.getText().toString()); - } finally { - setBooleanPreference(NEXT_WORD_PREDICTION_OPTION, previousNextWordPredictionOption, - defaultNextWordPredictionOption); - } - } - - public void testWordThenSpaceDisplaysPredictions() { - final String WORD_TO_TYPE = "beaujolais "; - final String EXPECTED_RESULT = "nouveau"; - final boolean defaultNextWordPredictionOption = - mLatinIME.getResources().getBoolean(R.bool.config_default_next_word_prediction); - final boolean previousNextWordPredictionOption = - setBooleanPreference(NEXT_WORD_PREDICTION_OPTION, true, - defaultNextWordPredictionOption); - try { - changeLanguage("fr"); - 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, suggestedWords.size() > 0 ? suggestedWords.getWord(0) : null); - } finally { - setBooleanPreference(NEXT_WORD_PREDICTION_OPTION, previousNextWordPredictionOption, - defaultNextWordPredictionOption); - } - } - - public void testAutoCorrectForGerman() { - final String STRING_TO_TYPE = "unf "; - final String EXPECTED_RESULT = "und "; - changeLanguage("de"); - type(STRING_TO_TYPE); - assertEquals("simple auto-correct for German", EXPECTED_RESULT, - mEditText.getText().toString()); - } - - public void testAutoCorrectWithUmlautForGerman() { - final String STRING_TO_TYPE = "ueber "; - final String EXPECTED_RESULT = "über "; - changeLanguage("de"); - type(STRING_TO_TYPE); - assertEquals("auto-correct with umlaut for German", EXPECTED_RESULT, - mEditText.getText().toString()); - } -} diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTestsReorderingMyanmar.java b/tests/src/com/android/inputmethod/latin/InputLogicTestsReorderingMyanmar.java deleted file mode 100644 index ab69c8592..000000000 --- a/tests/src/com/android/inputmethod/latin/InputLogicTestsReorderingMyanmar.java +++ /dev/null @@ -1,237 +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; - -import android.test.suitebuilder.annotation.LargeTest; -import android.test.suitebuilder.annotation.Suppress; -import android.util.Pair; - -/* - * Relevant characters for this test : - * Spurs the need to reorder : - * U+1031 MYANMAR VOWEL SIGN E : ေ - * U+1004 U+103A U+1039 Kinzi. It's a compound character. - * - * List of consonants : - * U+1000 MYANMAR LETTER KA က - * U+1001 MYANMAR LETTER KHA ခ - * U+1002 MYANMAR LETTER GA ဂ - * U+1003 MYANMAR LETTER GHA ဃ - * U+1004 MYANMAR LETTER NGA င - * U+1005 MYANMAR LETTER CA စ - * U+1006 MYANMAR LETTER CHA ဆ - * U+1007 MYANMAR LETTER JA ဇ - * U+1008 MYANMAR LETTER JHA ဈ - * U+1009 MYANMAR LETTER NYA ဉ - * U+100A MYANMAR LETTER NNYA ည - * U+100B MYANMAR LETTER TTA ဋ - * U+100C MYANMAR LETTER TTHA ဌ - * U+100D MYANMAR LETTER DDA ဍ - * U+100E MYANMAR LETTER DDHA ဎ - * U+100F MYANMAR LETTER NNA ဏ - * U+1010 MYANMAR LETTER TA တ - * U+1011 MYANMAR LETTER THA ထ - * U+1012 MYANMAR LETTER DA ဒ - * U+1013 MYANMAR LETTER DHA ဓ - * U+1014 MYANMAR LETTER NA န - * U+1015 MYANMAR LETTER PA ပ - * U+1016 MYANMAR LETTER PHA ဖ - * U+1017 MYANMAR LETTER BA ဗ - * U+1018 MYANMAR LETTER BHA ဘ - * U+1019 MYANMAR LETTER MA မ - * U+101A MYANMAR LETTER YA ယ - * U+101B MYANMAR LETTER RA ရ - * U+101C MYANMAR LETTER LA လ - * U+101D MYANMAR LETTER WA ဝ - * U+101E MYANMAR LETTER SA သ - * U+101F MYANMAR LETTER HA ဟ - * U+1020 MYANMAR LETTER LLA ဠ - * U+103F MYANMAR LETTER GREAT SA ဿ - * - * List of medials : - * U+103B MYANMAR CONSONANT SIGN MEDIAL YA ျ - * U+103C MYANMAR CONSONANT SIGN MEDIAL RA ြ - * U+103D MYANMAR CONSONANT SIGN MEDIAL WA ွ - * U+103E MYANMAR CONSONANT SIGN MEDIAL HA ှ - * U+105E MYANMAR CONSONANT SIGN MON MEDIAL NA ၞ - * U+105F MYANMAR CONSONANT SIGN MON MEDIAL MA ၟ - * U+1060 MYANMAR CONSONANT SIGN MON MEDIAL LA ၠ - * U+1082 MYANMAR CONSONANT SIGN SHAN MEDIAL WA ႂ - * - * Other relevant characters : - * U+200C ZERO WIDTH NON-JOINER - * U+200B ZERO WIDTH SPACE - */ - -@LargeTest -// These tests are inactive until the combining code for Myanmar Reordering is sorted out. -@Suppress -@SuppressWarnings("rawtypes") -public class InputLogicTestsReorderingMyanmar extends InputTestsBase { - // The tests are formatted as follows. - // Each test is an entry in the array of Pair arrays. - - // One test is an array of pairs. Each pair contains, in the `first' member, - // the code points that the next key press should contain. In the `second' - // member is stored the string that should be in the text view after this - // key press. - - private static final Pair[][] TESTS = { - - // Tests for U+1031 MYANMAR VOWEL SIGN E : ေ - new Pair[] { // Type : U+1031 U+1000 U+101F ေ က ဟ - Pair.create(new int[] { 0x1031 }, "\u1031"), // ေ - Pair.create(new int[] { 0x1000 }, "\u1000\u1031"), // ကေ - Pair.create(new int[] { 0x101F }, "\u1000\u1031\u101F") // ကေဟ - }, - - new Pair[] { // Type : U+1000 U+1031 U+101F က ေ ဟ - Pair.create(new int[] { 0x1000 }, "\u1000"), // က - Pair.create(new int[] { 0x1031 }, "\u1000\u200B\u1031"), // ကေ - Pair.create(new int[] { 0x101F }, "\u1000\u101F\u1031") // ကဟေ - }, - - new Pair[] { // Type : U+1031 U+101D U+103E U+1018 ေ ဝ ှ ဘ - Pair.create(new int[] { 0x1031 }, "\u1031"), // ေ - Pair.create(new int[] { 0x101D }, "\u101D\u1031"), // ဝေ - Pair.create(new int[] { 0x103E }, "\u101D\u103E\u1031"), // ဝှေ - Pair.create(new int[] { 0x1018 }, "\u101D\u103E\u1031\u1018") // ဝှေဘ - }, - - new Pair[] { // Type : U+1031 U+1014 U+1031 U+1000 U+102C U+1004 U+103A U+1038 U+101C - // U+102C U+1038 U+104B ေ န ေ က ာ င ် း လ ာ း ။ - Pair.create(new int[] { 0x1031 }, "\u1031"), // ေ - Pair.create(new int[] { 0x1014 }, "\u1014\u1031"), // နေ - Pair.create(new int[] { 0x1031 }, "\u1014\u1031\u1031"), // နေေ - Pair.create(new int[] { 0x1000 }, "\u1014\u1031\u1000\u1031"), // နေကေ - Pair.create(new int[] { 0x102C }, "\u1014\u1031\u1000\u1031\u102C"), // နေကော - Pair.create(new int[] { 0x1004 }, "\u1014\u1031\u1000\u1031\u102C\u1004"), // နေကောင - Pair.create(new int[] { 0x103A }, // နေကောင် - "\u1014\u1031\u1000\u1031\u102C\u1004\u103A"), - Pair.create(new int[] { 0x1038 }, // နေကောင်း - "\u1014\u1031\u1000\u1031\u102C\u1004\u103A\u1038"), - Pair.create(new int[] { 0x101C }, // နေကောင်းလ - "\u1014\u1031\u1000\u1031\u102C\u1004\u103A\u1038\u101C"), - Pair.create(new int[] { 0x102C }, // နေကောင်းလာ - "\u1014\u1031\u1000\u1031\u102C\u1004\u103A\u1038\u101C\u102C"), - Pair.create(new int[] { 0x1038 }, // နေကောင်းလား - "\u1014\u1031\u1000\u1031\u102C\u1004\u103A\u1038\u101C\u102C\u1038"), - Pair.create(new int[] { 0x104B }, // နေကောင်းလား။ - "\u1014\u1031\u1000\u1031\u102C\u1004\u103A\u1038\u101C\u102C\u1038\u104B") - }, - - new Pair[] { // Type : U+1031 U+1031 U+1031 U+1000 ေ ေ ေ က - Pair.create(new int[] { 0x1031 }, "\u1031"), // ေ - Pair.create(new int[] { 0x1031 }, "\u1031\u1031"), // ေေ - Pair.create(new int[] { 0x1031 }, "\u1031\u1031\u1031"), // U+1031ေေေ - Pair.create(new int[] { 0x1000 }, "\u1031\u1031\u1000\u1031") // ေေကေ - }, - - new Pair[] { // Type : U+1031 U+1001 U+103B U+103D U+1038 ေ ခ ျ ွ း - Pair.create(new int[] { 0x1031 }, "\u1031"), // ေ - Pair.create(new int[] { 0x1001 }, "\u1001\u1031"), // ခေ - Pair.create(new int[] { 0x103B }, "\u1001\u103B\u1031"), // ချေ - Pair.create(new int[] { 0x103D }, "\u1001\u103B\u103D\u1031"), // ချွေ - Pair.create(new int[] { 0x1038 }, "\u1001\u103B\u103D\u1031\u1038") // ချွေး - }, - - // Tests for Kinzi U+1004 U+103A U+1039 : - - /* Kinzi reordering is not implemented yet. Uncomment these tests when it is. - - new Pair[] { // Type : U+1021 U+1002 (U+1004 U+103A U+1039) - // U+101C U+1014 U+103A အ ဂ (င ် ္) လ န ် - Pair.create(new int[] { 0x1021 }, "\u1021"), // အ - Pair.create(new int[] { 0x1002 }, "\u1021\u1002"), // အဂ - Pair.create(new int[] { 0x1004, 0x103A, 0x1039 }, // အင်္ဂ - "\u1021\u1004\u103A\u1039\u1002"), - Pair.create(new int[] { 0x101C }, // အင်္ဂလ - "\u1021\u1004\u103A\u1039\u1002\u101C"), - Pair.create(new int[] { 0x1014 }, // အင်္ဂလန - "\u1021\u1004\u103A\u1039\u1002\u101C\u1014"), - Pair.create(new int[] { 0x103A }, // အင်္ဂလန် - "\u1021\u1004\u103A\u1039\u1002\u101C\u1014\u103A") - }, - - new Pair[] { //Type : kinzi after a whole syllable U+101E U+1001 U+103B U+102D U+102F - // (U+1004 U+103A U+1039) U+1004 U+103A U+1038 သ ခ ျ ိ ု င ် ္ င ် း - Pair.create(new int[] { 0x101E }, "\u101E"), // သခ - Pair.create(new int[] { 0x1001 }, "\u101E\u1001"), // သခ - Pair.create(new int[] { 0x103B }, "\u101E\u1001\u103B"), // သချ - Pair.create(new int[] { 0x102D }, "\u101E\u1001\u103B\u102D"), // သချိ - Pair.create(new int[] { 0x102F }, "\u101E\u1001\u103B\u102D\u102F"), // သချို - Pair.create(new int[] { 0x1004, 0x103A, 0x1039}, // သင်္ချို - "\u101E\u1004\u103A\u1039\u1001\u103B\u102D\u102F"), - Pair.create(new int[] { 0x1004 }, // သင်္ချိုင - "\u101E\u1004\u103A\u1039\u1001\u103B\u102D\u102F\u1004"), - Pair.create(new int[] { 0x103A }, // သင်္ချိုင် - "\u101E\u1004\u103A\u1039\u1001\u103B\u102D\u102F\u1004\u103A"), - Pair.create(new int[] { 0x1038 }, // သင်္ချိုင်း - "\u101E\u1004\u103A\u1039\u1001\u103B\u102D\u102F\u1004\u103A\u1038") - }, - - new Pair[] { // Type : kinzi after the consonant U+101E U+1001 (U+1004 U+103A U+1039) - // U+103B U+102D U+102F U+1004 U+103A U+1038 သ ခ င ် ္ ျ ိ ု င ် း - Pair.create(new int[] { 0x101E }, "\u101E"), // သခ - Pair.create(new int[] { 0x1001 }, "\u101E\u1001"), // သခ - Pair.create(new int[] { 0x1004, 0x103A, 0x1039 }, // သင်္ခ - "\u101E\u1004\u103A\u1039\u1001"), - Pair.create(new int[] { 0x103B }, // သင်္ချ - "\u101E\u1004\u103A\u1039\u1001\u103B"), - Pair.create(new int[] { 0x102D }, // သင်္ချိ - "\u101E\u1004\u103A\u1039\u1001\u103B\u102D"), - Pair.create(new int[] { 0x102F }, // သင်္ချို - "\u101E\u1004\u103A\u1039\u1001\u103B\u102D\u102F"), - Pair.create(new int[] { 0x1004 }, // သင်္ချိုင - "\u101E\u1004\u103A\u1039\u1001\u103B\u102D\u102F\u1004"), - Pair.create(new int[] { 0x103A }, // သင်္ချိုင် - "\u101E\u1004\u103A\u1039\u1001\u103B\u102D\u102F\u1004\u103A"), - Pair.create(new int[] { 0x1038 }, // သင်္ချိုင်း - "\u101E\u1004\u103A\u1039\u1001\u103B\u102D\u102F\u1004\u103A\u1038") - }, - */ - }; - - @SuppressWarnings("unchecked") - private void doMyanmarTest(final int testNumber, final Pair[] test) { - int stepNumber = 0; - for (final Pair<int[], String> step : test) { - ++stepNumber; - final int[] input = step.first; - final String expectedResult = step.second; - if (input.length > 1) { - mLatinIME.onTextInput(new String(input, 0, input.length)); - } else { - type(input[0]); - } - assertEquals("Myanmar reordering test " + testNumber + ", step " + stepNumber, - expectedResult, mEditText.getText().toString()); - } - } - - public void testMyanmarReordering() { - int testNumber = 0; - changeLanguage("my_MM", "CombiningRules=MyanmarReordering"); - for (final Pair[] test : TESTS) { - // Small trick to reset LatinIME : setText("") and send updateSelection with values - // LatinIME has never seen, and cursor pos 0,0. - mEditText.setText(""); - mLatinIME.onUpdateSelection(1, 1, 0, 0, -1, -1); - doMyanmarTest(++testNumber, test); - } - } -} diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java index 986fb1097..dead53da2 100644 --- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java +++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java @@ -18,6 +18,7 @@ package com.android.inputmethod.latin; import android.content.Context; import android.content.SharedPreferences; +import android.graphics.Point; import android.os.Looper; import android.preference.PreferenceManager; import android.test.ServiceTestCase; @@ -36,12 +37,17 @@ import android.widget.EditText; import android.widget.FrameLayout; import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils; +import com.android.inputmethod.event.Event; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.latin.Dictionary.PhonyDictionary; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; +import com.android.inputmethod.latin.common.Constants; +import com.android.inputmethod.latin.common.InputPointers; +import com.android.inputmethod.latin.common.LocaleUtils; +import com.android.inputmethod.latin.common.StringUtils; 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; @@ -52,21 +58,28 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { // 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"; + private static final boolean DEFAULT_AUTO_CORRECTION = true; // The message that sets the underline is posted with a 500 ms delay - protected static final int DELAY_TO_WAIT_FOR_UNDERLINE = 500; + protected static final int DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS = 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 static final int DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS = 200; + // We wait for gesture computation for this delay + protected static final int DELAY_TO_WAIT_FOR_GESTURE_MILLIS = 200; + // If a dictionary takes longer to load, we could have serious problems. + private final int TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS = 5; + + // Type for a test phony dictionary + private static final String TYPE_TEST = "test"; + private static final PhonyDictionary DICTIONARY_TEST = new PhonyDictionary(TYPE_TEST); protected LatinIME mLatinIME; protected Keyboard mKeyboard; protected MyEditText mEditText; protected View mInputView; protected InputConnection mInputConnection; + private boolean mPreviousAutoCorrectSetting; private boolean mPreviousBigramPredictionSettings; - private String mPreviousAutoCorrectSetting; // A helper class to ease span tests public static class SpanGetter { @@ -94,12 +107,15 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { throw new RuntimeException("Expected one span, found " + spans.length); } } + public SuggestionSpan getSpan() { + return (SuggestionSpan) mSpan; + } public boolean isAutoCorrectionIndicator() { return (mSpan instanceof SuggestionSpan) && - 0 != (SuggestionSpan.FLAG_AUTO_CORRECTION & ((SuggestionSpan)mSpan).getFlags()); + 0 != (SuggestionSpan.FLAG_AUTO_CORRECTION & getSpan().getFlags()); } public String[] getSuggestions() { - return ((SuggestionSpan)mSpan).getSuggestions(); + return getSpan().getSuggestions(); } } @@ -140,8 +156,6 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { super(LatinIMEForTests.class); } - // TODO: Isn't there a way to make this generic somehow? We can take a <T> and return a <T> - // but we'd have to dispatch types on editor.put...() functions protected boolean setBooleanPreference(final String key, final boolean value, final boolean defaultValue) { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mLatinIME); @@ -152,6 +166,11 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { return previousSetting; } + protected boolean getBooleanPreference(final String key, final boolean defaultValue) { + return PreferenceManager.getDefaultSharedPreferences(mLatinIME) + .getBoolean(key, defaultValue); + } + protected String setStringPreference(final String key, final String value, final String defaultValue) { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mLatinIME); @@ -182,13 +201,17 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { | InputType.TYPE_TEXT_FLAG_MULTI_LINE; mEditText.setInputType(inputType); mEditText.setEnabled(true); + mLastCursorPos = 0; + if (null == Looper.myLooper()) { + Looper.prepare(); + } setupService(); mLatinIME = getService(); 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); + mPreviousAutoCorrectSetting = setBooleanPreference(Settings.PREF_AUTO_CORRECTION, + DEFAULT_AUTO_CORRECTION, DEFAULT_AUTO_CORRECTION); mLatinIME.onCreate(); EditorInfo ei = new EditorInfo(); final InputConnection ic = mEditText.onCreateInputConnection(ei); @@ -207,7 +230,7 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { // 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); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); } @@ -219,8 +242,8 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { mLatinIME.mHandler.removeAllMessages(); setBooleanPreference(Settings.PREF_BIGRAM_PREDICTIONS, mPreviousBigramPredictionSettings, true /* defaultValue */); - setStringPreference(Settings.PREF_AUTO_CORRECTION_THRESHOLD, mPreviousAutoCorrectSetting, - DEFAULT_AUTO_CORRECTION_THRESHOLD); + setBooleanPreference(Settings.PREF_AUTO_CORRECTION, mPreviousAutoCorrectSetting, + DEFAULT_AUTO_CORRECTION); setDebugMode(false); mLatinIME.recycle(); super.tearDown(); @@ -236,7 +259,7 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { // Now, Looper#loop() never exits in normal operation unless the Looper#quit() method // is called, which has a lot of bad side effects. We can however just throw an exception // in the runnable which will unwind the stack and allow us to exit. - private final class InterruptRunMessagesException extends RuntimeException { + final class InterruptRunMessagesException extends RuntimeException { // Empty class } protected void runMessages() { @@ -263,14 +286,16 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { // but keep them in mind if something breaks. Commenting them out as is should work. //mLatinIME.onPressKey(codePoint, 0 /* repeatCount */, true /* isSinglePointer */); final Key key = mKeyboard.getKey(codePoint); + final Event event; if (key == null) { - mLatinIME.onCodeInput(codePoint, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, - isKeyRepeat); + event = Event.createSoftwareKeypressEvent(codePoint, Event.NOT_A_KEY_CODE, + Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, isKeyRepeat); } else { final int x = key.getX() + key.getWidth() / 2; final int y = key.getY() + key.getHeight() / 2; - mLatinIME.onCodeInput(codePoint, x, y, isKeyRepeat); + event = LatinIME.createSoftwareKeypressEvent(codePoint, x, y, isKeyRepeat); } + mLatinIME.onEvent(event); // Also see the comment at the top of this function about onReleaseKey //mLatinIME.onReleaseKey(codePoint, false /* withSliding */); } @@ -289,6 +314,46 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { } } + protected Point getXY(final int codePoint) { + final Key key = mKeyboard.getKey(codePoint); + if (key == null) { + throw new RuntimeException("Code point not on the keyboard"); + } + return new Point(key.getX() + key.getWidth() / 2, key.getY() + key.getHeight() / 2); + } + + protected void gesture(final String stringToGesture) { + if (StringUtils.codePointCount(stringToGesture) < 2) { + throw new RuntimeException("Can't gesture strings less than 2 chars long"); + } + + mLatinIME.onStartBatchInput(); + final int startCodePoint = stringToGesture.codePointAt(0); + Point oldPoint = getXY(startCodePoint); + int timestamp = 0; // In milliseconds since the start of the gesture + final InputPointers pointers = new InputPointers(Constants.DEFAULT_GESTURE_POINTS_CAPACITY); + pointers.addPointer(oldPoint.x, oldPoint.y, 0 /* pointerId */, timestamp); + + for (int i = Character.charCount(startCodePoint); i < stringToGesture.length(); + i = stringToGesture.offsetByCodePoints(i, 1)) { + final Point newPoint = getXY(stringToGesture.codePointAt(i)); + // Arbitrarily 0.5s between letters and 0.1 between events. Refine this later if needed. + final int STEPS = 5; + for (int j = 0; j < STEPS; ++j) { + timestamp += 100; + pointers.addPointer(oldPoint.x + ((newPoint.x - oldPoint.x) * j) / STEPS, + oldPoint.y + ((newPoint.y - oldPoint.y) * j) / STEPS, + 0 /* pointerId */, timestamp); + } + oldPoint.x = newPoint.x; + oldPoint.y = newPoint.y; + mLatinIME.onUpdateBatchInput(pointers); + } + mLatinIME.onEndBatchInput(pointers); + sleep(DELAY_TO_WAIT_FOR_GESTURE_MILLIS); + runMessages(); + } + protected void waitForDictionariesToBeLoaded() { try { mLatinIME.waitForLoadingDictionaries( @@ -329,7 +394,7 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { false /* isAuxiliary */, false /* overridesImplicitlyEnabledSubtype */, 0 /* id */); - SubtypeSwitcher.getInstance().forceSubtype(subtype); + RichInputMethodManager.forceSubtype(subtype); mLatinIME.onCurrentInputMethodSubtypeChanged(subtype); runMessages(); mKeyboard = mLatinIME.mKeyboardSwitcher.getKeyboard(); @@ -346,8 +411,9 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { } protected void pickSuggestionManually(final String suggestion) { - mLatinIME.pickSuggestionManually(new SuggestedWordInfo(suggestion, 1, - SuggestedWordInfo.KIND_CORRECTION, null /* sourceDict */, + mLatinIME.pickSuggestionManually(new SuggestedWordInfo(suggestion, + "" /* prevWordsContext */, 1 /* score */, + SuggestedWordInfo.KIND_CORRECTION, DICTIONARY_TEST, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */)); } @@ -358,4 +424,40 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { Thread.sleep(milliseconds); } catch (InterruptedException e) {} } + + // Some helper methods to manage the mock cursor position + // DO NOT CALL LatinIME#onUpdateSelection IF YOU WANT TO USE THOSE + int mLastCursorPos = 0; + /** + * Move the cached cursor position to the passed position and send onUpdateSelection to LatinIME + */ + protected int sendUpdateForCursorMoveTo(final int position) { + mInputConnection.setSelection(position, position); + mLatinIME.onUpdateSelection(mLastCursorPos, mLastCursorPos, position, position, -1, -1); + mLastCursorPos = position; + return position; + } + + /** + * Move the cached cursor position by the passed amount and send onUpdateSelection to LatinIME + */ + protected int sendUpdateForCursorMoveBy(final int offset) { + final int lastPos = mEditText.getText().length(); + final int requestedPosition = mLastCursorPos + offset; + if (requestedPosition < 0) { + return sendUpdateForCursorMoveTo(0); + } else if (requestedPosition > lastPos) { + return sendUpdateForCursorMoveTo(lastPos); + } else { + return sendUpdateForCursorMoveTo(requestedPosition); + } + } + + /** + * Move the cached cursor position to the end of the line and send onUpdateSelection to LatinIME + */ + protected int sendUpdateForCursorMoveToEndOfLine() { + final int lastPos = mEditText.getText().length(); + return sendUpdateForCursorMoveTo(lastPos); + } } diff --git a/tests/src/com/android/inputmethod/latin/LatinIMEForTests.java b/tests/src/com/android/inputmethod/latin/LatinIMEForTests.java index e47c55736..035c8d7ce 100644 --- a/tests/src/com/android/inputmethod/latin/LatinIMEForTests.java +++ b/tests/src/com/android/inputmethod/latin/LatinIMEForTests.java @@ -21,4 +21,16 @@ public class LatinIMEForTests extends LatinIME { public boolean isInputViewShown() { return true; } + + private boolean deallocateMemoryWasPerformed = false; + + @Override + protected void deallocateMemory() { + super.deallocateMemory(); + deallocateMemoryWasPerformed = true; + } + + public boolean getDeallocateMemoryWasPerformed() { + return deallocateMemoryWasPerformed; + } } diff --git a/tests/src/com/android/inputmethod/latin/LatinImeStressTests.java b/tests/src/com/android/inputmethod/latin/LatinImeStressTests.java index f5e993de8..22114b7a0 100644 --- a/tests/src/com/android/inputmethod/latin/LatinImeStressTests.java +++ b/tests/src/com/android/inputmethod/latin/LatinImeStressTests.java @@ -18,7 +18,7 @@ package com.android.inputmethod.latin; import android.test.suitebuilder.annotation.LargeTest; -import com.android.inputmethod.latin.makedict.CodePointUtils; +import com.android.inputmethod.latin.common.CodePointUtils; import java.util.Random; diff --git a/tests/src/com/android/inputmethod/latin/LatinImeTests.java b/tests/src/com/android/inputmethod/latin/LatinImeTests.java new file mode 100644 index 000000000..c6f631328 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/LatinImeTests.java @@ -0,0 +1,40 @@ +/* + * 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; + +import android.test.suitebuilder.annotation.LargeTest; + +@LargeTest +public class LatinImeTests extends InputTestsBase { + public void testDeferredDeallocation_doesntHappenBeforeTimeout() { + mLatinIME.mHandler.onFinishInputView(true); + runMessages(); + sleep(1000); // 1s + runMessages(); + assertFalse("memory deallocation performed before timeout passed", + ((LatinIMEForTests)mLatinIME).getDeallocateMemoryWasPerformed()); + } + + public void testDeferredDeallocation_doesHappenAfterTimeout() { + mLatinIME.mHandler.onFinishInputView(true); + runMessages(); + sleep(11000); // 11s (timeout is at 10s) + runMessages(); + assertTrue("memory deallocation not performed although timeout passed", + ((LatinIMEForTests)mLatinIME).getDeallocateMemoryWasPerformed()); + } +} diff --git a/tests/src/com/android/inputmethod/latin/NgramContextTests.java b/tests/src/com/android/inputmethod/latin/NgramContextTests.java new file mode 100644 index 000000000..0a662db82 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/NgramContextTests.java @@ -0,0 +1,145 @@ +/* + * 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; + +import com.android.inputmethod.latin.NgramContext.WordInfo; +import com.android.inputmethod.latin.settings.SpacingAndPunctuations; +import com.android.inputmethod.latin.utils.NgramContextUtils; + +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + +@SmallTest +public class NgramContextTests extends AndroidTestCase { + public void testConstruct() { + assertEquals(new NgramContext(new WordInfo("a")), new NgramContext(new WordInfo("a"))); + assertEquals(new NgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO), + new NgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO)); + assertEquals(new NgramContext(WordInfo.EMPTY_WORD_INFO), + new NgramContext(WordInfo.EMPTY_WORD_INFO)); + assertEquals(new NgramContext(WordInfo.EMPTY_WORD_INFO), + new NgramContext(WordInfo.EMPTY_WORD_INFO)); + } + + public void testIsBeginningOfSentenceContext() { + assertFalse(new NgramContext().isBeginningOfSentenceContext()); + assertTrue(new NgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO) + .isBeginningOfSentenceContext()); + assertTrue(NgramContext.BEGINNING_OF_SENTENCE.isBeginningOfSentenceContext()); + assertFalse(new NgramContext(new WordInfo("a")).isBeginningOfSentenceContext()); + assertFalse(new NgramContext(new WordInfo("")).isBeginningOfSentenceContext()); + assertFalse(new NgramContext(WordInfo.EMPTY_WORD_INFO).isBeginningOfSentenceContext()); + assertTrue(new NgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO, new WordInfo("a")) + .isBeginningOfSentenceContext()); + assertFalse(new NgramContext(new WordInfo("a"), WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO) + .isBeginningOfSentenceContext()); + assertFalse(new NgramContext( + WordInfo.EMPTY_WORD_INFO, WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO) + .isBeginningOfSentenceContext()); + } + + public void testGetNextNgramContext() { + final NgramContext ngramContext_a = new NgramContext(new WordInfo("a")); + final NgramContext ngramContext_b_a = + ngramContext_a.getNextNgramContext(new WordInfo("b")); + assertEquals("b", ngramContext_b_a.getNthPrevWord(1)); + assertEquals("a", ngramContext_b_a.getNthPrevWord(2)); + final NgramContext ngramContext_bos_b = + ngramContext_b_a.getNextNgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO); + assertTrue(ngramContext_bos_b.isBeginningOfSentenceContext()); + assertEquals("b", ngramContext_bos_b.getNthPrevWord(2)); + final NgramContext ngramContext_c_bos = + ngramContext_b_a.getNextNgramContext(new WordInfo("c")); + assertEquals("c", ngramContext_c_bos.getNthPrevWord(1)); + } + + public void testExtractPrevWordsContextTest() { + final NgramContext ngramContext_bos = + new NgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO); + assertEquals("<S>", ngramContext_bos.extractPrevWordsContext()); + final NgramContext ngramContext_a = new NgramContext(new WordInfo("a")); + final NgramContext ngramContext_b_a = + ngramContext_a.getNextNgramContext(new WordInfo("b")); + assertEquals("b", ngramContext_b_a.getNthPrevWord(1)); + assertEquals("a", ngramContext_b_a.getNthPrevWord(2)); + assertEquals("a b", ngramContext_b_a.extractPrevWordsContext()); + + final NgramContext ngramContext_bos_b = + ngramContext_b_a.getNextNgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO); + assertTrue(ngramContext_bos_b.isBeginningOfSentenceContext()); + assertEquals("b", ngramContext_bos_b.getNthPrevWord(2)); + assertEquals("a b <S>", ngramContext_bos_b.extractPrevWordsContext()); + + final NgramContext ngramContext_empty = new NgramContext(WordInfo.EMPTY_WORD_INFO); + assertEquals("", ngramContext_empty.extractPrevWordsContext()); + final NgramContext ngramContext_a_empty = + ngramContext_empty.getNextNgramContext(new WordInfo("a")); + assertEquals("a", ngramContext_a_empty.getNthPrevWord(1)); + assertEquals("a", ngramContext_a_empty.extractPrevWordsContext()); + } + + public void testExtractPrevWordsContextArray() { + final NgramContext ngramContext_bos = + new NgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO); + assertEquals("<S>", ngramContext_bos.extractPrevWordsContext()); + assertEquals(1, ngramContext_bos.extractPrevWordsContextArray().length); + final NgramContext ngramContext_a = new NgramContext(new WordInfo("a")); + final NgramContext ngramContext_b_a = + ngramContext_a.getNextNgramContext(new WordInfo("b")); + assertEquals(2, ngramContext_b_a.extractPrevWordsContextArray().length); + assertEquals("b", ngramContext_b_a.getNthPrevWord(1)); + assertEquals("a", ngramContext_b_a.getNthPrevWord(2)); + assertEquals("a", ngramContext_b_a.extractPrevWordsContextArray()[0]); + assertEquals("b", ngramContext_b_a.extractPrevWordsContextArray()[1]); + + final NgramContext ngramContext_bos_b = + ngramContext_b_a.getNextNgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO); + assertTrue(ngramContext_bos_b.isBeginningOfSentenceContext()); + assertEquals(3, ngramContext_bos_b.extractPrevWordsContextArray().length); + assertEquals("b", ngramContext_bos_b.getNthPrevWord(2)); + assertEquals("a", ngramContext_bos_b.extractPrevWordsContextArray()[0]); + assertEquals("b", ngramContext_bos_b.extractPrevWordsContextArray()[1]); + assertEquals("<S>", ngramContext_bos_b.extractPrevWordsContextArray()[2]); + + final NgramContext ngramContext_empty = new NgramContext(WordInfo.EMPTY_WORD_INFO); + assertEquals(0, ngramContext_empty.extractPrevWordsContextArray().length); + final NgramContext ngramContext_a_empty = + ngramContext_empty.getNextNgramContext(new WordInfo("a")); + assertEquals(1, ngramContext_a_empty.extractPrevWordsContextArray().length); + assertEquals("a", ngramContext_a_empty.extractPrevWordsContextArray()[0]); + } + + public void testGetNgramContextFromNthPreviousWord() { + SpacingAndPunctuations spacingAndPunctuations = new SpacingAndPunctuations( + mContext.getResources()); + assertEquals("<S>", NgramContextUtils.getNgramContextFromNthPreviousWord("", + spacingAndPunctuations, 1).extractPrevWordsContext()); + assertEquals("<S> b", NgramContextUtils.getNgramContextFromNthPreviousWord("a. b ", + spacingAndPunctuations, 1).extractPrevWordsContext()); + assertEquals("<S> b", NgramContextUtils.getNgramContextFromNthPreviousWord("a? b ", + spacingAndPunctuations, 1).extractPrevWordsContext()); + assertEquals("<S> b", NgramContextUtils.getNgramContextFromNthPreviousWord("a! b ", + spacingAndPunctuations, 1).extractPrevWordsContext()); + assertEquals("<S> b", NgramContextUtils.getNgramContextFromNthPreviousWord("a\nb ", + spacingAndPunctuations, 1).extractPrevWordsContext()); + assertEquals("<S> a b", NgramContextUtils.getNgramContextFromNthPreviousWord("a b ", + spacingAndPunctuations, 1).extractPrevWordsContext()); + assertFalse(NgramContextUtils + .getNgramContextFromNthPreviousWord("a b c d e", spacingAndPunctuations, 1) + .extractPrevWordsContext().startsWith("<S>")); + } +} diff --git a/tests/src/com/android/inputmethod/latin/PunctuationTests.java b/tests/src/com/android/inputmethod/latin/PunctuationTests.java index 64750fbda..3537918de 100644 --- a/tests/src/com/android/inputmethod/latin/PunctuationTests.java +++ b/tests/src/com/android/inputmethod/latin/PunctuationTests.java @@ -38,7 +38,7 @@ public class PunctuationTests extends InputTestsBase { try { mLatinIME.loadSettings(); type(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); assertTrue("type word then type space should display punctuation strip", mLatinIME.getSuggestedWordsForTest().isPunctuationSuggestions()); diff --git a/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java b/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java index f9d72269e..08779b9d3 100644 --- a/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java +++ b/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java @@ -30,12 +30,12 @@ import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputConnectionWrapper; -import com.android.inputmethod.latin.PrevWordsInfo.WordInfo; +import com.android.inputmethod.latin.common.Constants; +import com.android.inputmethod.latin.common.StringUtils; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; -import com.android.inputmethod.latin.utils.PrevWordsInfoUtils; +import com.android.inputmethod.latin.utils.NgramContextUtils; import com.android.inputmethod.latin.utils.RunInLocale; import com.android.inputmethod.latin.utils.ScriptUtils; -import com.android.inputmethod.latin.utils.StringUtils; import com.android.inputmethod.latin.utils.TextRange; import java.util.Locale; @@ -137,7 +137,7 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase { } } - private class MockInputMethodService extends InputMethodService { + static class MockInputMethodService extends InputMethodService { private MockConnection mMockConnection; public void setInputConnection(final MockConnection mockConnection) { mMockConnection = mockConnection; @@ -158,26 +158,25 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase { */ public void testGetPreviousWord() { // If one of the following cases breaks, the bigram suggestions won't work. - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc def", mSpacingAndPunctuations, 2).mPrevWordsInfo[0].mWord, "abc"); - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc", mSpacingAndPunctuations, 2), PrevWordsInfo.BEGINNING_OF_SENTENCE); - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc. def", mSpacingAndPunctuations, 2), PrevWordsInfo.BEGINNING_OF_SENTENCE); - - assertFalse(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc def", mSpacingAndPunctuations, 2).mPrevWordsInfo[0].mIsBeginningOfSentence); - assertTrue(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc", mSpacingAndPunctuations, 2).mPrevWordsInfo[0].mIsBeginningOfSentence); + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc def", mSpacingAndPunctuations, 2).getNthPrevWord(1), "abc"); + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc", mSpacingAndPunctuations, 2), NgramContext.BEGINNING_OF_SENTENCE); + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc. def", mSpacingAndPunctuations, 2), NgramContext.BEGINNING_OF_SENTENCE); + + assertFalse(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc def", mSpacingAndPunctuations, 2).isBeginningOfSentenceContext()); + assertTrue(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc", mSpacingAndPunctuations, 2).isBeginningOfSentenceContext()); // For n-gram - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc def", mSpacingAndPunctuations, 1).mPrevWordsInfo[0].mWord, "def"); - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc def", mSpacingAndPunctuations, 1).mPrevWordsInfo[1].mWord, "abc"); - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc def", mSpacingAndPunctuations, 2).mPrevWordsInfo[1], - WordInfo.BEGINNING_OF_SENTENCE); + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc def", mSpacingAndPunctuations, 1).getNthPrevWord(1), "def"); + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc def", mSpacingAndPunctuations, 1).getNthPrevWord(2), "abc"); + assertTrue(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc def", mSpacingAndPunctuations, 2).isNthPrevWordBeginningOfSentence(2)); // The following tests reflect the current behavior of the function // RichInputConnection#getNthPreviousWord. @@ -186,33 +185,37 @@ 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(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc def ", mSpacingAndPunctuations, 2).mPrevWordsInfo[0].mWord, "abc"); - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc def.", mSpacingAndPunctuations, 2).mPrevWordsInfo[0].mWord, "abc"); - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc def .", mSpacingAndPunctuations, 2).mPrevWordsInfo[0].mWord, "def"); - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc ", mSpacingAndPunctuations, 2), PrevWordsInfo.BEGINNING_OF_SENTENCE); - - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc def", mSpacingAndPunctuations, 1).mPrevWordsInfo[0].mWord, "def"); - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc def ", mSpacingAndPunctuations, 1).mPrevWordsInfo[0].mWord, "def"); - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc 'def", mSpacingAndPunctuations, 1).mPrevWordsInfo[0].mWord, "'def"); - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc def.", mSpacingAndPunctuations, 1), PrevWordsInfo.BEGINNING_OF_SENTENCE); - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc def .", mSpacingAndPunctuations, 1), PrevWordsInfo.BEGINNING_OF_SENTENCE); - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc, def", mSpacingAndPunctuations, 2), PrevWordsInfo.EMPTY_PREV_WORDS_INFO); - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc? def", mSpacingAndPunctuations, 2), PrevWordsInfo.EMPTY_PREV_WORDS_INFO); - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc! def", mSpacingAndPunctuations, 2), PrevWordsInfo.EMPTY_PREV_WORDS_INFO); - assertEquals(PrevWordsInfoUtils.getPrevWordsInfoFromNthPreviousWord( - "abc 'def", mSpacingAndPunctuations, 2), PrevWordsInfo.EMPTY_PREV_WORDS_INFO); + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc def ", mSpacingAndPunctuations, 2).getNthPrevWord(1), "abc"); + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc def.", mSpacingAndPunctuations, 2).getNthPrevWord(1), "abc"); + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc def .", mSpacingAndPunctuations, 2).getNthPrevWord(1), "def"); + assertTrue(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc ", mSpacingAndPunctuations, 2).isBeginningOfSentenceContext()); + + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc def", mSpacingAndPunctuations, 1).getNthPrevWord(1), "def"); + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc def ", mSpacingAndPunctuations, 1).getNthPrevWord(1), "def"); + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc 'def", mSpacingAndPunctuations, 1).getNthPrevWord(1), "'def"); + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc def.", mSpacingAndPunctuations, 1), NgramContext.BEGINNING_OF_SENTENCE); + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc def .", mSpacingAndPunctuations, 1), NgramContext.BEGINNING_OF_SENTENCE); + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc, def", mSpacingAndPunctuations, 2), NgramContext.EMPTY_PREV_WORDS_INFO); + // question mark is treated as the end of the sentence. Hence, beginning of the + // sentence is expected. + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc? def", mSpacingAndPunctuations, 2), NgramContext.BEGINNING_OF_SENTENCE); + // Exclamation mark is treated as the end of the sentence. Hence, beginning of the + // sentence is expected. + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc! def", mSpacingAndPunctuations, 2), NgramContext.BEGINNING_OF_SENTENCE); + assertEquals(NgramContextUtils.getNgramContextFromNthPreviousWord( + "abc 'def", mSpacingAndPunctuations, 2), NgramContext.EMPTY_PREV_WORDS_INFO); } public void testGetWordRangeAtCursor() { @@ -223,7 +226,6 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase { mSpacingAndPunctuations, new int[] { Constants.CODE_SPACE }); final SpacingAndPunctuations TAB = new SpacingAndPunctuations( mSpacingAndPunctuations, new int[] { Constants.CODE_TAB }); - final int[] SPACE_TAB = StringUtils.toSortedCodePointArray(" \t"); // A character that needs surrogate pair to represent its code point (U+2008A). final String SUPPLEMENTARY_CHAR_STRING = "\uD840\uDC8A"; final SpacingAndPunctuations SUPPLEMENTARY_CHAR = new SpacingAndPunctuations( diff --git a/tests/src/com/android/inputmethod/latin/RichInputMethodSubtypeTests.java b/tests/src/com/android/inputmethod/latin/RichInputMethodSubtypeTests.java new file mode 100644 index 000000000..af94be664 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/RichInputMethodSubtypeTests.java @@ -0,0 +1,318 @@ +/* + * 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; + +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 com.android.inputmethod.latin.RichInputMethodSubtype; +import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; +import com.android.inputmethod.latin.utils.RunInLocale; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +import java.util.ArrayList; +import java.util.Locale; + +@SmallTest +public class RichInputMethodSubtypeTests extends AndroidTestCase { + // All input method subtypes of LatinIME. + private final ArrayList<RichInputMethodSubtype> mSubtypesList = new ArrayList<>(); + + private RichInputMethodManager mRichImm; + private Resources mRes; + private InputMethodSubtype mSavedAddtionalSubtypes[]; + + RichInputMethodSubtype EN_US; + RichInputMethodSubtype EN_GB; + RichInputMethodSubtype ES_US; + RichInputMethodSubtype FR; + RichInputMethodSubtype FR_CA; + RichInputMethodSubtype FR_CH; + RichInputMethodSubtype DE; + RichInputMethodSubtype DE_CH; + RichInputMethodSubtype HI; + RichInputMethodSubtype SR; + RichInputMethodSubtype ZZ; + RichInputMethodSubtype DE_QWERTY; + RichInputMethodSubtype FR_QWERTZ; + RichInputMethodSubtype EN_US_AZERTY; + RichInputMethodSubtype EN_UK_DVORAK; + RichInputMethodSubtype ES_US_COLEMAK; + RichInputMethodSubtype ZZ_AZERTY; + RichInputMethodSubtype ZZ_PC; + + // These are preliminary subtypes and may not exist. + RichInputMethodSubtype HI_LATN; // Hinglish + RichInputMethodSubtype SR_LATN; // Serbian Latin + RichInputMethodSubtype HI_LATN_DVORAK; + RichInputMethodSubtype SR_LATN_QWERTY; + + @Override + protected void setUp() throws Exception { + super.setUp(); + final Context context = getContext(); + mRes = context.getResources(); + RichInputMethodManager.init(context); + mRichImm = RichInputMethodManager.getInstance(); + + // Save and reset additional subtypes + mSavedAddtionalSubtypes = mRichImm.getAdditionalSubtypes(); + final InputMethodSubtype[] predefinedAddtionalSubtypes = + AdditionalSubtypeUtils.createAdditionalSubtypesArray( + AdditionalSubtypeUtils.createPrefSubtypes( + mRes.getStringArray(R.array.predefined_subtypes))); + mRichImm.setAdditionalInputMethodSubtypes(predefinedAddtionalSubtypes); + + 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(new RichInputMethodSubtype(subtype)); + } + + EN_US = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + Locale.US.toString(), "qwerty")); + EN_GB = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + Locale.UK.toString(), "qwerty")); + ES_US = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + "es_US", "spanish")); + FR = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + Locale.FRENCH.toString(), "azerty")); + FR_CA = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + Locale.CANADA_FRENCH.toString(), "qwerty")); + FR_CH = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + "fr_CH", "swiss")); + DE = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + Locale.GERMAN.toString(), "qwertz")); + DE_CH = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + "de_CH", "swiss")); + HI = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + "hi", "hindi")); + SR = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + "sr", "south_slavic")); + ZZ = new RichInputMethodSubtype(mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + SubtypeLocaleUtils.NO_LANGUAGE, "qwerty")); + DE_QWERTY = new RichInputMethodSubtype( + AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( + Locale.GERMAN.toString(), "qwerty")); + FR_QWERTZ = new RichInputMethodSubtype( + AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( + Locale.FRENCH.toString(), "qwertz")); + EN_US_AZERTY = new RichInputMethodSubtype( + AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( + Locale.US.toString(), "azerty")); + EN_UK_DVORAK = new RichInputMethodSubtype( + AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( + Locale.UK.toString(), "dvorak")); + ES_US_COLEMAK = new RichInputMethodSubtype( + AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( + "es_US", "colemak")); + ZZ_AZERTY = new RichInputMethodSubtype( + AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( + SubtypeLocaleUtils.NO_LANGUAGE, "azerty")); + ZZ_PC = new RichInputMethodSubtype( + AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( + SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty")); + + final InputMethodSubtype hiLatn = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + "hi_ZZ", "qwerty"); + if (hiLatn != null) { + HI_LATN = new RichInputMethodSubtype(hiLatn); + HI_LATN_DVORAK = new RichInputMethodSubtype( + AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( + "hi_ZZ", "dvorak")); + } + final InputMethodSubtype srLatn = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + "sr_ZZ", "serbian_qwertz"); + if (srLatn != null) { + SR_LATN = new RichInputMethodSubtype(srLatn); + SR_LATN_QWERTY = new RichInputMethodSubtype( + AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( + "sr_ZZ", "qwerty")); + } + } + + @Override + protected void tearDown() throws Exception { + // Restore additional subtypes. + mRichImm.setAdditionalInputMethodSubtypes(mSavedAddtionalSubtypes); + super.tearDown(); + } + + public void testAllFullDisplayNameForSpacebar() { + for (final RichInputMethodSubtype subtype : mSubtypesList) { + final String subtypeName = SubtypeLocaleUtils + .getSubtypeDisplayNameInSystemLocale(subtype.getRawSubtype()); + final String spacebarText = subtype.getFullDisplayName(); + final String languageName = SubtypeLocaleUtils + .getSubtypeLocaleDisplayName(subtype.getLocale().toString()); + if (subtype.isNoLanguage()) { + assertFalse(subtypeName, spacebarText.contains(languageName)); + } else { + assertTrue(subtypeName, spacebarText.contains(languageName)); + } + } + } + + public void testAllMiddleDisplayNameForSpacebar() { + for (final RichInputMethodSubtype subtype : mSubtypesList) { + final String subtypeName = SubtypeLocaleUtils + .getSubtypeDisplayNameInSystemLocale(subtype.getRawSubtype()); + final Locale locale = subtype.getLocale(); + final Locale displayLocale = SubtypeLocaleUtils.getDisplayLocaleOfSubtypeLocale( + locale.toString()); + if (Locale.ROOT.equals(displayLocale)) { + // Skip test because the language part of this locale string doesn't represent + // the locale to be displayed on the spacebar (for example Hinglish). + continue; + } + final String spacebarText = subtype.getMiddleDisplayName(); + if (subtype.isNoLanguage()) { + assertEquals(subtypeName, SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName( + subtype.getRawSubtype()), spacebarText); + } else { + assertEquals(subtypeName, + SubtypeLocaleUtils.getSubtypeLanguageDisplayName(locale.toString()), + spacebarText); + } + } + } + + // InputMethodSubtype's display name for spacebar text in its locale. + // isAdditionalSubtype (T=true, F=false) + // locale layout | Middle Full + // ------ -------------- - --------- ---------------------- + // en_US qwerty F English English (US) exception + // en_GB qwerty F English English (UK) exception + // es_US spanish F Español Español (EE.UU.) exception + // fr azerty F Français Français + // fr_CA qwerty F Français Français (Canada) + // fr_CH swiss F Français Français (Suisse) + // de qwertz F Deutsch Deutsch + // de_CH swiss F Deutsch Deutsch (Schweiz) + // hi hindi F हिन्दी हिन्दी + // hi_ZZ qwerty F Hinglish Hinglish exception + // sr south_slavic F Српски Српски + // sr_ZZ serbian_qwertz F Srpski Srpski exception + // zz qwerty F QWERTY QWERTY + // fr qwertz T Français Français + // de qwerty T Deutsch Deutsch + // en_US azerty T English English (US) + // en_GB dvorak T English English (UK) + // hi_ZZ dvorak T Hinglish Hinglish exception + // sr_ZZ qwerty T Srpski Srpski exception + // zz azerty T AZERTY AZERTY + + private final RunInLocale<Void> testsPredefinedSubtypesForSpacebar = new RunInLocale<Void>() { + @Override + protected Void job(final Resources res) { + assertEquals("en_US", "English (US)", EN_US.getFullDisplayName()); + assertEquals("en_GB", "English (UK)", EN_GB.getFullDisplayName()); + assertEquals("es_US", "Español (EE.UU.)", ES_US.getFullDisplayName()); + assertEquals("fr", "Français", FR.getFullDisplayName()); + assertEquals("fr_CA", "Français (Canada)", FR_CA.getFullDisplayName()); + assertEquals("fr_CH", "Français (Suisse)", FR_CH.getFullDisplayName()); + assertEquals("de", "Deutsch", DE.getFullDisplayName()); + assertEquals("de_CH", "Deutsch (Schweiz)", DE_CH.getFullDisplayName()); + assertEquals("hi", "हिन्दी", HI.getFullDisplayName()); + assertEquals("sr", "Српски", SR.getFullDisplayName()); + assertEquals("zz", "QWERTY", ZZ.getFullDisplayName()); + + assertEquals("en_US", "English", EN_US.getMiddleDisplayName()); + assertEquals("en_GB", "English", EN_GB.getMiddleDisplayName()); + assertEquals("es_US", "Español", ES_US.getMiddleDisplayName()); + assertEquals("fr", "Français", FR.getMiddleDisplayName()); + assertEquals("fr_CA", "Français", FR_CA.getMiddleDisplayName()); + assertEquals("fr_CH", "Français", FR_CH.getMiddleDisplayName()); + assertEquals("de", "Deutsch", DE.getMiddleDisplayName()); + assertEquals("de_CH", "Deutsch", DE_CH.getMiddleDisplayName()); + assertEquals("zz", "QWERTY", ZZ.getMiddleDisplayName()); + + // These are preliminary subtypes and may not exist. + if (HI_LATN != null) { + assertEquals("hi_ZZ", "Hinglish", HI_LATN.getFullDisplayName()); + assertEquals("hi_ZZ", "Hinglish", HI_LATN.getMiddleDisplayName()); + } + if (SR_LATN != null) { + assertEquals("sr_ZZ", "Srpski", SR_LATN.getFullDisplayName()); + assertEquals("sr_ZZ", "Srpski", SR_LATN.getMiddleDisplayName()); + } + return null; + } + }; + + private final RunInLocale<Void> testsAdditionalSubtypesForSpacebar = new RunInLocale<Void>() { + @Override + protected Void job(final Resources res) { + assertEquals("fr qwertz", "Français", FR_QWERTZ.getFullDisplayName()); + assertEquals("de qwerty", "Deutsch", DE_QWERTY.getFullDisplayName()); + assertEquals("en_US azerty", "English (US)", EN_US_AZERTY.getFullDisplayName()); + assertEquals("en_UK dvorak", "English (UK)", EN_UK_DVORAK.getFullDisplayName()); + assertEquals("es_US colemak", "Español (EE.UU.)", ES_US_COLEMAK.getFullDisplayName()); + assertEquals("zz azerty", "AZERTY", ZZ_AZERTY.getFullDisplayName()); + assertEquals("zz pc", "PC", ZZ_PC.getFullDisplayName()); + + assertEquals("fr qwertz", "Français", FR_QWERTZ.getMiddleDisplayName()); + assertEquals("de qwerty", "Deutsch", DE_QWERTY.getMiddleDisplayName()); + assertEquals("en_US azerty", "English", EN_US_AZERTY.getMiddleDisplayName()); + assertEquals("en_UK dvorak", "English", EN_UK_DVORAK.getMiddleDisplayName()); + assertEquals("es_US colemak", "Español", ES_US_COLEMAK.getMiddleDisplayName()); + assertEquals("zz azerty", "AZERTY", ZZ_AZERTY.getMiddleDisplayName()); + assertEquals("zz pc", "PC", ZZ_PC.getMiddleDisplayName()); + + // These are preliminary subtypes and may not exist. + if (HI_LATN_DVORAK != null) { + assertEquals("hi_ZZ dvorak", "Hinglish", HI_LATN_DVORAK.getFullDisplayName()); + assertEquals("hi_ZZ dvorak", "Hinglish", HI_LATN_DVORAK.getMiddleDisplayName()); + } + if (SR_LATN_QWERTY != null) { + assertEquals("sr_ZZ qwerty", "Srpski", SR_LATN_QWERTY.getFullDisplayName()); + assertEquals("sr_ZZ qwerty", "Srpski", SR_LATN_QWERTY.getMiddleDisplayName()); + } + return null; + } + }; + + public void testPredefinedSubtypesForSpacebarInEnglish() { + testsPredefinedSubtypesForSpacebar.runInLocale(mRes, Locale.ENGLISH); + } + + public void testAdditionalSubtypeForSpacebarInEnglish() { + testsAdditionalSubtypesForSpacebar.runInLocale(mRes, Locale.ENGLISH); + } + + public void testPredefinedSubtypesForSpacebarInFrench() { + testsPredefinedSubtypesForSpacebar.runInLocale(mRes, Locale.FRENCH); + } + + public void testAdditionalSubtypeForSpacebarInFrench() { + testsAdditionalSubtypesForSpacebar.runInLocale(mRes, Locale.FRENCH); + } + + public void testRichInputMethodSubtypeForNullInputMethodSubtype() { + RichInputMethodSubtype subtype = RichInputMethodSubtype.getRichInputMethodSubtype(null); + assertNotNull(subtype); + assertEquals("zz", subtype.getRawSubtype().getLocale()); + assertEquals("keyboard", subtype.getRawSubtype().getMode()); + } +} diff --git a/tests/src/com/android/inputmethod/latin/ShiftModeTests.java b/tests/src/com/android/inputmethod/latin/ShiftModeTests.java index db3c9baa9..59bb5f8a4 100644 --- a/tests/src/com/android/inputmethod/latin/ShiftModeTests.java +++ b/tests/src/com/android/inputmethod/latin/ShiftModeTests.java @@ -16,13 +16,11 @@ package com.android.inputmethod.latin; -import android.os.Build; import android.test.suitebuilder.annotation.LargeTest; import android.text.TextUtils; import android.view.inputmethod.EditorInfo; -import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.WordComposer; +import com.android.inputmethod.latin.common.Constants; @LargeTest public class ShiftModeTests extends InputTestsBase { @@ -75,7 +73,7 @@ public class ShiftModeTests extends InputTestsBase { repeatKey(Constants.CODE_DELETE); } assertFalse("Caps immediately after repeating Backspace a lot", isCapsModeAutoShifted()); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); assertTrue("Caps after a while after repeating Backspace a lot", isCapsModeAutoShifted()); } diff --git a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java index 869c550e0..d465ce674 100644 --- a/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java +++ b/tests/src/com/android/inputmethod/latin/SuggestedWordsTests.java @@ -37,7 +37,7 @@ public class SuggestedWordsTests extends AndroidTestCase { private static SuggestedWordInfo createTypedWordInfo(final String word) { // Use 100 as the frequency because the numerical value does not matter as // long as it's > 1 and < INT_MAX. - return new SuggestedWordInfo(word, 100 /* score */, + return new SuggestedWordInfo(word, "" /* prevWordsContext */, 100 /* score */, SuggestedWordInfo.KIND_TYPED, null /* sourceDict */, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, @@ -52,49 +52,23 @@ public class SuggestedWordsTests extends AndroidTestCase { * @return a new instance of {@link SuggestedWordInfo}. */ private static SuggestedWordInfo createCorrectionWordInfo(final String word) { - return new SuggestedWordInfo(word, 1 /* score */, + return new SuggestedWordInfo(word, "" /* prevWordsContext */, 1 /* score */, SuggestedWordInfo.KIND_CORRECTION, null /* sourceDict */, SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */, SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */); } - public void testGetSuggestedWordsExcludingTypedWord() { - final String TYPED_WORD = "typed"; - final int NUMBER_OF_ADDED_SUGGESTIONS = 5; - final int KIND_OF_SECOND_CORRECTION = SuggestedWordInfo.KIND_CORRECTION; - final ArrayList<SuggestedWordInfo> list = new ArrayList<>(); - list.add(createTypedWordInfo(TYPED_WORD)); - for (int i = 0; i < NUMBER_OF_ADDED_SUGGESTIONS; ++i) { - list.add(createCorrectionWordInfo(Integer.toString(i))); + private static ArrayList<SuggestedWordInfo> createCorrectionWordInfos(final String... words) { + final ArrayList<SuggestedWordInfo> infos = new ArrayList<>(); + for (final String word : words) { + infos.add(createCorrectionWordInfo(word)); } - - final SuggestedWords words = new SuggestedWords( - list, null /* rawSuggestions */, - false /* typedWordValid */, - false /* willAutoCorrect */, - false /* isObsoleteSuggestions */, - SuggestedWords.INPUT_STYLE_NONE); - assertEquals(NUMBER_OF_ADDED_SUGGESTIONS + 1, words.size()); - assertEquals("typed", words.getWord(0)); - assertTrue(words.getInfo(0).isKindOf(SuggestedWordInfo.KIND_TYPED)); - assertEquals("0", words.getWord(1)); - assertTrue(words.getInfo(1).isKindOf(KIND_OF_SECOND_CORRECTION)); - assertEquals("4", words.getWord(5)); - assertTrue(words.getInfo(5).isKindOf(KIND_OF_SECOND_CORRECTION)); - - final SuggestedWords wordsWithoutTyped = - words.getSuggestedWordsExcludingTypedWordForRecorrection(); - // Make sure that the typed word has indeed been excluded, by testing the size of the - // suggested words, the string and the kind of the top suggestion, which should match - // the string and kind of what we inserted after the typed word. - assertEquals(words.size() - 1, wordsWithoutTyped.size()); - assertEquals("0", wordsWithoutTyped.getWord(0)); - assertTrue(wordsWithoutTyped.getInfo(0).isKindOf(KIND_OF_SECOND_CORRECTION)); + return infos; } // Helper for testGetTransformedWordInfo - private SuggestedWordInfo transformWordInfo(final String info, + private static SuggestedWordInfo transformWordInfo(final String info, final int trailingSingleQuotesCount) { final SuggestedWordInfo suggestedWordInfo = createTypedWordInfo(info); final SuggestedWordInfo returnedWordInfo = @@ -106,6 +80,30 @@ public class SuggestedWordsTests extends AndroidTestCase { return returnedWordInfo; } + public void testRemoveDupesNoDupes() { + final ArrayList<SuggestedWordInfo> infos = createCorrectionWordInfos("a", "c"); + assertEquals(-1, SuggestedWordInfo.removeDups("b", infos)); + assertEquals(2, infos.size()); + } + + public void testRemoveDupesTypedWordNotDupe() { + final ArrayList<SuggestedWordInfo> infos = createCorrectionWordInfos("a", "a", "c"); + assertEquals(-1, SuggestedWordInfo.removeDups("b", infos)); + assertEquals(2, infos.size()); + } + + public void testRemoveDupesTypedWordOnlyDupe() { + final ArrayList<SuggestedWordInfo> infos = createCorrectionWordInfos("a", "b", "c"); + assertEquals(1, SuggestedWordInfo.removeDups("b", infos)); + assertEquals(2, infos.size()); + } + + public void testRemoveDupesTypedWordNotOnlyDupe() { + final ArrayList<SuggestedWordInfo> infos = createCorrectionWordInfos("a", "b", "b", "c"); + assertEquals(1, SuggestedWordInfo.removeDups("b", infos)); + assertEquals(2, infos.size()); + } + public void testGetTransformedSuggestedWordInfo() { SuggestedWordInfo result = transformWordInfo("word", 0); assertEquals(result.mWord, "word"); @@ -123,9 +121,10 @@ public class SuggestedWordsTests extends AndroidTestCase { public void testGetTypedWordInfoOrNull() { final String TYPED_WORD = "typed"; + final SuggestedWordInfo TYPED_WORD_INFO = createTypedWordInfo(TYPED_WORD); final int NUMBER_OF_ADDED_SUGGESTIONS = 5; final ArrayList<SuggestedWordInfo> list = new ArrayList<>(); - list.add(createTypedWordInfo(TYPED_WORD)); + list.add(TYPED_WORD_INFO); for (int i = 0; i < NUMBER_OF_ADDED_SUGGESTIONS; ++i) { list.add(createCorrectionWordInfo(Integer.toString(i))); } @@ -133,30 +132,41 @@ public class SuggestedWordsTests extends AndroidTestCase { // Make sure getTypedWordInfoOrNull() returns non-null object. final SuggestedWords wordsWithTypedWord = new SuggestedWords( list, null /* rawSuggestions */, + TYPED_WORD_INFO, false /* typedWordValid */, false /* willAutoCorrect */, false /* isObsoleteSuggestions */, - SuggestedWords.INPUT_STYLE_NONE); + SuggestedWords.INPUT_STYLE_NONE, + SuggestedWords.NOT_A_SEQUENCE_NUMBER); final SuggestedWordInfo typedWord = wordsWithTypedWord.getTypedWordInfoOrNull(); assertNotNull(typedWord); assertEquals(TYPED_WORD, typedWord.mWord); - // Make sure getTypedWordInfoOrNull() returns null. - final SuggestedWords wordsWithoutTypedWord = - wordsWithTypedWord.getSuggestedWordsExcludingTypedWordForRecorrection(); + // Make sure getTypedWordInfoOrNull() returns null when no typed word. + list.remove(0); + final SuggestedWords wordsWithoutTypedWord = new SuggestedWords( + list, null /* rawSuggestions */, + null /* typedWord */, + false /* typedWordValid */, + false /* willAutoCorrect */, + false /* isObsoleteSuggestions */, + SuggestedWords.INPUT_STYLE_NONE, + SuggestedWords.NOT_A_SEQUENCE_NUMBER); assertNull(wordsWithoutTypedWord.getTypedWordInfoOrNull()); // Make sure getTypedWordInfoOrNull() returns null. - assertNull(SuggestedWords.EMPTY.getTypedWordInfoOrNull()); + assertNull(SuggestedWords.getEmptyInstance().getTypedWordInfoOrNull()); final SuggestedWords emptySuggestedWords = new SuggestedWords( new ArrayList<SuggestedWordInfo>(), null /* rawSuggestions */, + null /* typedWord */, false /* typedWordValid */, false /* willAutoCorrect */, false /* isObsoleteSuggestions */, - SuggestedWords.INPUT_STYLE_NONE); + SuggestedWords.INPUT_STYLE_NONE, + SuggestedWords.NOT_A_SEQUENCE_NUMBER); assertNull(emptySuggestedWords.getTypedWordInfoOrNull()); - assertNull(SuggestedWords.EMPTY.getTypedWordInfoOrNull()); + assertNull(SuggestedWords.getEmptyInstance().getTypedWordInfoOrNull()); } } diff --git a/tests/src/com/android/inputmethod/latin/WordComposerTests.java b/tests/src/com/android/inputmethod/latin/WordComposerTests.java index c44544f3d..8ae475f7e 100644 --- a/tests/src/com/android/inputmethod/latin/WordComposerTests.java +++ b/tests/src/com/android/inputmethod/latin/WordComposerTests.java @@ -19,8 +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; +import com.android.inputmethod.latin.common.Constants; +import com.android.inputmethod.latin.common.CoordinateUtils; +import com.android.inputmethod.latin.common.StringUtils; /** * Unit tests for WordComposer. diff --git a/tests/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiverTests.java b/tests/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiverTests.java new file mode 100644 index 000000000..832817967 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/accounts/AccountsChangedReceiverTests.java @@ -0,0 +1,112 @@ +/* + * 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.accounts; + +import android.accounts.AccountManager; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.test.AndroidTestCase; + +import com.android.inputmethod.latin.settings.LocalSettingsConstants; + +/** + * Tests for {@link AccountsChangedReceiver}. + */ +public class AccountsChangedReceiverTests extends AndroidTestCase { + private static final String ACCOUNT_1 = "account1@example.com"; + private static final String ACCOUNT_2 = "account2@example.com"; + + private SharedPreferences mPrefs; + private String mLastKnownAccount = null; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mPrefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + // Keep track of the current account so that we restore it when the test finishes. + mLastKnownAccount = mPrefs.getString(LocalSettingsConstants.PREF_ACCOUNT_NAME, null); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + // Restore the account that was present before running the test. + updateAccountName(mLastKnownAccount); + } + + public void testUnknownIntent() { + updateAccountName(ACCOUNT_1); + AccountsChangedReceiver reciever = new AccountsChangedReceiver(); + reciever.onReceive(getContext(), new Intent("some-random-action")); + // Account should *not* be removed from preferences. + assertAccountName(ACCOUNT_1); + } + + public void testAccountRemoved() { + updateAccountName(ACCOUNT_1); + AccountsChangedReceiver reciever = new AccountsChangedReceiver() { + @Override + protected String[] getAccountsForLogin(Context context) { + return new String[] {ACCOUNT_2}; + } + }; + reciever.onReceive(getContext(), new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION)); + // Account should be removed from preferences. + assertAccountName(null); + } + + public void testAccountRemoved_noAccounts() { + updateAccountName(ACCOUNT_2); + AccountsChangedReceiver reciever = new AccountsChangedReceiver() { + @Override + protected String[] getAccountsForLogin(Context context) { + return new String[0]; + } + }; + reciever.onReceive(getContext(), new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION)); + // Account should be removed from preferences. + assertAccountName(null); + } + + public void testAccountNotRemoved() { + updateAccountName(ACCOUNT_2); + AccountsChangedReceiver reciever = new AccountsChangedReceiver() { + @Override + protected String[] getAccountsForLogin(Context context) { + return new String[] {ACCOUNT_1, ACCOUNT_2}; + } + }; + reciever.onReceive(getContext(), new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION)); + // Account should *not* be removed from preferences. + assertAccountName(ACCOUNT_2); + } + + private void updateAccountName(String accountName) { + if (accountName == null) { + mPrefs.edit().remove(LocalSettingsConstants.PREF_ACCOUNT_NAME).apply(); + } else { + mPrefs.edit().putString(LocalSettingsConstants.PREF_ACCOUNT_NAME, accountName).apply(); + } + } + + private void assertAccountName(String expectedAccountName) { + assertEquals(expectedAccountName, + mPrefs.getString(LocalSettingsConstants.PREF_ACCOUNT_NAME, null)); + } +} diff --git a/tests/src/com/android/inputmethod/latin/InputPointersTests.java b/tests/src/com/android/inputmethod/latin/common/InputPointersTests.java index 1a47cddf4..6b3490de8 100644 --- a/tests/src/com/android/inputmethod/latin/InputPointersTests.java +++ b/tests/src/com/android/inputmethod/latin/common/InputPointersTests.java @@ -14,13 +14,11 @@ * limitations under the License. */ -package com.android.inputmethod.latin; +package com.android.inputmethod.latin.common; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; -import com.android.inputmethod.latin.utils.ResizableIntArray; - import java.util.Arrays; @SmallTest diff --git a/tests/src/com/android/inputmethod/latin/utils/ResizableIntArrayTests.java b/tests/src/com/android/inputmethod/latin/common/ResizableIntArrayTests.java index 8f58e6873..bd1629faf 100644 --- a/tests/src/com/android/inputmethod/latin/utils/ResizableIntArrayTests.java +++ b/tests/src/com/android/inputmethod/latin/common/ResizableIntArrayTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.inputmethod.latin.utils; +package com.android.inputmethod.latin.common; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; @@ -79,13 +79,13 @@ public class ResizableIntArrayTests extends AndroidTestCase { public void testGet() { final ResizableIntArray src = new ResizableIntArray(DEFAULT_CAPACITY); try { - final int value = src.get(0); + src.get(0); fail("get(0) shouldn't succeed"); } catch (ArrayIndexOutOfBoundsException e) { // success } try { - final int value = src.get(DEFAULT_CAPACITY); + src.get(DEFAULT_CAPACITY); fail("get(DEFAULT_CAPACITY) shouldn't succeed"); } catch (ArrayIndexOutOfBoundsException e) { // success @@ -98,7 +98,7 @@ public class ResizableIntArrayTests extends AndroidTestCase { 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()); + src.get(src.getLength()); fail("get(length) shouldn't succeed"); } catch (ArrayIndexOutOfBoundsException e) { // success diff --git a/tests/src/com/android/inputmethod/latin/utils/StringAndJsonUtilsTests.java b/tests/src/com/android/inputmethod/latin/common/StringUtilsTests.java index 637ae10ee..ec9d4be92 100644 --- a/tests/src/com/android/inputmethod/latin/utils/StringAndJsonUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/common/StringUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 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. @@ -14,22 +14,177 @@ * limitations under the License. */ -package com.android.inputmethod.latin.utils; +package com.android.inputmethod.latin.common; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; -import android.text.SpannableString; -import android.text.Spanned; -import android.text.SpannedString; -import com.android.inputmethod.latin.Constants; - -import java.util.Arrays; -import java.util.List; import java.util.Locale; @SmallTest -public class StringAndJsonUtilsTests extends AndroidTestCase { +public class StringUtilsTests extends AndroidTestCase { + private static final Locale US = Locale.US; + private static final Locale GERMAN = Locale.GERMAN; + private static final Locale TURKEY = new Locale("tr", "TR"); + private static final Locale GREECE = new Locale("el", "GR"); + + private static void assert_toTitleCaseOfKeyLabel(final Locale locale, + final String lowerCase, final String expected) { + assertEquals(lowerCase + " in " + locale, expected, + StringUtils.toTitleCaseOfKeyLabel(lowerCase, locale)); + } + + public void test_toTitleCaseOfKeyLabel() { + assert_toTitleCaseOfKeyLabel(US, null, null); + assert_toTitleCaseOfKeyLabel(US, "", ""); + assert_toTitleCaseOfKeyLabel(US, "aeiou", "AEIOU"); + // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE + // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE + // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX + // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS + // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON + // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE + // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA + // U+00C0: "À" LATIN CAPITAL LETTER A WITH GRAVE + // U+00C8: "È" LATIN CAPITAL LETTER E WITH GRAVE + // U+00CE: "Î" LATIN CAPITAL LETTER I WITH CIRCUMFLEX + // U+00D6: "Ö" LATIN CAPITAL LETTER O WITH DIAERESIS + // U+016A: "Ū" LATIN CAPITAL LETTER U WITH MACRON + // U+00D1: "Ñ" LATIN CAPITAL LETTER N WITH TILDE + // U+00C7: "Ç" LATIN CAPITAL LETTER C WITH CEDILLA + assert_toTitleCaseOfKeyLabel(US, + "\u00E0\u00E8\u00EE\u00F6\u016B\u00F1\u00E7", + "\u00C0\u00C8\u00CE\u00D6\u016A\u00D1\u00C7"); + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE + // U+0161: "š" LATIN SMALL LETTER S WITH CARON + // U+015A: "Ś" LATIN CAPITAL LETTER S WITH ACUTE + // U+0160: "Š" LATIN CAPITAL LETTER S WITH CARONZ + assert_toTitleCaseOfKeyLabel(GERMAN, + "\u00DF\u015B\u0161", + "SS\u015A\u0160"); + // U+0259: "ə" LATIN SMALL LETTER SCHWA + // U+0069: "i" LATIN SMALL LETTER I + // U+0131: "ı" LATIN SMALL LETTER DOTLESS I + // U+018F: "Ə" LATIN SMALL LETTER SCHWA + // U+0130: "İ" LATIN SMALL LETTER I WITH DOT ABOVE + // U+0049: "I" LATIN SMALL LETTER I + assert_toTitleCaseOfKeyLabel(TURKEY, + "\u0259\u0069\u0131", + "\u018F\u0130\u0049"); + // U+03C3: "σ" GREEK SMALL LETTER SIGMA + // U+03C2: "ς" GREEK SMALL LETTER FINAL SIGMA + // U+03A3: "Σ" GREEK CAPITAL LETTER SIGMA + assert_toTitleCaseOfKeyLabel(GREECE, + "\u03C3\u03C2", + "\u03A3\u03A3"); + // U+03AC: "ά" GREEK SMALL LETTER ALPHA WITH TONOS + // U+03AD: "έ" GREEK SMALL LETTER EPSILON WITH TONOS + // U+03AE: "ή" GREEK SMALL LETTER ETA WITH TONOS + // U+03AF: "ί" GREEK SMALL LETTER IOTA WITH TONOS + // U+03CC: "ό" GREEK SMALL LETTER OMICRON WITH TONOS + // U+03CD: "ύ" GREEK SMALL LETTER UPSILON WITH TONOS + // U+03CE: "ώ" GREEK SMALL LETTER OMEGA WITH TONOS + // U+0386: "Ά" GREEK CAPITAL LETTER ALPHA WITH TONOS + // U+0388: "Έ" GREEK CAPITAL LETTER EPSILON WITH TONOS + // U+0389: "Ή" GREEK CAPITAL LETTER ETA WITH TONOS + // U+038A: "Ί" GREEK CAPITAL LETTER IOTA WITH TONOS + // U+038C: "Ό" GREEK CAPITAL LETTER OMICRON WITH TONOS + // U+038E: "Ύ" GREEK CAPITAL LETTER UPSILON WITH TONOS + // U+038F: "Ώ" GREEK CAPITAL LETTER OMEGA WITH TONOS + assert_toTitleCaseOfKeyLabel(GREECE, + "\u03AC\u03AD\u03AE\u03AF\u03CC\u03CD\u03CE", + "\u0386\u0388\u0389\u038A\u038C\u038E\u038F"); + // U+03CA: "ϊ" GREEK SMALL LETTER IOTA WITH DIALYTIKA + // U+03CB: "ϋ" GREEK SMALL LETTER UPSILON WITH DIALYTIKA + // U+0390: "ΐ" GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + // U+03B0: "ΰ" GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + // U+03AA: "Ϊ" GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + // U+03AB: "Ϋ" GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + // U+0399: "Ι" GREEK CAPITAL LETTER IOTA + // U+03A5: "Υ" GREEK CAPITAL LETTER UPSILON + // U+0308: COMBINING DIAERESIS + // U+0301: COMBINING GRAVE ACCENT + assert_toTitleCaseOfKeyLabel(GREECE, + "\u03CA\u03CB\u0390\u03B0", + "\u03AA\u03AB\u0399\u0308\u0301\u03A5\u0308\u0301"); + } + + private static void assert_toTitleCaseOfKeyCode(final Locale locale, final int lowerCase, + final int expected) { + assertEquals(lowerCase + " in " + locale, expected, + StringUtils.toTitleCaseOfKeyCode(lowerCase, locale)); + } + + public void test_toTitleCaseOfKeyCode() { + assert_toTitleCaseOfKeyCode(US, Constants.CODE_ENTER, Constants.CODE_ENTER); + assert_toTitleCaseOfKeyCode(US, Constants.CODE_SPACE, Constants.CODE_SPACE); + assert_toTitleCaseOfKeyCode(US, Constants.CODE_COMMA, Constants.CODE_COMMA); + // U+0069: "i" LATIN SMALL LETTER I + // U+0131: "ı" LATIN SMALL LETTER DOTLESS I + // U+0130: "İ" LATIN SMALL LETTER I WITH DOT ABOVE + // U+0049: "I" LATIN SMALL LETTER I + assert_toTitleCaseOfKeyCode(US, 0x0069, 0x0049); // i -> I + assert_toTitleCaseOfKeyCode(US, 0x0131, 0x0049); // ı -> I + assert_toTitleCaseOfKeyCode(TURKEY, 0x0069, 0x0130); // i -> İ + assert_toTitleCaseOfKeyCode(TURKEY, 0x0131, 0x0049); // ı -> I + // U+00DF: "ß" LATIN SMALL LETTER SHARP S + // The title case of "ß" is "SS". + assert_toTitleCaseOfKeyCode(US, 0x00DF, Constants.CODE_UNSPECIFIED); + // U+03AC: "ά" GREEK SMALL LETTER ALPHA WITH TONOS + // U+0386: "Ά" GREEK CAPITAL LETTER ALPHA WITH TONOS + assert_toTitleCaseOfKeyCode(GREECE, 0x03AC, 0x0386); + // U+03CA: "ϊ" GREEK SMALL LETTER IOTA WITH DIALYTIKA + // U+03AA: "Ϊ" GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + assert_toTitleCaseOfKeyCode(GREECE, 0x03CA, 0x03AA); + // U+03B0: "ΰ" GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + // The title case of "ΰ" is "\u03A5\u0308\u0301". + assert_toTitleCaseOfKeyCode(GREECE, 0x03B0, Constants.CODE_UNSPECIFIED); + } + + private static void assert_capitalizeFirstCodePoint(final Locale locale, final String text, + final String expected) { + assertEquals(text + " in " + locale, expected, + StringUtils.capitalizeFirstCodePoint(text, locale)); + } + + public void test_capitalizeFirstCodePoint() { + assert_capitalizeFirstCodePoint(US, "", ""); + assert_capitalizeFirstCodePoint(US, "a", "A"); + assert_capitalizeFirstCodePoint(US, "à", "À"); + assert_capitalizeFirstCodePoint(US, "ß", "SS"); + assert_capitalizeFirstCodePoint(US, "text", "Text"); + assert_capitalizeFirstCodePoint(US, "iGoogle", "IGoogle"); + assert_capitalizeFirstCodePoint(TURKEY, "iyi", "İyi"); + assert_capitalizeFirstCodePoint(TURKEY, "ısırdı", "Isırdı"); + assert_capitalizeFirstCodePoint(GREECE, "ά", "Ά"); + assert_capitalizeFirstCodePoint(GREECE, "άνεση", "Άνεση"); + } + + private static void assert_capitalizeFirstAndDowncaseRest(final Locale locale, + final String text, final String expected) { + assertEquals(text + " in " + locale, expected, + StringUtils.capitalizeFirstAndDowncaseRest(text, locale)); + } + + public void test_capitalizeFirstAndDowncaseRest() { + assert_capitalizeFirstAndDowncaseRest(US, "", ""); + assert_capitalizeFirstAndDowncaseRest(US, "a", "A"); + assert_capitalizeFirstAndDowncaseRest(US, "à", "À"); + assert_capitalizeFirstAndDowncaseRest(US, "ß", "SS"); + assert_capitalizeFirstAndDowncaseRest(US, "text", "Text"); + assert_capitalizeFirstAndDowncaseRest(US, "iGoogle", "Igoogle"); + assert_capitalizeFirstAndDowncaseRest(US, "invite", "Invite"); + assert_capitalizeFirstAndDowncaseRest(US, "INVITE", "Invite"); + assert_capitalizeFirstAndDowncaseRest(TURKEY, "iyi", "İyi"); + assert_capitalizeFirstAndDowncaseRest(TURKEY, "İYİ", "İyi"); + assert_capitalizeFirstAndDowncaseRest(TURKEY, "ısırdı", "Isırdı"); + assert_capitalizeFirstAndDowncaseRest(TURKEY, "ISIRDI", "Isırdı"); + assert_capitalizeFirstAndDowncaseRest(GREECE, "ά", "Ά"); + assert_capitalizeFirstAndDowncaseRest(GREECE, "άνεση", "Άνεση"); + assert_capitalizeFirstAndDowncaseRest(GREECE, "ΆΝΕΣΗ", "Άνεση"); + } + public void testContainsInArray() { assertFalse("empty array", StringUtils.containsInArray("key", new String[0])); assertFalse("not in 1 element", StringUtils.containsInArray("key", new String[] { @@ -246,16 +401,6 @@ public class StringAndJsonUtilsTests extends AndroidTestCase { assertTrue(bytesStr.equals(bytesStr2)); } - public void testJsonUtils() { - final Object[] objs = new Object[] { 1, "aaa", "bbb", 3 }; - final List<Object> objArray = Arrays.asList(objs); - 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)); - } - } - public void testToCodePointArray() { final String STR_WITH_SUPPLEMENTARY_CHAR = "abcde\uD861\uDED7fgh\u0000\u2002\u2003\u3000xx"; final int[] EXPECTED_RESULT = new int[] { 'a', 'b', 'c', 'd', 'e', 0x286D7, 'f', 'g', 'h', @@ -329,171 +474,4 @@ public class StringAndJsonUtilsTests extends AndroidTestCase { assertEquals(1, StringUtils.getTrailingSingleQuotesCount("'word'")); assertEquals(0, StringUtils.getTrailingSingleQuotesCount("I'm")); } - - private static void assertSpanCount(final int expectedCount, final CharSequence cs) { - final int actualCount; - if (cs instanceof Spanned) { - final Spanned spanned = (Spanned) cs; - actualCount = spanned.getSpans(0, spanned.length(), Object.class).length; - } else { - actualCount = 0; - } - assertEquals(expectedCount, actualCount); - } - - private static void assertSpan(final CharSequence cs, final Object expectedSpan, - final int expectedStart, final int expectedEnd, final int expectedFlags) { - assertTrue(cs instanceof Spanned); - final Spanned spanned = (Spanned) cs; - final Object[] actualSpans = spanned.getSpans(0, spanned.length(), Object.class); - for (Object actualSpan : actualSpans) { - if (actualSpan == expectedSpan) { - final int actualStart = spanned.getSpanStart(actualSpan); - final int actualEnd = spanned.getSpanEnd(actualSpan); - final int actualFlags = spanned.getSpanFlags(actualSpan); - assertEquals(expectedStart, actualStart); - assertEquals(expectedEnd, actualEnd); - assertEquals(expectedFlags, actualFlags); - return; - } - } - assertTrue(false); - } - - public void testSplitCharSequenceWithSpan() { - // text: " a bcd efg hij " - // span1: ^^^^^^^ - // span2: ^^^^^ - // span3: ^ - final SpannableString spannableString = new SpannableString(" a bcd efg hij "); - final Object span1 = new Object(); - final Object span2 = new Object(); - final Object span3 = new Object(); - final int SPAN1_FLAGS = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE; - final int SPAN2_FLAGS = Spanned.SPAN_EXCLUSIVE_INCLUSIVE; - final int SPAN3_FLAGS = Spanned.SPAN_INCLUSIVE_INCLUSIVE; - spannableString.setSpan(span1, 0, 7, SPAN1_FLAGS); - spannableString.setSpan(span2, 0, 5, SPAN2_FLAGS); - spannableString.setSpan(span3, 12, 13, SPAN3_FLAGS); - final CharSequence[] charSequencesFromSpanned = StringUtils.split( - spannableString, " ", true /* preserveTrailingEmptySegmengs */); - final CharSequence[] charSequencesFromString = StringUtils.split( - spannableString.toString(), " ", true /* preserveTrailingEmptySegmengs */); - - - assertEquals(7, charSequencesFromString.length); - assertEquals(7, charSequencesFromSpanned.length); - - // text: "" - // span1: ^ - // span2: ^ - // span3: - assertEquals("", charSequencesFromString[0].toString()); - assertSpanCount(0, charSequencesFromString[0]); - assertEquals("", charSequencesFromSpanned[0].toString()); - assertSpanCount(2, charSequencesFromSpanned[0]); - assertSpan(charSequencesFromSpanned[0], span1, 0, 0, SPAN1_FLAGS); - assertSpan(charSequencesFromSpanned[0], span2, 0, 0, SPAN2_FLAGS); - - // text: "a" - // span1: ^ - // span2: ^ - // span3: - assertEquals("a", charSequencesFromString[1].toString()); - assertSpanCount(0, charSequencesFromString[1]); - assertEquals("a", charSequencesFromSpanned[1].toString()); - assertSpanCount(2, charSequencesFromSpanned[1]); - assertSpan(charSequencesFromSpanned[1], span1, 0, 1, SPAN1_FLAGS); - assertSpan(charSequencesFromSpanned[1], span2, 0, 1, SPAN2_FLAGS); - - // text: "bcd" - // span1: ^^^ - // span2: ^^ - // span3: - assertEquals("bcd", charSequencesFromString[2].toString()); - assertSpanCount(0, charSequencesFromString[2]); - assertEquals("bcd", charSequencesFromSpanned[2].toString()); - assertSpanCount(2, charSequencesFromSpanned[2]); - assertSpan(charSequencesFromSpanned[2], span1, 0, 3, SPAN1_FLAGS); - assertSpan(charSequencesFromSpanned[2], span2, 0, 2, SPAN2_FLAGS); - - // text: "efg" - // span1: - // span2: - // span3: - assertEquals("efg", charSequencesFromString[3].toString()); - assertSpanCount(0, charSequencesFromString[3]); - assertEquals("efg", charSequencesFromSpanned[3].toString()); - assertSpanCount(0, charSequencesFromSpanned[3]); - - // text: "hij" - // span1: - // span2: - // span3: ^ - assertEquals("hij", charSequencesFromString[4].toString()); - assertSpanCount(0, charSequencesFromString[4]); - assertEquals("hij", charSequencesFromSpanned[4].toString()); - assertSpanCount(1, charSequencesFromSpanned[4]); - assertSpan(charSequencesFromSpanned[4], span3, 1, 2, SPAN3_FLAGS); - - // text: "" - // span1: - // span2: - // span3: - assertEquals("", charSequencesFromString[5].toString()); - assertSpanCount(0, charSequencesFromString[5]); - assertEquals("", charSequencesFromSpanned[5].toString()); - assertSpanCount(0, charSequencesFromSpanned[5]); - - // text: "" - // span1: - // span2: - // span3: - assertEquals("", charSequencesFromString[6].toString()); - assertSpanCount(0, charSequencesFromString[6]); - assertEquals("", charSequencesFromSpanned[6].toString()); - assertSpanCount(0, charSequencesFromSpanned[6]); - } - - public void testSplitCharSequencePreserveTrailingEmptySegmengs() { - assertEquals(1, StringUtils.split("", " ", - false /* preserveTrailingEmptySegmengs */).length); - assertEquals(1, StringUtils.split(new SpannedString(""), " ", - false /* preserveTrailingEmptySegmengs */).length); - - assertEquals(1, StringUtils.split("", " ", - true /* preserveTrailingEmptySegmengs */).length); - assertEquals(1, StringUtils.split(new SpannedString(""), " ", - true /* preserveTrailingEmptySegmengs */).length); - - assertEquals(0, StringUtils.split(" ", " ", - false /* preserveTrailingEmptySegmengs */).length); - assertEquals(0, StringUtils.split(new SpannedString(" "), " ", - false /* preserveTrailingEmptySegmengs */).length); - - assertEquals(2, StringUtils.split(" ", " ", - true /* preserveTrailingEmptySegmengs */).length); - assertEquals(2, StringUtils.split(new SpannedString(" "), " ", - true /* preserveTrailingEmptySegmengs */).length); - - assertEquals(3, StringUtils.split("a b c ", " ", - false /* preserveTrailingEmptySegmengs */).length); - assertEquals(3, StringUtils.split(new SpannedString("a b c "), " ", - false /* preserveTrailingEmptySegmengs */).length); - - assertEquals(5, StringUtils.split("a b c ", " ", - true /* preserveTrailingEmptySegmengs */).length); - assertEquals(5, StringUtils.split(new SpannedString("a b c "), " ", - true /* preserveTrailingEmptySegmengs */).length); - - assertEquals(6, StringUtils.split("a b ", " ", - false /* preserveTrailingEmptySegmengs */).length); - assertEquals(6, StringUtils.split(new SpannedString("a b "), " ", - false /* preserveTrailingEmptySegmengs */).length); - - assertEquals(7, StringUtils.split("a b ", " ", - true /* preserveTrailingEmptySegmengs */).length); - assertEquals(7, StringUtils.split(new SpannedString("a b "), " ", - true /* preserveTrailingEmptySegmengs */).length); - } } diff --git a/tests/src/com/android/inputmethod/latin/common/UnicodeSurrogateTests.java b/tests/src/com/android/inputmethod/latin/common/UnicodeSurrogateTests.java new file mode 100644 index 000000000..59bb08292 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/common/UnicodeSurrogateTests.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015 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.common; + +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + +@SmallTest +public class UnicodeSurrogateTests extends AndroidTestCase { + + public void testIsLowSurrogate() { + assertFalse(UnicodeSurrogate.isLowSurrogate('\uD7FF')); + assertTrue(UnicodeSurrogate.isLowSurrogate('\uD83D')); + assertFalse(UnicodeSurrogate.isLowSurrogate('\uDC00')); + } + + public void testIsHighSurrogate() { + assertFalse(UnicodeSurrogate.isHighSurrogate('\uDBFF')); + assertTrue(UnicodeSurrogate.isHighSurrogate('\uDE25')); + assertFalse(UnicodeSurrogate.isHighSurrogate('\uE000')); + } +} diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java deleted file mode 100644 index 406046a74..000000000 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java +++ /dev/null @@ -1,696 +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.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.FormatOptions; -import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode; -import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray; -import com.android.inputmethod.latin.utils.BinaryDictionaryUtils; -import com.android.inputmethod.latin.utils.ByteArrayDictBuffer; - -import java.io.File; -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; -import java.util.TreeMap; - -/** - * Unit tests for BinaryDictDecoderUtils and BinaryDictEncoderUtils. - */ -@LargeTest -public class BinaryDictDecoderEncoderTests extends AndroidTestCase { - private static final String TAG = BinaryDictDecoderEncoderTests.class.getSimpleName(); - 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 ArrayList<String> sWords = new ArrayList<>(); - private static final ArrayList<String> sWordsWithVariousCodePoints = new ArrayList<>(); - private static final SparseArray<List<Integer>> sEmptyBigrams = new SparseArray<>(); - private static final SparseArray<List<Integer>> sStarBigrams = new SparseArray<>(); - private static final SparseArray<List<Integer>> sChainBigrams = new SparseArray<>(); - private static final HashMap<String, List<String>> sShortcuts = new HashMap<>(); - - public BinaryDictDecoderEncoderTests() { - this(System.currentTimeMillis(), DEFAULT_MAX_UNIGRAMS); - } - - public BinaryDictDecoderEncoderTests(final long seed, final int maxUnigrams) { - super(); - BinaryDictionaryUtils.setCurrentTimeForTest(0); - Log.e(TAG, "Testing dictionary: seed is " + seed); - final Random random = new Random(seed); - sWords.clear(); - sWordsWithVariousCodePoints.clear(); - generateWords(maxUnigrams, random); - - for (int i = 0; i < sWords.size(); ++i) { - sChainBigrams.put(i, new ArrayList<Integer>()); - if (i > 0) { - sChainBigrams.get(i - 1).add(i); - } - } - - sStarBigrams.put(0, new ArrayList<Integer>()); - // MAX - 1 because we added one above already - final int maxBigrams = Math.min(sWords.size(), FormatSpec.MAX_BIGRAMS_IN_A_PTNODE - 1); - for (int i = 1; i < maxBigrams; ++i) { - sStarBigrams.get(0).add(i); - } - - sShortcuts.clear(); - for (int i = 0; i < NUM_OF_NODES_HAVING_SHORTCUTS; ++i) { - final int from = Math.abs(random.nextInt()) % sWords.size(); - sShortcuts.put(sWords.get(from), new ArrayList<String>()); - for (int j = 0; j < NUM_OF_SHORTCUTS; ++j) { - final int to = Math.abs(random.nextInt()) % sWords.size(); - sShortcuts.get(sWords.get(from)).add(sWords.get(to)); - } - } - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - BinaryDictionaryUtils.setCurrentTimeForTest(0); - } - - @Override - protected void tearDown() throws Exception { - // Quit test mode. - BinaryDictionaryUtils.setCurrentTimeForTest(-1); - super.tearDown(); - } - - private void generateWords(final int number, final Random random) { - final int[] codePointSet = CodePointUtils.generateCodePointSet(DEFAULT_CODE_POINT_SET_SIZE, - random); - final Set<String> wordSet = new HashSet<>(); - 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); - } - - /** - * Adds unigrams to the dictionary. - */ - private void addUnigrams(final int number, final FusionDictionary dict, - final List<String> words, final HashMap<String, List<String>> shortcutMap) { - for (int i = 0; i < number; ++i) { - final String word = words.get(i); - final ArrayList<WeightedString> shortcuts = new ArrayList<>(); - if (shortcutMap != null && shortcutMap.containsKey(word)) { - for (final String shortcut : shortcutMap.get(word)) { - shortcuts.add(new WeightedString(shortcut, UNIGRAM_FREQ)); - } - } - dict.add(word, new ProbabilityInfo(UNIGRAM_FREQ), - (shortcutMap == null) ? null : shortcuts, false /* isNotAWord */); - } - } - - private void addBigrams(final FusionDictionary dict, - final List<String> words, - final SparseArray<List<Integer>> bigrams) { - 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), new ProbabilityInfo(BIGRAM_FREQ)); - } - } - } - -// The following is useful to dump the dictionary into a textual file, but it can't compile -// on-device, so it's commented out. -// private void dumpToCombinedFileForDebug(final FusionDictionary dict, final String filename) -// throws IOException { -// com.android.inputmethod.latin.dicttool.CombinedInputOutput.writeDictionaryCombined( -// new java.io.FileWriter(new File(filename)), dict); -// } - - private long timeWritingDictToFile(final File file, final FusionDictionary dict, - final FormatSpec.FormatOptions formatOptions) { - - long now = -1, diff = -1; - - try { - 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 - // function above - // dumpToCombinedFileForDebug(file, "/tmp/foo"); - dictEncoder.writeDictionary(dict, formatOptions); - diff = System.currentTimeMillis() - now; - } catch (IOException e) { - Log.e(TAG, "IO exception while writing file", e); - } catch (UnsupportedFormatException e) { - Log.e(TAG, "UnsupportedFormatException", e); - } - - return diff; - } - - private void checkDictionary(final FusionDictionary dict, final List<String> words, - final SparseArray<List<Integer>> bigrams, - final HashMap<String, List<String>> shortcutMap) { - assertNotNull(dict); - - // check unigram - for (final String word : words) { - final PtNode ptNode = FusionDictionary.findWordInTree(dict.mRootNodeArray, word); - assertNotNull(ptNode); - } - - // check bigram - for (int i = 0; i < bigrams.size(); ++i) { - final int w1 = bigrams.keyAt(i); - for (final int w2 : bigrams.valueAt(i)) { - final PtNode ptNode = FusionDictionary.findWordInTree(dict.mRootNodeArray, - words.get(w1)); - assertNotNull(words.get(w1) + "," + words.get(w2), ptNode.getBigram(words.get(w2))); - } - } - - // check shortcut - if (shortcutMap != null) { - for (final Entry<String, List<String>> entry : shortcutMap.entrySet()) { - assertTrue(words.contains(entry.getKey())); - final PtNode ptNode = FusionDictionary.findWordInTree(dict.mRootNodeArray, - entry.getKey()); - for (final String word : entry.getValue()) { - assertNotNull("shortcut not found: " + entry.getKey() + ", " + word, - ptNode.getShortcut(word)); - } - } - } - } - - private String outputOptions(final int bufferType, - final FormatSpec.FormatOptions formatOptions) { - String result = " : buffer type = " - + ((bufferType == BinaryDictUtils.USE_BYTE_BUFFER) ? "byte buffer" : "byte array"); - return result + " : version = " + formatOptions.mVersion; - } - - // 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) { - long now, diff = -1; - - FusionDictionary dict = null; - try { - final DictDecoder dictDecoder = BinaryDictIOUtils.getDictDecoder(file, 0, file.length(), - bufferType); - now = System.currentTimeMillis(); - dict = dictDecoder.readDictionaryBinary(false /* deleteDictIfBroken */); - diff = System.currentTimeMillis() - now; - } catch (IOException e) { - Log.e(TAG, "IOException while reading dictionary", e); - } catch (UnsupportedFormatException e) { - Log.e(TAG, "Unsupported format", e); - } - - checkDictionary(dict, words, bigrams, shortcutMap); - return diff; - } - - // Tests for readDictionaryBinary and writeDictionaryBinary - private String runReadAndWrite(final List<String> words, - final SparseArray<List<Integer>> bigrams, final HashMap<String, List<String>> shortcuts, - final int bufferType, final FormatSpec.FormatOptions formatOptions, - final String message) { - - final String dictName = "runReadAndWrite"; - final String dictVersion = Long.toString(System.currentTimeMillis()); - final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions, - getContext().getCacheDir()); - - final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - 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); - - return "PROF: read=" + read + "ms, write=" + write + "ms :" + message - + " : " + outputOptions(bufferType, formatOptions); - } - - private void runReadAndWriteTests(final List<String> results, final int bufferType, - final FormatSpec.FormatOptions formatOptions) { - results.add(runReadAndWrite(sWords, sEmptyBigrams, null /* shortcuts */, bufferType, - formatOptions, "unigram")); - results.add(runReadAndWrite(sWords, sChainBigrams, null /* shortcuts */, bufferType, - formatOptions, "chain")); - results.add(runReadAndWrite(sWords, sStarBigrams, null /* shortcuts */, bufferType, - formatOptions, "star")); - results.add(runReadAndWrite(sWords, sEmptyBigrams, sShortcuts, bufferType, formatOptions, - "unigram with shortcuts")); - results.add(runReadAndWrite(sWords, sChainBigrams, sShortcuts, bufferType, formatOptions, - "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. - public void testCharEncoding() { - // the max length of a word in sWords is less than 50. - // See generateWords. - final byte[] buffer = new byte[50 * 3]; - final DictBuffer dictBuffer = new ByteArrayDictBuffer(buffer); - for (final String word : sWords) { - Arrays.fill(buffer, (byte) 0); - CharEncoding.writeString(buffer, 0, word); - dictBuffer.position(0); - final String str = CharEncoding.readString(dictBuffer); - assertEquals(word, str); - } - } - - public void testReadAndWriteWithByteBuffer() { - final List<String> results = new ArrayList<>(); - - 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); - } - } - - public void testReadAndWriteWithByteArray() { - final List<String> results = new ArrayList<>(); - - 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); - } - } - - // Tests for readUnigramsAndBigramsBinary - - private void checkWordMap(final List<String> expectedWords, - final SparseArray<List<Integer>> expectedBigrams, - final TreeMap<Integer, String> resultWords, - final TreeMap<Integer, Integer> resultFrequencies, - final TreeMap<Integer, ArrayList<PendingAttribute>> resultBigrams, - final boolean checkProbability) { - // check unigrams - final Set<String> actualWordsSet = new HashSet<>(resultWords.values()); - final Set<String> expectedWordsSet = new HashSet<>(expectedWords); - assertEquals(actualWordsSet, expectedWordsSet); - if (checkProbability) { - for (int freq : resultFrequencies.values()) { - assertEquals(freq, UNIGRAM_FREQ); - } - } - - // check bigrams - final HashMap<String, Set<String>> expBigrams = new HashMap<>(); - 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 HashSet<String>()); - } - expBigrams.get(word1).add(expectedWords.get(w2)); - } - } - - final HashMap<String, Set<String>> actBigrams = new HashMap<>(); - 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 HashSet<String>()); - } - actBigrams.get(word1).add(word2); - - 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 boolean checkProbability) { - final TreeMap<Integer, String> resultWords = new TreeMap<>(); - final TreeMap<Integer, ArrayList<PendingAttribute>> resultBigrams = new TreeMap<>(); - final TreeMap<Integer, Integer> resultFreqs = new TreeMap<>(); - - long now = -1, diff = -1; - try { - final DictDecoder dictDecoder = BinaryDictIOUtils.getDictDecoder(file, 0, file.length(), - bufferType); - now = System.currentTimeMillis(); - dictDecoder.readUnigramsAndBigramsBinary(resultWords, resultFreqs, resultBigrams); - diff = System.currentTimeMillis() - now; - } catch (IOException e) { - Log.e(TAG, "IOException", e); - } catch (UnsupportedFormatException e) { - Log.e(TAG, "UnsupportedFormatException", e); - } - - checkWordMap(words, bigrams, resultWords, resultFreqs, resultBigrams, checkProbability); - return diff; - } - - private String runReadUnigramsAndBigramsBinary(final ArrayList<String> words, - final SparseArray<List<Integer>> bigrams, final int bufferType, - final FormatSpec.FormatOptions formatOptions, final String message) { - final String dictName = "runReadUnigrams"; - final String dictVersion = Long.toString(System.currentTimeMillis()); - final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions, - getContext().getCacheDir()); - - // making the dictionary from lists of words. - final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - 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.mHasTimestamp /* checkProbability */); - long fullReading = timeReadingAndCheckDict(file, words, bigrams, null /* shortcutMap */, - bufferType); - - return "readDictionaryBinary=" + fullReading + ", readUnigramsAndBigramsBinary=" + wordMap - + " : " + message + " : " + outputOptions(bufferType, formatOptions); - } - - private void runReadUnigramsAndBigramsTests(final ArrayList<String> results, - final int bufferType, final FormatSpec.FormatOptions formatOptions) { - results.add(runReadUnigramsAndBigramsBinary(sWords, sEmptyBigrams, bufferType, - formatOptions, "unigram")); - results.add(runReadUnigramsAndBigramsBinary(sWords, sChainBigrams, bufferType, - formatOptions, "chain")); - results.add(runReadUnigramsAndBigramsBinary(sWords, sStarBigrams, bufferType, - formatOptions, "star")); - } - - public void testReadUnigramsAndBigramsBinaryWithByteBuffer() { - final ArrayList<String> results = new ArrayList<>(); - - runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_BUFFER, - BinaryDictUtils.VERSION2_OPTIONS); - - for (final String result : results) { - Log.d(TAG, result); - } - } - - public void testReadUnigramsAndBigramsBinaryWithByteArray() { - final ArrayList<String> results = new ArrayList<>(); - - runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_ARRAY, - BinaryDictUtils.VERSION2_OPTIONS); - - for (final String result : results) { - Log.d(TAG, result); - } - } - - // Tests for getTerminalPosition - private String getWordFromBinary(final DictDecoder dictDecoder, final int address) { - if (dictDecoder.getPosition() != 0) dictDecoder.setPosition(0); - - DictionaryHeader fileHeader = null; - try { - fileHeader = dictDecoder.readHeader(); - } catch (IOException e) { - return null; - } catch (UnsupportedFormatException e) { - return null; - } - if (fileHeader == null) return null; - return BinaryDictDecoderUtils.getWordAtPosition(dictDecoder, fileHeader.mBodyOffset, - address).mWord; - } - - private long checkGetTerminalPosition(final DictDecoder dictDecoder, final String word, - final boolean contained) { - long diff = -1; - int position = -1; - try { - final long now = System.nanoTime(); - position = dictDecoder.getTerminalPosition(word); - diff = System.nanoTime() - now; - } catch (IOException e) { - Log.e(TAG, "IOException while getTerminalPosition", e); - } catch (UnsupportedFormatException e) { - Log.e(TAG, "UnsupportedFormatException while getTerminalPosition", e); - } - - assertEquals(FormatSpec.NOT_VALID_WORD != position, contained); - if (contained) assertEquals(getWordFromBinary(dictDecoder, position), word); - return diff; - } - - private void runGetTerminalPosition(final ArrayList<String> words, - final SparseArray<List<Integer>> bigrams, final int bufferType, - final FormatOptions formatOptions, final String message) { - final String dictName = "testGetTerminalPosition"; - final String dictVersion = Long.toString(System.currentTimeMillis()); - final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions, - getContext().getCacheDir()); - - final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion, formatOptions)); - addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */); - addBigrams(dict, words, bigrams); - timeWritingDictToFile(file, dict, formatOptions); - - final DictDecoder dictDecoder = BinaryDictIOUtils.getDictDecoder(file, 0, file.length(), - DictDecoder.USE_BYTEARRAY); - try { - dictDecoder.openDictBuffer(); - } catch (IOException e) { - 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()); - - try { - // too long word - final String longWord = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"; - assertEquals(FormatSpec.NOT_VALID_WORD, dictDecoder.getTerminalPosition(longWord)); - - // null - assertEquals(FormatSpec.NOT_VALID_WORD, dictDecoder.getTerminalPosition(null)); - - // empty string - assertEquals(FormatSpec.NOT_VALID_WORD, dictDecoder.getTerminalPosition("")); - } catch (IOException e) { - } catch (UnsupportedFormatException e) { - } - - // Test a word that is contained within the dictionary. - long sum = 0; - for (int i = 0; i < sWords.size(); ++i) { - final long time = checkGetTerminalPosition(dictDecoder, sWords.get(i), true); - sum += time == -1 ? 0 : time; - } - Log.d(TAG, "per search : " + (((double)sum) / sWords.size() / 1000000) + " : " + message - + " : " + outputOptions(bufferType, formatOptions)); - - // Test a word that isn't contained within the dictionary. - final Random random = new Random((int)System.currentTimeMillis()); - final int[] codePointSet = CodePointUtils.generateCodePointSet(DEFAULT_CODE_POINT_SET_SIZE, - random); - for (int i = 0; i < 1000; ++i) { - final String word = CodePointUtils.generateWord(random, codePointSet); - if (sWords.indexOf(word) != -1) continue; - checkGetTerminalPosition(dictDecoder, word, false); - } - } - - private void runGetTerminalPositionTests(final int bufferType, - final FormatOptions formatOptions) { - runGetTerminalPosition(sWords, sEmptyBigrams, bufferType, formatOptions, "unigram"); - } - - public void testGetTerminalPosition() { - final ArrayList<String> results = new ArrayList<>(); - - 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); - } - } - - 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 FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - 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 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, - false /* isBeginningOfSentence */); - 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 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<>(words); - final HashSet<Pair<String, String>> bigramSet = new HashSet<>(); - - 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<>(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<>(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/BinaryDictDecoderUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java index 96604a197..be75565bb 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderUtils.java @@ -17,11 +17,16 @@ package com.android.inputmethod.latin.makedict; import com.android.inputmethod.annotations.UsedForTesting; +import com.android.inputmethod.latin.makedict.UnsupportedFormatException; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.LinkedList; + +import javax.annotation.Nonnull; /** * Decodes binary files for a FusionDictionary. @@ -109,15 +114,20 @@ public final class BinaryDictDecoderUtils { * A class grouping utility function for our specific character encoding. */ static final class CharEncoding { - private static final int MINIMAL_ONE_BYTE_CHARACTER_VALUE = 0x20; - private static final int MAXIMAL_ONE_BYTE_CHARACTER_VALUE = 0xFF; /** * Helper method to find out whether this code fits on one byte */ - private static boolean fitsOnOneByte(final int character) { - return character >= MINIMAL_ONE_BYTE_CHARACTER_VALUE - && character <= MAXIMAL_ONE_BYTE_CHARACTER_VALUE; + private static boolean fitsOnOneByte(final int character, + final HashMap<Integer, Integer> codePointToOneByteCodeMap) { + int codePoint = character; + if (codePointToOneByteCodeMap != null) { + if (codePointToOneByteCodeMap.containsKey(character)) { + codePoint = codePointToOneByteCodeMap.get(character); + } + } + return codePoint >= FormatSpec.MINIMAL_ONE_BYTE_CHARACTER_VALUE + && codePoint <= FormatSpec.MAXIMAL_ONE_BYTE_CHARACTER_VALUE; } /** @@ -137,9 +147,10 @@ public final class BinaryDictDecoderUtils { * @param character the character code. * @return the size in binary encoded-form, either 1 or 3 bytes. */ - static int getCharSize(final int character) { + static int getCharSize(final int character, + final HashMap<Integer, Integer> codePointToOneByteCodeMap) { // See char encoding in FusionDictionary.java - if (fitsOnOneByte(character)) return 1; + if (fitsOnOneByte(character, codePointToOneByteCodeMap)) return 1; if (FormatSpec.INVALID_CHARACTER == character) return 1; return 3; } @@ -147,9 +158,10 @@ public final class BinaryDictDecoderUtils { /** * Compute the byte size of a character array. */ - static int getCharArraySize(final int[] chars) { + static int getCharArraySize(final int[] chars, + final HashMap<Integer, Integer> codePointToOneByteCodeMap) { int size = 0; - for (int character : chars) size += getCharSize(character); + for (int character : chars) size += getCharSize(character, codePointToOneByteCodeMap); return size; } @@ -158,12 +170,21 @@ public final class BinaryDictDecoderUtils { * * @param codePoints the code point array to write. * @param buffer the byte buffer to write to. - * @param index the index in buffer to write the character array to. + * @param fromIndex the index in buffer to write the character array to. + * @param codePointToOneByteCodeMap the map to convert the code point. * @return the index after the last character. */ - static int writeCharArray(final int[] codePoints, final byte[] buffer, int index) { + static int writeCharArray(final int[] codePoints, final byte[] buffer, final int fromIndex, + final HashMap<Integer, Integer> codePointToOneByteCodeMap) { + int index = fromIndex; for (int codePoint : codePoints) { - if (1 == getCharSize(codePoint)) { + if (codePointToOneByteCodeMap != null) { + if (codePointToOneByteCodeMap.containsKey(codePoint)) { + // Convert code points + codePoint = codePointToOneByteCodeMap.get(codePoint); + } + } + if (1 == getCharSize(codePoint, codePointToOneByteCodeMap)) { buffer[index++] = (byte)codePoint; } else { buffer[index++] = (byte)(0xFF & (codePoint >> 16)); @@ -184,12 +205,19 @@ public final class BinaryDictDecoderUtils { * @param word the string to write. * @return the size written, in bytes. */ - static int writeString(final byte[] buffer, final int origin, final String word) { + static int writeString(final byte[] buffer, final int origin, final String word, + final HashMap<Integer, Integer> codePointToOneByteCodeMap) { final int length = word.length(); int index = origin; for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) { - final int codePoint = word.codePointAt(i); - if (1 == getCharSize(codePoint)) { + int codePoint = word.codePointAt(i); + if (codePointToOneByteCodeMap != null) { + if (codePointToOneByteCodeMap.containsKey(codePoint)) { + // Convert code points + codePoint = codePointToOneByteCodeMap.get(codePoint); + } + } + if (1 == getCharSize(codePoint, codePointToOneByteCodeMap)) { buffer[index++] = (byte)codePoint; } else { buffer[index++] = (byte)(0xFF & (codePoint >> 16)); @@ -210,12 +238,13 @@ public final class BinaryDictDecoderUtils { * @param word the string to write. * @return the size written, in bytes. */ - static int writeString(final OutputStream stream, final String word) throws IOException { + static int writeString(final OutputStream stream, final String word, + final HashMap<Integer, Integer> codePointToOneByteCodeMap) throws IOException { final int length = word.length(); int written = 0; for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) { final int codePoint = word.codePointAt(i); - final int charSize = getCharSize(codePoint); + final int charSize = getCharSize(codePoint, codePointToOneByteCodeMap); if (1 == charSize) { stream.write((byte) codePoint); } else { @@ -253,7 +282,7 @@ public final class BinaryDictDecoderUtils { */ static int readChar(final DictBuffer dictBuffer) { int character = dictBuffer.readUnsignedByte(); - if (!fitsOnOneByte(character)) { + if (!fitsOnOneByte(character, null)) { if (FormatSpec.PTNODE_CHARACTERS_TERMINATOR == character) { return FormatSpec.INVALID_CHARACTER; } @@ -271,10 +300,9 @@ public final class BinaryDictDecoderUtils { final int msb = dictBuffer.readUnsignedByte(); if (FormatSpec.MAX_PTNODES_FOR_ONE_BYTE_PTNODE_COUNT >= msb) { return msb; - } else { - return ((FormatSpec.MAX_PTNODES_FOR_ONE_BYTE_PTNODE_COUNT & msb) << 8) - + dictBuffer.readUnsignedByte(); } + return ((FormatSpec.MAX_PTNODES_FOR_ONE_BYTE_PTNODE_COUNT & msb) << 8) + + dictBuffer.readUnsignedByte(); } /** @@ -338,6 +366,43 @@ public final class BinaryDictDecoderUtils { } /** + * Helper method that brutally decodes a header from a byte array. + * + * @param headerBuffer a buffer containing the bytes of the header. + * @return a hashmap of the attributes stored in the header + */ + @Nonnull + public static HashMap<String, String> decodeHeaderAttributes(@Nonnull final byte[] headerBuffer) + throws UnsupportedFormatException { + final StringBuilder sb = new StringBuilder(); + final LinkedList<String> keyValues = new LinkedList<>(); + int index = 0; + while (index < headerBuffer.length) { + if (headerBuffer[index] == FormatSpec.PTNODE_CHARACTERS_TERMINATOR) { + keyValues.add(sb.toString()); + sb.setLength(0); + } else if (CharEncoding.fitsOnOneByte(headerBuffer[index] & 0xFF, + null /* codePointTable */)) { + sb.appendCodePoint(headerBuffer[index] & 0xFF); + } else { + sb.appendCodePoint(((headerBuffer[index] & 0xFF) << 16) + + ((headerBuffer[index + 1] & 0xFF) << 8) + + (headerBuffer[index + 2] & 0xFF)); + index += 2; + } + index += 1; + } + if ((keyValues.size() & 1) != 0) { + throw new UnsupportedFormatException("Odd number of attributes"); + } + final HashMap<String, String> attributes = new HashMap<>(); + for (int i = 0; i < keyValues.size(); i += 2) { + attributes.put(keyValues.get(i), keyValues.get(i + 1)); + } + return attributes; + } + + /** * Helper method to pass a file name instead of a File object to isBinaryDictionary. */ public static boolean isBinaryDictionary(final String filename) { diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java index eabd8d722..bd5136583 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictEncoderUtils.java @@ -16,9 +16,7 @@ package com.android.inputmethod.latin.makedict; -import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding; -import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer; import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions; import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode; import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray; @@ -27,6 +25,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map.Entry; /** * Encodes binary files for a FusionDictionary. @@ -59,8 +59,9 @@ public class BinaryDictEncoderUtils { * @param characters the character array * @return the size of the char array, including the terminator if any */ - static int getPtNodeCharactersSize(final int[] characters) { - int size = CharEncoding.getCharArraySize(characters); + static int getPtNodeCharactersSize(final int[] characters, + final HashMap<Integer, Integer> codePointToOneByteCodeMap) { + int size = CharEncoding.getCharArraySize(characters, codePointToOneByteCodeMap); if (characters.length > 1) size += FormatSpec.PTNODE_TERMINATOR_SIZE; return size; } @@ -74,8 +75,9 @@ public class BinaryDictEncoderUtils { * @param ptNode the PtNode * @return the size of the char array, including the terminator if any */ - private static int getPtNodeCharactersSize(final PtNode ptNode) { - return getPtNodeCharactersSize(ptNode.mChars); + private static int getPtNodeCharactersSize(final PtNode ptNode, + final HashMap<Integer, Integer> codePointToOneByteCodeMap) { + return getPtNodeCharactersSize(ptNode.mChars, codePointToOneByteCodeMap); } /** @@ -88,49 +90,19 @@ public class BinaryDictEncoderUtils { } /** - * Compute the size of a shortcut in bytes. - */ - private static int getShortcutSize(final WeightedString shortcut) { - int size = FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE; - final String word = shortcut.mWord; - final int length = word.length(); - for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) { - final int codePoint = word.codePointAt(i); - size += CharEncoding.getCharSize(codePoint); - } - size += FormatSpec.PTNODE_TERMINATOR_SIZE; - return size; - } - - /** - * Compute the size of a shortcut list in bytes. - * - * This is known in advance and does not change according to position in the file - * like address lists do. - */ - static int getShortcutListSize(final ArrayList<WeightedString> shortcutList) { - if (null == shortcutList || shortcutList.isEmpty()) return 0; - int size = FormatSpec.PTNODE_SHORTCUT_LIST_SIZE_SIZE; - for (final WeightedString shortcut : shortcutList) { - size += getShortcutSize(shortcut); - } - return size; - } - - /** * Compute the maximum size of a PtNode, assuming 3-byte addresses for everything. * * @param ptNode the PtNode to compute the size of. * @return the maximum size of the PtNode. */ - private static int getPtNodeMaximumSize(final PtNode ptNode) { - int size = getNodeHeaderSize(ptNode); + private static int getPtNodeMaximumSize(final PtNode ptNode, + final HashMap<Integer, Integer> codePointToOneByteCodeMap) { + int size = getNodeHeaderSize(ptNode, codePointToOneByteCodeMap); if (ptNode.isTerminal()) { // If terminal, one byte for the frequency. size += FormatSpec.PTNODE_FREQUENCY_SIZE; } size += FormatSpec.PTNODE_MAX_ADDRESS_SIZE; // For children address - size += getShortcutListSize(ptNode.mShortcutTargets); if (null != ptNode.mBigrams) { size += (FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE + FormatSpec.PTNODE_ATTRIBUTE_MAX_ADDRESS_SIZE) @@ -146,10 +118,11 @@ public class BinaryDictEncoderUtils { * * @param ptNodeArray the node array to compute the maximum size of. */ - private static void calculatePtNodeArrayMaximumSize(final PtNodeArray ptNodeArray) { + private static void calculatePtNodeArrayMaximumSize(final PtNodeArray ptNodeArray, + final HashMap<Integer, Integer> codePointToOneByteCodeMap) { int size = getPtNodeCountSize(ptNodeArray); for (PtNode node : ptNodeArray.mData) { - final int nodeSize = getPtNodeMaximumSize(node); + final int nodeSize = getPtNodeMaximumSize(node, codePointToOneByteCodeMap); node.mCachedSize = nodeSize; size += nodeSize; } @@ -161,8 +134,10 @@ public class BinaryDictEncoderUtils { * * @param ptNode the PtNode of which to compute the size of the header */ - private static int getNodeHeaderSize(final PtNode ptNode) { - return FormatSpec.PTNODE_FLAGS_SIZE + getPtNodeCharactersSize(ptNode); + private static int getNodeHeaderSize(final PtNode ptNode, + final HashMap<Integer, Integer> codePointToOneByteCodeMap) { + return FormatSpec.PTNODE_FLAGS_SIZE + getPtNodeCharactersSize(ptNode, + codePointToOneByteCodeMap); } /** @@ -188,8 +163,9 @@ public class BinaryDictEncoderUtils { } } - static int writeUIntToBuffer(final byte[] buffer, int position, final int value, + static int writeUIntToBuffer(final byte[] buffer, final int fromPosition, final int value, final int size) { + int position = fromPosition; switch(size) { case 4: buffer[position++] = (byte) ((value >> 24) & 0xFF); @@ -229,27 +205,6 @@ public class BinaryDictEncoderUtils { } } - @UsedForTesting - static void writeUIntToDictBuffer(final DictBuffer dictBuffer, final int value, - final int size) { - switch(size) { - case 4: - dictBuffer.put((byte) ((value >> 24) & 0xFF)); - /* fall through */ - case 3: - dictBuffer.put((byte) ((value >> 16) & 0xFF)); - /* fall through */ - case 2: - dictBuffer.put((byte) ((value >> 8) & 0xFF)); - /* fall through */ - case 1: - dictBuffer.put((byte) (value & 0xFF)); - break; - default: - /* nop */ - } - } - // End utility methods // This method is responsible for finding a nice ordering of the nodes that favors run-time @@ -313,11 +268,9 @@ public class BinaryDictEncoderUtils { return targetNodeArray.mCachedAddressAfterUpdate - (currentNodeArray.mCachedAddressAfterUpdate + offsetFromStartOfCurrentNodeArray); - } else { - return targetNodeArray.mCachedAddressBeforeUpdate - - (currentNodeArray.mCachedAddressBeforeUpdate - + offsetFromStartOfCurrentNodeArray); } + return targetNodeArray.mCachedAddressBeforeUpdate + - (currentNodeArray.mCachedAddressBeforeUpdate + offsetFromStartOfCurrentNodeArray); } /** @@ -345,9 +298,8 @@ public class BinaryDictEncoderUtils { final int newOffsetBasePoint = currentNodeArray.mCachedAddressAfterUpdate + offsetFromStartOfCurrentNodeArray; return targetPtNode.mCachedAddressAfterUpdate - newOffsetBasePoint; - } else { - return targetPtNode.mCachedAddressBeforeUpdate - oldOffsetBasePoint; } + return targetPtNode.mCachedAddressBeforeUpdate - oldOffsetBasePoint; } /** @@ -365,7 +317,8 @@ public class BinaryDictEncoderUtils { * @return false if none of the cached addresses inside the node array changed, true otherwise. */ private static boolean computeActualPtNodeArraySize(final PtNodeArray ptNodeArray, - final FusionDictionary dict) { + final FusionDictionary dict, + final HashMap<Integer, Integer> codePointToOneByteCodeMap) { boolean changed = false; int size = getPtNodeCountSize(ptNodeArray); for (PtNode ptNode : ptNodeArray.mData) { @@ -373,7 +326,7 @@ public class BinaryDictEncoderUtils { if (ptNode.mCachedAddressAfterUpdate != ptNode.mCachedAddressBeforeUpdate) { changed = true; } - int nodeSize = getNodeHeaderSize(ptNode); + int nodeSize = getNodeHeaderSize(ptNode, codePointToOneByteCodeMap); if (ptNode.isTerminal()) { nodeSize += FormatSpec.PTNODE_FREQUENCY_SIZE; } @@ -381,7 +334,6 @@ public class BinaryDictEncoderUtils { nodeSize += getByteSize(getOffsetToTargetNodeArrayDuringUpdate(ptNodeArray, nodeSize + size, ptNode.mChildren)); } - nodeSize += getShortcutListSize(ptNode.mShortcutTargets); if (null != ptNode.mBigrams) { for (WeightedString bigram : ptNode.mBigrams) { final int offset = getOffsetToTargetPtNodeDuringUpdate(ptNodeArray, @@ -452,10 +404,11 @@ public class BinaryDictEncoderUtils { * @return the same array it was passed. The nodes have been updated for address and size. */ /* package */ static ArrayList<PtNodeArray> computeAddresses(final FusionDictionary dict, - final ArrayList<PtNodeArray> flatNodes) { + final ArrayList<PtNodeArray> flatNodes, + final HashMap<Integer, Integer> codePointToOneByteCodeMap) { // First get the worst possible sizes and offsets for (final PtNodeArray n : flatNodes) { - calculatePtNodeArrayMaximumSize(n); + calculatePtNodeArrayMaximumSize(n, codePointToOneByteCodeMap); } final int offset = initializePtNodeArraysCachedAddresses(flatNodes); @@ -470,7 +423,8 @@ public class BinaryDictEncoderUtils { for (final PtNodeArray ptNodeArray : flatNodes) { ptNodeArray.mCachedAddressAfterUpdate = ptNodeArrayStartOffset; final int oldNodeArraySize = ptNodeArray.mCachedSize; - final boolean changed = computeActualPtNodeArraySize(ptNodeArray, dict); + final boolean changed = computeActualPtNodeArraySize(ptNodeArray, dict, + codePointToOneByteCodeMap); final int newNodeArraySize = ptNodeArray.mCachedSize; if (oldNodeArraySize < newNodeArraySize) { throw new RuntimeException("Increased size ?!"); @@ -521,12 +475,13 @@ public class BinaryDictEncoderUtils { * Helper method to write a children position to a file. * * @param buffer the buffer to write to. - * @param index the index in the buffer to write the address to. + * @param fromIndex the index in the buffer to write the address to. * @param position the position to write. * @return the size in bytes the address actually took. */ - /* package */ static int writeChildrenPosition(final byte[] buffer, int index, + /* package */ static int writeChildrenPosition(final byte[] buffer, final int fromIndex, final int position) { + int index = fromIndex; switch (getByteSize(position)) { case 1: buffer[index++] = (byte)position; @@ -548,42 +503,19 @@ public class BinaryDictEncoderUtils { } /** - * Helper method to write a signed children position to a file. - * - * @param buffer the buffer to write to. - * @param index the index in the buffer to write the address to. - * @param position the position to write. - * @return the size in bytes the address actually took. - */ - /* package */ static int writeSignedChildrenPosition(final byte[] buffer, int index, - final int position) { - if (!BinaryDictIOUtils.hasChildrenAddress(position)) { - buffer[index] = buffer[index + 1] = buffer[index + 2] = 0; - } else { - final int absPosition = Math.abs(position); - buffer[index++] = - (byte)((position < 0 ? FormatSpec.MSB8 : 0) | (0xFF & (absPosition >> 16))); - buffer[index++] = (byte)(0xFF & (absPosition >> 8)); - buffer[index++] = (byte)(0xFF & absPosition); - } - return 3; - } - - /** * Makes the flag value for a PtNode. * * @param hasMultipleChars whether the PtNode has multiple chars. * @param isTerminal whether the PtNode is terminal. * @param childrenAddressSize the size of a children address. - * @param hasShortcuts whether the PtNode has shortcuts. * @param hasBigrams whether the PtNode has bigrams. * @param isNotAWord whether the PtNode is not a word. - * @param isBlackListEntry whether the PtNode is a blacklist entry. + * @param isPossiblyOffensive whether the PtNode is a possibly offensive entry. * @return the flags */ static int makePtNodeFlags(final boolean hasMultipleChars, final boolean isTerminal, - final int childrenAddressSize, final boolean hasShortcuts, final boolean hasBigrams, - final boolean isNotAWord, final boolean isBlackListEntry) { + final int childrenAddressSize, final boolean hasBigrams, + final boolean isNotAWord, final boolean isPossiblyOffensive) { byte flags = 0; if (hasMultipleChars) flags |= FormatSpec.FLAG_HAS_MULTIPLE_CHARS; if (isTerminal) flags |= FormatSpec.FLAG_IS_TERMINAL; @@ -603,19 +535,17 @@ public class BinaryDictEncoderUtils { default: throw new RuntimeException("Node with a strange address"); } - if (hasShortcuts) flags |= FormatSpec.FLAG_HAS_SHORTCUT_TARGETS; if (hasBigrams) flags |= FormatSpec.FLAG_HAS_BIGRAMS; if (isNotAWord) flags |= FormatSpec.FLAG_IS_NOT_A_WORD; - if (isBlackListEntry) flags |= FormatSpec.FLAG_IS_BLACKLISTED; + if (isPossiblyOffensive) flags |= FormatSpec.FLAG_IS_POSSIBLY_OFFENSIVE; return flags; } /* package */ static byte makePtNodeFlags(final PtNode node, final int childrenOffset) { return (byte) makePtNodeFlags(node.mChars.length > 1, node.isTerminal(), getByteSize(childrenOffset), - node.mShortcutTargets != null && !node.mShortcutTargets.isEmpty(), node.mBigrams != null && !node.mBigrams.isEmpty(), - node.mIsNotAWord, node.mIsBlacklistEntry); + node.mIsNotAWord, node.mIsPossiblyOffensive); } /** @@ -628,8 +558,8 @@ public class BinaryDictEncoderUtils { * @param word the second bigram, for debugging purposes * @return the flags */ - /* package */ static final int makeBigramFlags(final boolean more, final int offset, - int bigramFrequency, final int unigramFrequency, final String word) { + /* package */ static int makeBigramFlags(final boolean more, final int offset, + final int bigramFrequency, final int unigramFrequency, final String word) { int bigramFlags = (more ? FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT : 0) + (offset < 0 ? FormatSpec.FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE : 0); switch (getByteSize(offset)) { @@ -645,13 +575,16 @@ public class BinaryDictEncoderUtils { default: throw new RuntimeException("Strange offset size"); } + final int frequency; if (unigramFrequency > bigramFrequency) { MakedictLog.e("Unigram freq is superior to bigram freq for \"" + word + "\". Bigram freq is " + bigramFrequency + ", unigram freq for " + word + " is " + unigramFrequency); - bigramFrequency = unigramFrequency; + frequency = unigramFrequency; + } else { + frequency = bigramFrequency; } - bigramFlags += getBigramFrequencyDiff(unigramFrequency, bigramFrequency) + bigramFlags += getBigramFrequencyDiff(unigramFrequency, frequency) & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY; return bigramFlags; } @@ -694,21 +627,10 @@ public class BinaryDictEncoderUtils { return discretizedFrequency > 0 ? discretizedFrequency : 0; } - /** - * Makes the flag value for a shortcut. - * - * @param more whether there are more attributes after this one. - * @param frequency the frequency of the attribute, 0..15 - * @return the flags - */ - static final int makeShortcutFlags(final boolean more, final int frequency) { - return (more ? FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT : 0) - + (frequency & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY); - } - - /* package */ static final int getChildrenPosition(final PtNode ptNode) { + /* package */ static int getChildrenPosition(final PtNode ptNode, + final HashMap<Integer, Integer> codePointToOneByteCodeMap) { int positionOfChildrenPosField = ptNode.mCachedAddressAfterUpdate - + getNodeHeaderSize(ptNode); + + getNodeHeaderSize(ptNode, codePointToOneByteCodeMap); if (ptNode.isTerminal()) { // A terminal node has the frequency. // If positionOfChildrenPosField is incorrect, we may crash when jumping to the children @@ -725,19 +647,16 @@ public class BinaryDictEncoderUtils { * @param dict the dictionary the node array is a part of (for relative offsets). * @param dictEncoder the dictionary encoder. * @param ptNodeArray the node array to write. + * @param codePointToOneByteCodeMap the map to convert the code points. */ - @SuppressWarnings("unused") /* package */ static void writePlacedPtNodeArray(final FusionDictionary dict, - final DictEncoder dictEncoder, final PtNodeArray ptNodeArray) { + final DictEncoder dictEncoder, final PtNodeArray ptNodeArray, + final HashMap<Integer, Integer> codePointToOneByteCodeMap) { // TODO: Make the code in common with BinaryDictIOUtils#writePtNode dictEncoder.setPosition(ptNodeArray.mCachedAddressAfterUpdate); final int ptNodeCount = ptNodeArray.mData.size(); dictEncoder.writePtNodeCount(ptNodeCount); - final int parentPosition = - (ptNodeArray.mCachedParentAddress == FormatSpec.NO_PARENT_ADDRESS) - ? FormatSpec.NO_PARENT_ADDRESS - : ptNodeArray.mCachedParentAddress + ptNodeArray.mCachedAddressAfterUpdate; for (int i = 0; i < ptNodeCount; ++i) { final PtNode ptNode = ptNodeArray.mData.get(i); if (dictEncoder.getPosition() != ptNode.mCachedAddressAfterUpdate) { @@ -751,7 +670,7 @@ public class BinaryDictEncoderUtils { + FormatSpec.MAX_TERMINAL_FREQUENCY + " : " + ptNode.mProbabilityInfo.toString()); } - dictEncoder.writePtNode(ptNode, dict); + dictEncoder.writePtNode(ptNode, dict, codePointToOneByteCodeMap); } if (dictEncoder.getPosition() != ptNodeArray.mCachedAddressAfterUpdate + ptNodeArray.mCachedSize) { @@ -817,18 +736,26 @@ public class BinaryDictEncoderUtils { * @param destination the stream to write the file header to. * @param dict the dictionary to write. * @param formatOptions file format options. + * @param codePointOccurrenceArray code points ordered by occurrence count. * @return the size of the header. */ /* package */ static int writeDictionaryHeader(final OutputStream destination, - final FusionDictionary dict, final FormatOptions formatOptions) + final FusionDictionary dict, final FormatOptions formatOptions, + final ArrayList<Entry<Integer, Integer>> codePointOccurrenceArray) throws IOException, UnsupportedFormatException { final int version = formatOptions.mVersion; - if (version < FormatSpec.MINIMUM_SUPPORTED_VERSION - || version > FormatSpec.MAXIMUM_SUPPORTED_VERSION) { + if ((version >= FormatSpec.MINIMUM_SUPPORTED_STATIC_VERSION && + version <= FormatSpec.MAXIMUM_SUPPORTED_STATIC_VERSION) || ( + version >= FormatSpec.MINIMUM_SUPPORTED_DYNAMIC_VERSION && + version <= FormatSpec.MAXIMUM_SUPPORTED_DYNAMIC_VERSION)) { + // Dictionary is valid + } else { throw new UnsupportedFormatException("Requested file format version " + version - + ", but this implementation only supports versions " - + FormatSpec.MINIMUM_SUPPORTED_VERSION + " through " - + FormatSpec.MAXIMUM_SUPPORTED_VERSION); + + ", but this implementation only supports static versions " + + FormatSpec.MINIMUM_SUPPORTED_STATIC_VERSION + " through " + + FormatSpec.MAXIMUM_SUPPORTED_STATIC_VERSION + " and dynamic versions " + + FormatSpec.MINIMUM_SUPPORTED_DYNAMIC_VERSION + " through " + + FormatSpec.MAXIMUM_SUPPORTED_DYNAMIC_VERSION); } ByteArrayOutputStream headerBuffer = new ByteArrayOutputStream(256); @@ -856,8 +783,15 @@ public class BinaryDictEncoderUtils { // Write out the options. for (final String key : dict.mOptions.mAttributes.keySet()) { final String value = dict.mOptions.mAttributes.get(key); - CharEncoding.writeString(headerBuffer, key); - CharEncoding.writeString(headerBuffer, value); + CharEncoding.writeString(headerBuffer, key, null); + CharEncoding.writeString(headerBuffer, value, null); + } + // Write out the codePointTable if there is codePointOccurrenceArray. + if (codePointOccurrenceArray != null) { + final String codePointTableString = + encodeCodePointTable(codePointOccurrenceArray); + CharEncoding.writeString(headerBuffer, DictionaryHeader.CODE_POINT_TABLE_KEY, null); + CharEncoding.writeString(headerBuffer, codePointTableString, null); } final int size = headerBuffer.size(); final byte[] bytes = headerBuffer.toByteArray(); @@ -871,4 +805,35 @@ public class BinaryDictEncoderUtils { headerBuffer.close(); return size; } + + static final class CodePointTable { + final HashMap<Integer, Integer> mCodePointToOneByteCodeMap; + final ArrayList<Entry<Integer, Integer>> mCodePointOccurrenceArray; + + // Let code point table empty for version 200 dictionary which used in test + CodePointTable() { + mCodePointToOneByteCodeMap = null; + mCodePointOccurrenceArray = null; + } + + CodePointTable(final HashMap<Integer, Integer> codePointToOneByteCodeMap, + final ArrayList<Entry<Integer, Integer>> codePointOccurrenceArray) { + mCodePointToOneByteCodeMap = codePointToOneByteCodeMap; + mCodePointOccurrenceArray = codePointOccurrenceArray; + } + } + + private static String encodeCodePointTable( + final ArrayList<Entry<Integer, Integer>> codePointOccurrenceArray) { + final StringBuilder codePointTableString = new StringBuilder(); + int currentCodePointTableIndex = FormatSpec.MINIMAL_ONE_BYTE_CHARACTER_VALUE; + for (final Entry<Integer, Integer> entry : codePointOccurrenceArray) { + // Native reads the table as a string + codePointTableString.appendCodePoint(entry.getKey()); + if (FormatSpec.MAXIMAL_ONE_BYTE_CHARACTER_VALUE < ++currentCodePointTableIndex) { + break; + } + } + return codePointTableString.toString(); + } } diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java index 9c3b37387..da1b32a8b 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java @@ -17,7 +17,7 @@ package com.android.inputmethod.latin.makedict; import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.define.DecoderSpecificConstants; import com.android.inputmethod.latin.makedict.DictDecoder.DictionaryBufferFactory; import java.io.File; @@ -43,22 +43,12 @@ public final class BinaryDictIOUtils { */ public static DictDecoder getDictDecoder(final File dictFile, final long offset, final long length, final int bufferType) { - if (dictFile.isDirectory()) { - return new Ver4DictDecoder(dictFile, bufferType); - } else if (dictFile.isFile()) { - return new Ver2DictDecoder(dictFile, offset, length, bufferType); - } - return null; + return new Ver4DictDecoder(dictFile); } public static DictDecoder getDictDecoder(final File dictFile, final long offset, final long length, final DictionaryBufferFactory factory) { - if (dictFile.isDirectory()) { - return new Ver4DictDecoder(dictFile, factory); - } else if (dictFile.isFile()) { - return new Ver2DictDecoder(dictFile, offset, length, factory); - } - return null; + return new Ver4DictDecoder(dictFile); } public static DictDecoder getDictDecoder(final File dictFile, final long offset, @@ -183,7 +173,7 @@ public final class BinaryDictIOUtils { dictDecoder.readHeader(); int wordPos = 0; final int wordLen = word.codePointCount(0, word.length()); - for (int depth = 0; depth < Constants.DICTIONARY_MAX_WORD_LENGTH; ++depth) { + for (int depth = 0; depth < DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH; ++depth) { if (wordPos >= wordLen) return FormatSpec.NOT_VALID_WORD; do { @@ -206,11 +196,7 @@ public final class BinaryDictIOUtils { if (same) { // found the PtNode matches the word. if (wordPos + currentInfo.mCharacters.length == wordLen) { - if (!currentInfo.isTerminal()) { - return FormatSpec.NOT_VALID_WORD; - } else { - return ptNodePos; - } + return currentInfo.isTerminal() ? ptNodePos : FormatSpec.NOT_VALID_WORD; } wordPos += currentInfo.mCharacters.length; if (currentInfo.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS) { diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java deleted file mode 100644 index 5a3eba801..000000000 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java +++ /dev/null @@ -1,78 +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 com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions; -import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions; - -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/CodePointUtils.java b/tests/src/com/android/inputmethod/latin/makedict/CodePointUtils.java deleted file mode 100644 index a270ee774..000000000 --- a/tests/src/com/android/inputmethod/latin/makedict/CodePointUtils.java +++ /dev/null @@ -1,101 +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 java.util.Random; - -// Utility methods related with code points used for tests. -public class CodePointUtils { - private CodePointUtils() { - // This utility class is not publicly instantiable. - } - - public static final int[] LATIN_ALPHABETS_LOWER = { - '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', - 0x00E0 /* LATIN SMALL LETTER A WITH GRAVE */, - 0x00E1 /* LATIN SMALL LETTER A WITH ACUTE */, - 0x00E2 /* LATIN SMALL LETTER A WITH CIRCUMFLEX */, - 0x00E3 /* LATIN SMALL LETTER A WITH TILDE */, - 0x00E4 /* LATIN SMALL LETTER A WITH DIAERESIS */, - 0x00E5 /* LATIN SMALL LETTER A WITH RING ABOVE */, - 0x00E6 /* LATIN SMALL LETTER AE */, - 0x00E7 /* LATIN SMALL LETTER C WITH CEDILLA */, - 0x00E8 /* LATIN SMALL LETTER E WITH GRAVE */, - 0x00E9 /* LATIN SMALL LETTER E WITH ACUTE */, - 0x00EA /* LATIN SMALL LETTER E WITH CIRCUMFLEX */, - 0x00EB /* LATIN SMALL LETTER E WITH DIAERESIS */, - 0x00EC /* LATIN SMALL LETTER I WITH GRAVE */, - 0x00ED /* LATIN SMALL LETTER I WITH ACUTE */, - 0x00EE /* LATIN SMALL LETTER I WITH CIRCUMFLEX */, - 0x00EF /* LATIN SMALL LETTER I WITH DIAERESIS */, - 0x00F0 /* LATIN SMALL LETTER ETH */, - 0x00F1 /* LATIN SMALL LETTER N WITH TILDE */, - 0x00F2 /* LATIN SMALL LETTER O WITH GRAVE */, - 0x00F3 /* LATIN SMALL LETTER O WITH ACUTE */, - 0x00F4 /* LATIN SMALL LETTER O WITH CIRCUMFLEX */, - 0x00F5 /* LATIN SMALL LETTER O WITH TILDE */, - 0x00F6 /* LATIN SMALL LETTER O WITH DIAERESIS */, - 0x00F7 /* LATIN SMALL LETTER O WITH STROKE */, - 0x00F9 /* LATIN SMALL LETTER U WITH GRAVE */, - 0x00FA /* LATIN SMALL LETTER U WITH ACUTE */, - 0x00FB /* LATIN SMALL LETTER U WITH CIRCUMFLEX */, - 0x00FC /* LATIN SMALL LETTER U WITH DIAERESIS */, - 0x00FD /* LATIN SMALL LETTER Y WITH ACUTE */, - 0x00FE /* LATIN SMALL LETTER THORN */, - 0x00FF /* LATIN SMALL LETTER Y WITH DIAERESIS */ - }; - - public static int[] generateCodePointSet(final int codePointSetSize, final Random random) { - final int[] codePointSet = new int[codePointSetSize]; - for (int i = codePointSet.length - 1; i >= 0; ) { - final int r = Math.abs(random.nextInt()); - if (r < 0) continue; - // Don't insert 0~0x20, but insert any other code point. - // Code points are in the range 0~0x10FFFF. - final int candidateCodePoint = 0x20 + r % (Character.MAX_CODE_POINT - 0x20); - // Code points between MIN_ and MAX_SURROGATE are not valid on their own. - if (candidateCodePoint >= Character.MIN_SURROGATE - && candidateCodePoint <= Character.MAX_SURROGATE) continue; - codePointSet[i] = candidateCodePoint; - --i; - } - return codePointSet; - } - - /** - * Generates a random word. - */ - public static String generateWord(final Random random, final int[] codePointSet) { - StringBuilder builder = new StringBuilder(); - // 8 * 4 = 32 chars max, but we do it the following way so as to bias the random toward - // longer words. This should be closer to natural language, and more importantly, it will - // exercise the algorithms in dicttool much more. - final int count = 1 + (Math.abs(random.nextInt()) % 5) - + (Math.abs(random.nextInt()) % 5) - + (Math.abs(random.nextInt()) % 5) - + (Math.abs(random.nextInt()) % 5) - + (Math.abs(random.nextInt()) % 5) - + (Math.abs(random.nextInt()) % 5) - + (Math.abs(random.nextInt()) % 5) - + (Math.abs(random.nextInt()) % 5); - while (builder.length() < count) { - builder.appendCodePoint(codePointSet[Math.abs(random.nextInt()) % codePointSet.length]); - } - return builder.toString(); - } -} diff --git a/tests/src/com/android/inputmethod/latin/makedict/DictEncoder.java b/tests/src/com/android/inputmethod/latin/makedict/DictEncoder.java index 678c5ca6b..10dd00325 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/DictEncoder.java +++ b/tests/src/com/android/inputmethod/latin/makedict/DictEncoder.java @@ -21,6 +21,7 @@ import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions; import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode; import java.io.IOException; +import java.util.HashMap; /** * An interface of binary dictionary encoder. @@ -33,6 +34,6 @@ public interface DictEncoder { public void setPosition(final int position); public int getPosition(); public void writePtNodeCount(final int ptNodeCount); - public void writeForwardLinkAddress(final int forwardLinkAddress); - public void writePtNode(final PtNode ptNode, final FusionDictionary dict); + public void writePtNode(final PtNode ptNode, final FusionDictionary dict, + final HashMap<Integer, Integer> codePointToOneByteCodeMap); } diff --git a/tests/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/tests/src/com/android/inputmethod/latin/makedict/FusionDictionary.java index 4a8c178b5..52060bed2 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/FusionDictionary.java +++ b/tests/src/com/android/inputmethod/latin/makedict/FusionDictionary.java @@ -17,7 +17,7 @@ package com.android.inputmethod.latin.makedict; import com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.define.DecoderSpecificConstants; import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions; import java.util.ArrayList; @@ -82,14 +82,13 @@ public final class FusionDictionary implements Iterable<WordProperty> { public static final class PtNode { private static final int NOT_A_TERMINAL = -1; final int mChars[]; - ArrayList<WeightedString> mShortcutTargets; ArrayList<WeightedString> mBigrams; // null == mProbabilityInfo indicates this is not a terminal. ProbabilityInfo mProbabilityInfo; int mTerminalId; // NOT_A_TERMINAL == mTerminalId indicates this is not a terminal. PtNodeArray mChildren; boolean mIsNotAWord; // Only a shortcut - boolean mIsBlacklistEntry; + boolean mIsPossiblyOffensive; // mCachedSize and mCachedAddressBefore/AfterUpdate are helpers for binary dictionary // generation. Before and After always hold the same value except during dictionary // address compression, where the update process needs to know about both values at the @@ -100,30 +99,27 @@ public final class FusionDictionary implements Iterable<WordProperty> { int mCachedAddressBeforeUpdate; // The address of this PtNode (before update) int mCachedAddressAfterUpdate; // The address of this PtNode (after update) - public PtNode(final int[] chars, final ArrayList<WeightedString> shortcutTargets, - final ArrayList<WeightedString> bigrams, final ProbabilityInfo probabilityInfo, - final boolean isNotAWord, final boolean isBlacklistEntry) { + public PtNode(final int[] chars, final ArrayList<WeightedString> bigrams, + final ProbabilityInfo probabilityInfo, final boolean isNotAWord, + final boolean isPossiblyOffensive) { mChars = chars; mProbabilityInfo = probabilityInfo; mTerminalId = probabilityInfo == null ? NOT_A_TERMINAL : probabilityInfo.mProbability; - mShortcutTargets = shortcutTargets; mBigrams = bigrams; mChildren = null; mIsNotAWord = isNotAWord; - mIsBlacklistEntry = isBlacklistEntry; + mIsPossiblyOffensive = isPossiblyOffensive; } - public PtNode(final int[] chars, final ArrayList<WeightedString> shortcutTargets, - final ArrayList<WeightedString> bigrams, final ProbabilityInfo probabilityInfo, - final boolean isNotAWord, final boolean isBlacklistEntry, - final PtNodeArray children) { + public PtNode(final int[] chars, final ArrayList<WeightedString> bigrams, + final ProbabilityInfo probabilityInfo, final boolean isNotAWord, + final boolean isPossiblyOffensive, final PtNodeArray children) { mChars = chars; mProbabilityInfo = probabilityInfo; - mShortcutTargets = shortcutTargets; mBigrams = bigrams; mChildren = children; mIsNotAWord = isNotAWord; - mIsBlacklistEntry = isBlacklistEntry; + mIsPossiblyOffensive = isPossiblyOffensive; } public void addChild(PtNode n) { @@ -142,27 +138,15 @@ public final class FusionDictionary implements Iterable<WordProperty> { } public int getProbability() { - if (isTerminal()) { - return mProbabilityInfo.mProbability; - } else { - return NOT_A_TERMINAL; - } + return isTerminal() ? mProbabilityInfo.mProbability : NOT_A_TERMINAL; } public boolean getIsNotAWord() { return mIsNotAWord; } - public boolean getIsBlacklistEntry() { - return mIsBlacklistEntry; - } - - public ArrayList<WeightedString> getShortcutTargets() { - // We don't want write permission to escape outside the package, so we return a copy - if (null == mShortcutTargets) return null; - final ArrayList<WeightedString> copyOfShortcutTargets = - new ArrayList<>(mShortcutTargets); - return copyOfShortcutTargets; + public boolean getIsPossiblyOffensive() { + return mIsPossiblyOffensive; } public ArrayList<WeightedString> getBigrams() { @@ -195,24 +179,6 @@ public final class FusionDictionary implements Iterable<WordProperty> { } /** - * Gets the shortcut target for the given word. Returns null if the word is not in the - * shortcut list. - */ - public WeightedString getShortcut(final String word) { - // TODO: Don't do a linear search - if (mShortcutTargets != null) { - final int size = mShortcutTargets.size(); - for (int i = 0; i < size; ++i) { - WeightedString shortcut = mShortcutTargets.get(i); - if (shortcut.mWord.equals(word)) { - return shortcut; - } - } - } - return null; - } - - /** * Gets the bigram for the given word. * Returns null if the word is not in the bigrams list. */ @@ -235,28 +201,10 @@ public final class FusionDictionary implements Iterable<WordProperty> { * the existing ones if any. Note: unigram, bigram, and shortcut frequencies are only * updated if they are higher than the existing ones. */ - private void update(final ProbabilityInfo probabilityInfo, - final ArrayList<WeightedString> shortcutTargets, + void update(final ProbabilityInfo probabilityInfo, final ArrayList<WeightedString> bigrams, - final boolean isNotAWord, final boolean isBlacklistEntry) { + final boolean isNotAWord, final boolean isPossiblyOffensive) { mProbabilityInfo = ProbabilityInfo.max(mProbabilityInfo, probabilityInfo); - if (shortcutTargets != null) { - if (mShortcutTargets == null) { - mShortcutTargets = shortcutTargets; - } else { - final int size = shortcutTargets.size(); - for (int i = 0; i < size; ++i) { - final WeightedString shortcut = shortcutTargets.get(i); - final WeightedString existingShortcut = getShortcut(shortcut.mWord); - if (existingShortcut == null) { - mShortcutTargets.add(shortcut); - } else { - existingShortcut.mProbabilityInfo = ProbabilityInfo.max( - existingShortcut.mProbabilityInfo, shortcut.mProbabilityInfo); - } - } - } - } if (bigrams != null) { if (mBigrams == null) { mBigrams = bigrams; @@ -275,7 +223,7 @@ public final class FusionDictionary implements Iterable<WordProperty> { } } mIsNotAWord = isNotAWord; - mIsBlacklistEntry = isBlacklistEntry; + mIsPossiblyOffensive = isPossiblyOffensive; } } @@ -316,31 +264,16 @@ public final class FusionDictionary implements Iterable<WordProperty> { * Helper method to add a word as a string. * * This method adds a word to the dictionary with the given frequency. Optional - * lists of bigrams and shortcuts can be passed here. For each word inside, + * lists of bigrams can be passed here. For each word inside, * they will be added to the dictionary as necessary. - * - * @param word the word to add. + * @param word the word to add. * @param probabilityInfo probability information of the word. - * @param shortcutTargets a list of shortcut targets for this word, or null. * @param isNotAWord true if this should not be considered a word (e.g. shortcut only) + * @param isPossiblyOffensive true if this word is possibly offensive */ public void add(final String word, final ProbabilityInfo probabilityInfo, - final ArrayList<WeightedString> shortcutTargets, final boolean isNotAWord) { - add(getCodePoints(word), probabilityInfo, shortcutTargets, isNotAWord, - false /* isBlacklistEntry */); - } - - /** - * Helper method to add a blacklist entry as a string. - * - * @param word the word to add as a blacklist entry. - * @param shortcutTargets a list of shortcut targets for this word, or null. - * @param isNotAWord true if this is not a word for spellcheking purposes (shortcut only or so) - */ - public void addBlacklistEntry(final String word, - final ArrayList<WeightedString> shortcutTargets, final boolean isNotAWord) { - add(getCodePoints(word), new ProbabilityInfo(0), shortcutTargets, isNotAWord, - true /* isBlacklistEntry */); + final boolean isNotAWord, final boolean isPossiblyOffensive) { + add(getCodePoints(word), probabilityInfo, isNotAWord, isPossiblyOffensive); } /** @@ -349,15 +282,15 @@ public final class FusionDictionary implements Iterable<WordProperty> { * This method checks that all PtNodes in a node array are ordered as expected. * If they are, nothing happens. If they aren't, an exception is thrown. */ - private void checkStack(PtNodeArray ptNodeArray) { + private static void checkStack(PtNodeArray ptNodeArray) { ArrayList<PtNode> stack = ptNodeArray.mData; int lastValue = -1; for (int i = 0; i < stack.size(); ++i) { int currentValue = stack.get(i).mChars[0]; - if (currentValue <= lastValue) + if (currentValue <= lastValue) { throw new RuntimeException("Invalid stack"); - else - lastValue = currentValue; + } + lastValue = currentValue; } } @@ -374,8 +307,8 @@ public final class FusionDictionary implements Iterable<WordProperty> { if (ptNode0 != null) { final PtNode ptNode1 = findWordInTree(mRootNodeArray, word1); if (ptNode1 == null) { - add(getCodePoints(word1), new ProbabilityInfo(0), null, false /* isNotAWord */, - false /* isBlacklistEntry */); + add(getCodePoints(word1), new ProbabilityInfo(0), false /* isNotAWord */, + false /* isPossiblyOffensive */); // The PtNode for the first word may have moved by the above insertion, // if word1 and word2 share a common stem that happens not to have been // a cutting point until now. In this case, we need to refresh ptNode. @@ -392,18 +325,15 @@ public final class FusionDictionary implements Iterable<WordProperty> { * * The shortcuts, if any, have to be in the dictionary already. If they aren't, * an exception is thrown. - * - * @param word the word, as an int array. + * @param word the word, as an int array. * @param probabilityInfo the probability information of the word. - * @param shortcutTargets an optional list of shortcut targets for this word (null if none). * @param isNotAWord true if this is not a word for spellcheking purposes (shortcut only or so) - * @param isBlacklistEntry true if this is a blacklisted word, false otherwise + * @param isPossiblyOffensive true if this word is possibly offensive */ private void add(final int[] word, final ProbabilityInfo probabilityInfo, - final ArrayList<WeightedString> shortcutTargets, - final boolean isNotAWord, final boolean isBlacklistEntry) { + final boolean isNotAWord, final boolean isPossiblyOffensive) { assert(probabilityInfo.mProbability <= FormatSpec.MAX_TERMINAL_FREQUENCY); - if (word.length >= Constants.DICTIONARY_MAX_WORD_LENGTH) { + if (word.length >= DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH) { MakedictLog.w("Ignoring a word that is too long: word.length = " + word.length); return; } @@ -430,8 +360,8 @@ public final class FusionDictionary implements Iterable<WordProperty> { // No node at this point to accept the word. Create one. final int insertionIndex = findInsertionIndex(currentNodeArray, word[charIndex]); final PtNode newPtNode = new PtNode(Arrays.copyOfRange(word, charIndex, word.length), - shortcutTargets, null /* bigrams */, probabilityInfo, isNotAWord, - isBlacklistEntry); + null /* bigrams */, probabilityInfo, isNotAWord, + isPossiblyOffensive); currentNodeArray.mData.add(insertionIndex, newPtNode); if (DBG) checkStack(currentNodeArray); } else { @@ -441,15 +371,15 @@ public final class FusionDictionary implements Iterable<WordProperty> { // The new word is a prefix of an existing word, but the node on which it // should end already exists as is. Since the old PtNode was not a terminal, // make it one by filling in its frequency and other attributes - currentPtNode.update(probabilityInfo, shortcutTargets, null, isNotAWord, - isBlacklistEntry); + currentPtNode.update(probabilityInfo, null, isNotAWord, + isPossiblyOffensive); } else { // The new word matches the full old word and extends past it. // We only have to create a new node and add it to the end of this. final PtNode newNode = new PtNode( Arrays.copyOfRange(word, charIndex + differentCharIndex, word.length), - shortcutTargets, null /* bigrams */, probabilityInfo, - isNotAWord, isBlacklistEntry); + null /* bigrams */, probabilityInfo, + isNotAWord, isPossiblyOffensive); currentPtNode.mChildren = new PtNodeArray(); currentPtNode.mChildren.mData.add(newNode); } @@ -457,18 +387,18 @@ public final class FusionDictionary implements Iterable<WordProperty> { if (0 == differentCharIndex) { // Exact same word. Update the frequency if higher. This will also add the // new shortcuts to the existing shortcut list if it already exists. - currentPtNode.update(probabilityInfo, shortcutTargets, null, + currentPtNode.update(probabilityInfo, null, currentPtNode.mIsNotAWord && isNotAWord, - currentPtNode.mIsBlacklistEntry || isBlacklistEntry); + currentPtNode.mIsPossiblyOffensive || isPossiblyOffensive); } else { // Partial prefix match only. We have to replace the current node with a node // containing the current prefix and create two new ones for the tails. PtNodeArray newChildren = new PtNodeArray(); final PtNode newOldWord = new PtNode( Arrays.copyOfRange(currentPtNode.mChars, differentCharIndex, - currentPtNode.mChars.length), currentPtNode.mShortcutTargets, + currentPtNode.mChars.length), currentPtNode.mBigrams, currentPtNode.mProbabilityInfo, - currentPtNode.mIsNotAWord, currentPtNode.mIsBlacklistEntry, + currentPtNode.mIsNotAWord, currentPtNode.mIsPossiblyOffensive, currentPtNode.mChildren); newChildren.mData.add(newOldWord); @@ -476,18 +406,18 @@ public final class FusionDictionary implements Iterable<WordProperty> { if (charIndex + differentCharIndex >= word.length) { newParent = new PtNode( Arrays.copyOfRange(currentPtNode.mChars, 0, differentCharIndex), - shortcutTargets, null /* bigrams */, probabilityInfo, - isNotAWord, isBlacklistEntry, newChildren); + null /* bigrams */, probabilityInfo, + isNotAWord, isPossiblyOffensive, newChildren); } else { newParent = new PtNode( Arrays.copyOfRange(currentPtNode.mChars, 0, differentCharIndex), - null /* shortcutTargets */, null /* bigrams */, - null /* probabilityInfo */, false /* isNotAWord */, - false /* isBlacklistEntry */, newChildren); + null /* bigrams */, null /* probabilityInfo */, + false /* isNotAWord */, false /* isPossiblyOffensive */, + newChildren); final PtNode newWord = new PtNode(Arrays.copyOfRange(word, charIndex + differentCharIndex, word.length), - shortcutTargets, null /* bigrams */, probabilityInfo, - isNotAWord, isBlacklistEntry); + null /* bigrams */, probabilityInfo, + isNotAWord, isPossiblyOffensive); final int addIndex = word[charIndex + differentCharIndex] > currentPtNode.mChars[differentCharIndex] ? 1 : 0; newChildren.mData.add(addIndex, newWord); @@ -533,14 +463,14 @@ public final class FusionDictionary implements Iterable<WordProperty> { * is ignored. * This comparator imposes orderings that are inconsistent with equals. */ - static private final class PtNodeComparator implements java.util.Comparator<PtNode> { + static final class PtNodeComparator implements java.util.Comparator<PtNode> { @Override public int compare(PtNode p1, PtNode p2) { if (p1.mChars[0] == p2.mChars[0]) return 0; return p1.mChars[0] < p2.mChars[0] ? -1 : 1; } } - final static private PtNodeComparator PTNODE_COMPARATOR = new PtNodeComparator(); + final static PtNodeComparator PTNODE_COMPARATOR = new PtNodeComparator(); /** * Finds the insertion index of a character within a node array. @@ -548,8 +478,8 @@ public final class FusionDictionary implements Iterable<WordProperty> { private static int findInsertionIndex(final PtNodeArray nodeArray, int character) { final ArrayList<PtNode> data = nodeArray.mData; final PtNode reference = new PtNode(new int[] { character }, - null /* shortcutTargets */, null /* bigrams */, null /* probabilityInfo */, - false /* isNotAWord */, false /* isBlacklistEntry */); + null /* bigrams */, null /* probabilityInfo */, + false /* isNotAWord */, false /* isPossiblyOffensive */); int result = Collections.binarySearch(data, reference, PTNODE_COMPARATOR); return result >= 0 ? result : -result - 1; } @@ -571,7 +501,8 @@ public final class FusionDictionary implements Iterable<WordProperty> { /** * Helper method to find a word in a given branch. */ - public static PtNode findWordInTree(PtNodeArray nodeArray, final String string) { + public static PtNode findWordInTree(final PtNodeArray rootNodeArray, final String string) { + PtNodeArray nodeArray = rootNodeArray; int index = 0; final StringBuilder checker = DBG ? new StringBuilder() : null; final int[] codePoints = getCodePoints(string); @@ -684,9 +615,8 @@ public final class FusionDictionary implements Iterable<WordProperty> { } if (currentPtNode.isTerminal()) { return new WordProperty(mCurrentString.toString(), - currentPtNode.mProbabilityInfo, - currentPtNode.mShortcutTargets, currentPtNode.mBigrams, - currentPtNode.mIsNotAWord, currentPtNode.mIsBlacklistEntry); + currentPtNode.mProbabilityInfo, currentPtNode.mBigrams, + currentPtNode.mIsNotAWord, currentPtNode.mIsPossiblyOffensive); } } else { mPositions.removeLast(); diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java deleted file mode 100644 index 65b84d5f7..000000000 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoder.java +++ /dev/null @@ -1,321 +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 com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.BinaryDictionary; -import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding; -import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; - -/** - * An implementation of DictDecoder for version 2 binary dictionary. - */ -// TODO: Separate logics that are used only for testing. -@UsedForTesting -public class Ver2DictDecoder extends AbstractDictDecoder { - /** - * A utility class for reading a PtNode. - */ - protected static class PtNodeReader { - private static ProbabilityInfo readProbabilityInfo(final DictBuffer dictBuffer) { - // Ver2 dicts don't contain historical information. - return new ProbabilityInfo(dictBuffer.readUnsignedByte()); - } - - protected static int readPtNodeOptionFlags(final DictBuffer dictBuffer) { - return dictBuffer.readUnsignedByte(); - } - - protected static int readChildrenAddress(final DictBuffer dictBuffer, - final int ptNodeFlags) { - switch (ptNodeFlags & FormatSpec.MASK_CHILDREN_ADDRESS_TYPE) { - case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_ONEBYTE: - return dictBuffer.readUnsignedByte(); - case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_TWOBYTES: - return dictBuffer.readUnsignedShort(); - case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_THREEBYTES: - return dictBuffer.readUnsignedInt24(); - case FormatSpec.FLAG_CHILDREN_ADDRESS_TYPE_NOADDRESS: - default: - return FormatSpec.NO_CHILDREN_ADDRESS; - } - } - - // Reads shortcuts and returns the read length. - protected static int readShortcut(final DictBuffer dictBuffer, - final ArrayList<WeightedString> shortcutTargets) { - final int pointerBefore = dictBuffer.position(); - dictBuffer.readUnsignedShort(); // skip the size - while (true) { - final int targetFlags = dictBuffer.readUnsignedByte(); - final String word = CharEncoding.readString(dictBuffer); - shortcutTargets.add(new WeightedString(word, - targetFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY)); - if (0 == (targetFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT)) break; - } - return dictBuffer.position() - pointerBefore; - } - - protected static int readBigramAddresses(final DictBuffer dictBuffer, - final ArrayList<PendingAttribute> bigrams, final int baseAddress) { - int readLength = 0; - int bigramCount = 0; - while (bigramCount++ < FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) { - final int bigramFlags = dictBuffer.readUnsignedByte(); - ++readLength; - final int sign = 0 == (bigramFlags & FormatSpec.FLAG_BIGRAM_ATTR_OFFSET_NEGATIVE) - ? 1 : -1; - int bigramAddress = baseAddress + readLength; - switch (bigramFlags & FormatSpec.MASK_BIGRAM_ATTR_ADDRESS_TYPE) { - case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_ONEBYTE: - bigramAddress += sign * dictBuffer.readUnsignedByte(); - readLength += 1; - break; - case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_TWOBYTES: - bigramAddress += sign * dictBuffer.readUnsignedShort(); - readLength += 2; - break; - case FormatSpec.FLAG_BIGRAM_ATTR_ADDRESS_TYPE_THREEBYTES: - bigramAddress += sign * dictBuffer.readUnsignedInt24(); - readLength += 3; - break; - default: - throw new RuntimeException("Has bigrams with no address"); - } - bigrams.add(new PendingAttribute( - bigramFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_FREQUENCY, - bigramAddress)); - if (0 == (bigramFlags & FormatSpec.FLAG_BIGRAM_SHORTCUT_ATTR_HAS_NEXT)) break; - } - return readLength; - } - } - - protected final File mDictionaryBinaryFile; - protected final long mOffset; - protected final long mLength; - // TODO: Remove mBufferFactory and mDictBuffer from this class members because they are now - // used only for testing. - private final DictionaryBufferFactory mBufferFactory; - protected DictBuffer mDictBuffer; - - @UsedForTesting - /* package */ Ver2DictDecoder(final File file, final long offset, final long length, - final int factoryFlag) { - mDictionaryBinaryFile = file; - mOffset = offset; - mLength = length; - mDictBuffer = null; - if ((factoryFlag & MASK_DICTBUFFER) == USE_READONLY_BYTEBUFFER) { - mBufferFactory = new DictionaryBufferFromReadOnlyByteBufferFactory(); - } else if ((factoryFlag & MASK_DICTBUFFER) == USE_BYTEARRAY) { - mBufferFactory = new DictionaryBufferFromByteArrayFactory(); - } else if ((factoryFlag & MASK_DICTBUFFER) == USE_WRITABLE_BYTEBUFFER) { - mBufferFactory = new DictionaryBufferFromWritableByteBufferFactory(); - } else { - mBufferFactory = new DictionaryBufferFromReadOnlyByteBufferFactory(); - } - } - - /* package */ Ver2DictDecoder(final File file, final long offset, final long length, - final DictionaryBufferFactory factory) { - mDictionaryBinaryFile = file; - mOffset = offset; - mLength = length; - mBufferFactory = factory; - } - - @Override - public void openDictBuffer() throws FileNotFoundException, IOException { - mDictBuffer = mBufferFactory.getDictionaryBuffer(mDictionaryBinaryFile); - } - - @Override - public boolean isDictBufferOpen() { - return mDictBuffer != null; - } - - /* package */ DictBuffer getDictBuffer() { - return mDictBuffer; - } - - @UsedForTesting - /* package */ DictBuffer openAndGetDictBuffer() throws FileNotFoundException, IOException { - openDictBuffer(); - return getDictBuffer(); - } - - @Override - public DictionaryHeader readHeader() throws IOException, UnsupportedFormatException { - // dictType is not being used in dicttool. Passing an empty string. - final BinaryDictionary binaryDictionary = new BinaryDictionary( - mDictionaryBinaryFile.getAbsolutePath(), mOffset, mLength, - true /* useFullEditDistance */, null /* locale */, "" /* dictType */, - false /* isUpdatable */); - final DictionaryHeader header = binaryDictionary.getHeader(); - binaryDictionary.close(); - if (header == null) { - throw new IOException("Cannot read the dictionary header."); - } - if (header.mFormatOptions.mVersion != FormatSpec.VERSION2) { - throw new UnsupportedFormatException("File header has a wrong version : " - + header.mFormatOptions.mVersion); - } - if (!isDictBufferOpen()) { - openDictBuffer(); - } - // Advance buffer reading position to the head of dictionary body. - setPosition(header.mBodyOffset); - return header; - } - - // TODO: Make this buffer multi thread safe. - private final int[] mCharacterBuffer = new int[FormatSpec.MAX_WORD_LENGTH]; - @Override - public PtNodeInfo readPtNode(final int ptNodePos) { - int addressPointer = ptNodePos; - final int flags = PtNodeReader.readPtNodeOptionFlags(mDictBuffer); - addressPointer += FormatSpec.PTNODE_FLAGS_SIZE; - final int characters[]; - if (0 != (flags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS)) { - int index = 0; - int character = CharEncoding.readChar(mDictBuffer); - addressPointer += CharEncoding.getCharSize(character); - while (FormatSpec.INVALID_CHARACTER != character) { - // FusionDictionary is making sure that the length of the word is smaller than - // MAX_WORD_LENGTH. - // So we'll never write past the end of mCharacterBuffer. - mCharacterBuffer[index++] = character; - character = CharEncoding.readChar(mDictBuffer); - addressPointer += CharEncoding.getCharSize(character); - } - characters = Arrays.copyOfRange(mCharacterBuffer, 0, index); - } else { - final int character = CharEncoding.readChar(mDictBuffer); - addressPointer += CharEncoding.getCharSize(character); - characters = new int[] { character }; - } - final ProbabilityInfo probabilityInfo; - if (0 != (FormatSpec.FLAG_IS_TERMINAL & flags)) { - probabilityInfo = PtNodeReader.readProbabilityInfo(mDictBuffer); - addressPointer += FormatSpec.PTNODE_FREQUENCY_SIZE; - } else { - probabilityInfo = null; - } - int childrenAddress = PtNodeReader.readChildrenAddress(mDictBuffer, flags); - if (childrenAddress != FormatSpec.NO_CHILDREN_ADDRESS) { - childrenAddress += addressPointer; - } - addressPointer += BinaryDictIOUtils.getChildrenAddressSize(flags); - final ArrayList<WeightedString> shortcutTargets; - if (0 != (flags & FormatSpec.FLAG_HAS_SHORTCUT_TARGETS)) { - // readShortcut will add shortcuts to shortcutTargets. - shortcutTargets = new ArrayList<>(); - addressPointer += PtNodeReader.readShortcut(mDictBuffer, shortcutTargets); - } else { - shortcutTargets = null; - } - - final ArrayList<PendingAttribute> bigrams; - if (0 != (flags & FormatSpec.FLAG_HAS_BIGRAMS)) { - bigrams = new ArrayList<>(); - addressPointer += PtNodeReader.readBigramAddresses(mDictBuffer, bigrams, - addressPointer); - if (bigrams.size() >= FormatSpec.MAX_BIGRAMS_IN_A_PTNODE) { - throw new RuntimeException("Too many bigrams in a PtNode (" + bigrams.size() - + " but max is " + FormatSpec.MAX_BIGRAMS_IN_A_PTNODE + ")"); - } - } else { - bigrams = null; - } - return new PtNodeInfo(ptNodePos, addressPointer, flags, characters, probabilityInfo, - childrenAddress, shortcutTargets, bigrams); - } - - @Override - public FusionDictionary readDictionaryBinary(final boolean deleteDictIfBroken) - throws FileNotFoundException, IOException, UnsupportedFormatException { - // dictType is not being used in dicttool. Passing an empty string. - final BinaryDictionary binaryDictionary = new BinaryDictionary( - mDictionaryBinaryFile.getAbsolutePath(), 0 /* offset */, - mDictionaryBinaryFile.length() /* length */, true /* useFullEditDistance */, - null /* locale */, "" /* dictType */, false /* isUpdatable */); - final DictionaryHeader header = readHeader(); - final FusionDictionary fusionDict = - new FusionDictionary(new FusionDictionary.PtNodeArray(), header.mDictionaryOptions); - int token = 0; - final ArrayList<WordProperty> wordProperties = new ArrayList<>(); - do { - final BinaryDictionary.GetNextWordPropertyResult result = - binaryDictionary.getNextWordProperty(token); - final WordProperty wordProperty = result.mWordProperty; - if (wordProperty == null) { - binaryDictionary.close(); - if (deleteDictIfBroken) { - mDictionaryBinaryFile.delete(); - } - return null; - } - wordProperties.add(wordProperty); - token = result.mNextToken; - } while (token != 0); - - // Insert unigrams into the fusion dictionary. - for (final WordProperty wordProperty : wordProperties) { - if (wordProperty.mIsBlacklistEntry) { - fusionDict.addBlacklistEntry(wordProperty.mWord, wordProperty.mShortcutTargets, - wordProperty.mIsNotAWord); - } else { - fusionDict.add(wordProperty.mWord, wordProperty.mProbabilityInfo, - wordProperty.mShortcutTargets, wordProperty.mIsNotAWord); - } - } - // Insert bigrams into the fusion dictionary. - for (final WordProperty wordProperty : wordProperties) { - if (wordProperty.mBigrams == null) { - continue; - } - final String word0 = wordProperty.mWord; - for (final WeightedString bigram : wordProperty.mBigrams) { - fusionDict.setBigram(word0, bigram.mWord, bigram.mProbabilityInfo); - } - } - binaryDictionary.close(); - return fusionDict; - } - - @Override - public void setPosition(int newPos) { - mDictBuffer.position(newPos); - } - - @Override - public int getPosition() { - return mDictBuffer.position(); - } - - @Override - public int readPtNodeCount() { - return BinaryDictDecoderUtils.readPtNodeCount(mDictBuffer); - } -} diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java deleted file mode 100644 index 3882c2c55..000000000 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictDecoderTests.java +++ /dev/null @@ -1,150 +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 com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer; -import com.android.inputmethod.latin.makedict.DictDecoder.DictionaryBufferFactory; -import com.android.inputmethod.latin.makedict.DictDecoder.DictionaryBufferFromByteArrayFactory; -import com.android.inputmethod.latin.makedict.DictDecoder. - DictionaryBufferFromReadOnlyByteBufferFactory; -import com.android.inputmethod.latin.makedict.DictDecoder. - DictionaryBufferFromWritableByteBufferFactory; - -import android.test.AndroidTestCase; -import android.util.Log; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; - -/** - * Unit tests for Ver2DictDecoder - */ -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 }; - - // Utilities for testing - public void writeDataToFile(final File file) { - FileOutputStream outStream = null; - try { - outStream = new FileOutputStream(file); - outStream.write(data); - } catch (IOException e) { - fail ("Can't write data to the test file"); - } finally { - if (outStream != null) { - try { - outStream.close(); - } catch (IOException e) { - Log.e(TAG, "Failed to close the output stream", e); - } - } - } - } - - public void runTestOpenBuffer(final String testName, final DictionaryBufferFactory factory) { - File testFile = null; - try { - testFile = File.createTempFile(testName, ".tmp", getContext().getCacheDir()); - } catch (IOException e) { - Log.e(TAG, "IOException while the creating temporary file", e); - } - - assertNotNull(testFile); - final Ver2DictDecoder dictDecoder = new Ver2DictDecoder(testFile, 0, testFile.length(), - factory); - try { - dictDecoder.openDictBuffer(); - } catch (Exception e) { - Log.e(TAG, "Failed to open the buffer", e); - } - - writeDataToFile(testFile); - - try { - dictDecoder.openDictBuffer(); - } catch (Exception e) { - Log.e(TAG, "Raised the exception while opening buffer", e); - } - - assertEquals(testFile.length(), dictDecoder.getDictBuffer().capacity()); - } - - public void testOpenBufferWithByteBuffer() { - runTestOpenBuffer("testOpenBufferWithByteBuffer", - new DictionaryBufferFromReadOnlyByteBufferFactory()); - } - - public void testOpenBufferWithByteArray() { - runTestOpenBuffer("testOpenBufferWithByteArray", - new DictionaryBufferFromByteArrayFactory()); - } - - public void testOpenBufferWithWritableByteBuffer() { - runTestOpenBuffer("testOpenBufferWithWritableByteBuffer", - new DictionaryBufferFromWritableByteBufferFactory()); - } - - public void runTestGetBuffer(final String testName, final DictionaryBufferFactory factory) { - File testFile = null; - try { - testFile = File.createTempFile(testName, ".tmp", getContext().getCacheDir()); - } catch (IOException e) { - Log.e(TAG, "IOException while the creating temporary file", e); - } - - final Ver2DictDecoder dictDecoder = new Ver2DictDecoder(testFile, 0, testFile.length(), - factory); - - // the default return value of getBuffer() must be null. - assertNull("the default return value of getBuffer() is not null", - dictDecoder.getDictBuffer()); - - writeDataToFile(testFile); - assertTrue(testFile.exists()); - Log.d(TAG, "file length = " + testFile.length()); - - DictBuffer dictBuffer = null; - try { - dictBuffer = dictDecoder.openAndGetDictBuffer(); - } catch (IOException e) { - Log.e(TAG, "Failed to open and get the buffer", e); - } - assertNotNull("the buffer must not be null", dictBuffer); - - for (int i = 0; i < data.length; ++i) { - assertEquals(data[i], dictBuffer.readUnsignedByte()); - } - } - - public void testGetBufferWithByteBuffer() { - runTestGetBuffer("testGetBufferWithByteBuffer", - new DictionaryBufferFromReadOnlyByteBufferFactory()); - } - - public void testGetBufferWithByteArray() { - runTestGetBuffer("testGetBufferWithByteArray", - new DictionaryBufferFromByteArrayFactory()); - } - - public void testGetBufferWithWritableByteBuffer() { - runTestGetBuffer("testGetBufferWithWritableByteBuffer", - new DictionaryBufferFromWritableByteBufferFactory()); - } -} diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java b/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java deleted file mode 100644 index a286190cb..000000000 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver2DictEncoder.java +++ /dev/null @@ -1,240 +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 com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncoding; -import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions; -import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode; -import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Iterator; - -/** - * An implementation of DictEncoder for version 2 binary dictionary. - */ -@UsedForTesting -public class Ver2DictEncoder implements DictEncoder { - - private final File mDictFile; - private OutputStream mOutStream; - private byte[] mBuffer; - private int mPosition; - - @UsedForTesting - public Ver2DictEncoder(final File dictFile) { - mDictFile = dictFile; - mOutStream = null; - mBuffer = null; - } - - // This constructor is used only by BinaryDictOffdeviceUtilsTests. - // If you want to use this in the production code, you should consider keeping consistency of - // the interface of Ver3DictDecoder by using factory. - @UsedForTesting - public Ver2DictEncoder(final OutputStream outStream) { - mDictFile = null; - mOutStream = outStream; - } - - private void openStream() throws FileNotFoundException { - mOutStream = new FileOutputStream(mDictFile); - } - - private void close() throws IOException { - if (mOutStream != null) { - mOutStream.close(); - mOutStream = null; - } - } - - @Override - public void writeDictionary(final FusionDictionary dict, final FormatOptions formatOptions) - throws IOException, UnsupportedFormatException { - if (formatOptions.mVersion > FormatSpec.VERSION2) { - throw new UnsupportedFormatException( - "The given format options has wrong version number : " - + formatOptions.mVersion); - } - - if (mOutStream == null) { - openStream(); - } - BinaryDictEncoderUtils.writeDictionaryHeader(mOutStream, dict, formatOptions); - - // Addresses are limited to 3 bytes, but since addresses can be relative to each node - // array, the structure itself is not limited to 16MB. However, if it is over 16MB deciding - // the order of the PtNode arrays becomes a quite complicated problem, because though the - // dictionary itself does not have a size limit, each node array must still be within 16MB - // of all its children and parents. As long as this is ensured, the dictionary file may - // grow to any size. - - // Leave the choice of the optimal node order to the flattenTree function. - MakedictLog.i("Flattening the tree..."); - ArrayList<PtNodeArray> flatNodes = BinaryDictEncoderUtils.flattenTree(dict.mRootNodeArray); - - MakedictLog.i("Computing addresses..."); - BinaryDictEncoderUtils.computeAddresses(dict, flatNodes); - MakedictLog.i("Checking PtNode array..."); - if (MakedictLog.DBG) BinaryDictEncoderUtils.checkFlatPtNodeArrayList(flatNodes); - - // Create a buffer that matches the final dictionary size. - final PtNodeArray lastNodeArray = flatNodes.get(flatNodes.size() - 1); - final int bufferSize = lastNodeArray.mCachedAddressAfterUpdate + lastNodeArray.mCachedSize; - mBuffer = new byte[bufferSize]; - - MakedictLog.i("Writing file..."); - - for (PtNodeArray nodeArray : flatNodes) { - BinaryDictEncoderUtils.writePlacedPtNodeArray(dict, this, nodeArray); - } - if (MakedictLog.DBG) BinaryDictEncoderUtils.showStatistics(flatNodes); - mOutStream.write(mBuffer, 0, mPosition); - - MakedictLog.i("Done"); - close(); - } - - @Override - public void setPosition(final int position) { - if (mBuffer == null || position < 0 || position >= mBuffer.length) return; - mPosition = position; - } - - @Override - public int getPosition() { - return mPosition; - } - - @Override - public void writePtNodeCount(final int ptNodeCount) { - final int countSize = BinaryDictIOUtils.getPtNodeCountSize(ptNodeCount); - if (countSize != 1 && countSize != 2) { - throw new RuntimeException("Strange size from getGroupCountSize : " + countSize); - } - final int encodedPtNodeCount = (countSize == 2) ? - (ptNodeCount | FormatSpec.LARGE_PTNODE_ARRAY_SIZE_FIELD_SIZE_FLAG) : ptNodeCount; - mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, encodedPtNodeCount, - countSize); - } - - private void writePtNodeFlags(final PtNode ptNode) { - final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode); - mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, - BinaryDictEncoderUtils.makePtNodeFlags(ptNode, childrenPos), - FormatSpec.PTNODE_FLAGS_SIZE); - } - - private void writeCharacters(final int[] codePoints, final boolean hasSeveralChars) { - mPosition = CharEncoding.writeCharArray(codePoints, mBuffer, mPosition); - if (hasSeveralChars) { - mBuffer[mPosition++] = FormatSpec.PTNODE_CHARACTERS_TERMINATOR; - } - } - - private void writeFrequency(final int frequency) { - if (frequency >= 0) { - mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, frequency, - FormatSpec.PTNODE_FREQUENCY_SIZE); - } - } - - private void writeChildrenPosition(final PtNode ptNode) { - final int childrenPos = BinaryDictEncoderUtils.getChildrenPosition(ptNode); - mPosition += BinaryDictEncoderUtils.writeChildrenPosition(mBuffer, mPosition, - childrenPos); - } - - /** - * Write a shortcut attributes list to mBuffer. - * - * @param shortcuts the shortcut attributes list. - */ - private void writeShortcuts(final ArrayList<WeightedString> shortcuts) { - if (null == shortcuts || shortcuts.isEmpty()) return; - - final int indexOfShortcutByteSize = mPosition; - mPosition += FormatSpec.PTNODE_SHORTCUT_LIST_SIZE_SIZE; - final Iterator<WeightedString> shortcutIterator = shortcuts.iterator(); - while (shortcutIterator.hasNext()) { - final WeightedString target = shortcutIterator.next(); - final int shortcutFlags = BinaryDictEncoderUtils.makeShortcutFlags( - shortcutIterator.hasNext(), - target.getProbability()); - mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, shortcutFlags, - FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE); - final int shortcutShift = CharEncoding.writeString(mBuffer, mPosition, target.mWord); - mPosition += shortcutShift; - } - final int shortcutByteSize = mPosition - indexOfShortcutByteSize; - if (shortcutByteSize > FormatSpec.MAX_SHORTCUT_LIST_SIZE_IN_A_PTNODE) { - throw new RuntimeException("Shortcut list too large"); - } - BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, indexOfShortcutByteSize, shortcutByteSize, - FormatSpec.PTNODE_SHORTCUT_LIST_SIZE_SIZE); - } - - /** - * Write a bigram attributes list to mBuffer. - * - * @param bigrams the bigram attributes list. - * @param dict the dictionary the node array is a part of (for relative offsets). - */ - private void writeBigrams(final ArrayList<WeightedString> bigrams, - final FusionDictionary dict) { - if (bigrams == null) return; - - final Iterator<WeightedString> bigramIterator = bigrams.iterator(); - while (bigramIterator.hasNext()) { - final WeightedString bigram = bigramIterator.next(); - final PtNode target = - FusionDictionary.findWordInTree(dict.mRootNodeArray, bigram.mWord); - final int addressOfBigram = target.mCachedAddressAfterUpdate; - final int unigramFrequencyForThisWord = target.getProbability(); - final int offset = addressOfBigram - - (mPosition + FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE); - final int bigramFlags = BinaryDictEncoderUtils.makeBigramFlags(bigramIterator.hasNext(), - offset, bigram.getProbability(), unigramFrequencyForThisWord, bigram.mWord); - mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, bigramFlags, - FormatSpec.PTNODE_ATTRIBUTE_FLAGS_SIZE); - mPosition += BinaryDictEncoderUtils.writeChildrenPosition(mBuffer, mPosition, - Math.abs(offset)); - } - } - - @Override - public void writeForwardLinkAddress(final int forwardLinkAddress) { - mPosition = BinaryDictEncoderUtils.writeUIntToBuffer(mBuffer, mPosition, forwardLinkAddress, - FormatSpec.FORWARD_LINK_ADDRESS_SIZE); - } - - @Override - public void writePtNode(final PtNode ptNode, final FusionDictionary dict) { - writePtNodeFlags(ptNode); - writeCharacters(ptNode.mChars, ptNode.hasSeveralChars()); - writeFrequency(ptNode.getProbability()); - writeChildrenPosition(ptNode); - writeShortcuts(ptNode.mShortcutTargets); - writeBigrams(ptNode.mBigrams, dict); - } -} diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java b/tests/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java index 5e8417ed6..746431dfa 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java +++ b/tests/src/com/android/inputmethod/latin/makedict/Ver4DictDecoder.java @@ -18,7 +18,7 @@ package com.android.inputmethod.latin.makedict; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.BinaryDictionary; -import com.android.inputmethod.latin.utils.FileUtils; +import com.android.inputmethod.latin.common.FileUtils; import java.io.File; import java.io.FileNotFoundException; @@ -33,12 +33,7 @@ public class Ver4DictDecoder extends AbstractDictDecoder { final File mDictDirectory; @UsedForTesting - /* package */ Ver4DictDecoder(final File dictDirectory, final int factoryFlag) { - this(dictDirectory, null /* factory */); - } - - @UsedForTesting - /* package */ Ver4DictDecoder(final File dictDirectory, final DictionaryBufferFactory factory) { + /* package */ Ver4DictDecoder(final File dictDirectory) { mDictDirectory = dictDirectory; } @@ -88,21 +83,18 @@ public class Ver4DictDecoder extends AbstractDictDecoder { // Insert unigrams into the fusion dictionary. for (final WordProperty wordProperty : wordProperties) { - if (wordProperty.mIsBlacklistEntry) { - fusionDict.addBlacklistEntry(wordProperty.mWord, wordProperty.mShortcutTargets, - wordProperty.mIsNotAWord); - } else { - fusionDict.add(wordProperty.mWord, wordProperty.mProbabilityInfo, - wordProperty.mShortcutTargets, wordProperty.mIsNotAWord); - } + fusionDict.add(wordProperty.mWord, wordProperty.mProbabilityInfo, + wordProperty.mIsNotAWord, + wordProperty.mIsPossiblyOffensive); } // Insert bigrams into the fusion dictionary. + // TODO: Support ngrams. for (final WordProperty wordProperty : wordProperties) { - if (wordProperty.mBigrams == null) { + if (!wordProperty.mHasNgrams) { continue; } final String word0 = wordProperty.mWord; - for (final WeightedString bigram : wordProperty.mBigrams) { + for (final WeightedString bigram : wordProperty.getBigrams()) { fusionDict.setBigram(word0, bigram.mWord, bigram.mProbabilityInfo); } } diff --git a/tests/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java b/tests/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java deleted file mode 100644 index 76eaef431..000000000 --- a/tests/src/com/android/inputmethod/latin/makedict/Ver4DictEncoder.java +++ /dev/null @@ -1,150 +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 com.android.inputmethod.annotations.UsedForTesting; -import com.android.inputmethod.latin.BinaryDictionary; -import com.android.inputmethod.latin.Dictionary; -import com.android.inputmethod.latin.PrevWordsInfo; -import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions; -import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode; -import com.android.inputmethod.latin.utils.BinaryDictionaryUtils; -import com.android.inputmethod.latin.utils.LocaleUtils; - -import java.io.File; -import java.io.IOException; - -/** - * An implementation of DictEncoder for version 4 binary dictionary. - */ -@UsedForTesting -public class Ver4DictEncoder implements DictEncoder { - private final File mDictPlacedDir; - - @UsedForTesting - public Ver4DictEncoder(final File dictPlacedDir) { - mDictPlacedDir = dictPlacedDir; - } - - // TODO: This builds a FusionDictionary first and iterates it to add words to the binary - // dictionary. However, it is possible to just add words directly to the binary dictionary - // instead. - // In the long run, when we stop supporting version 2, FusionDictionary will become deprecated - // and we can remove it. Then we'll be able to just call BinaryDictionary directly. - @Override - public void writeDictionary(FusionDictionary dict, FormatOptions formatOptions) - throws IOException, UnsupportedFormatException { - if (formatOptions.mVersion != FormatSpec.VERSION4) { - throw new UnsupportedFormatException("File header has a wrong version number : " - + formatOptions.mVersion); - } - if (!mDictPlacedDir.isDirectory()) { - throw new UnsupportedFormatException("Given path is not a directory."); - } - if (!BinaryDictionaryUtils.createEmptyDictFile(mDictPlacedDir.getAbsolutePath(), - FormatSpec.VERSION4, LocaleUtils.constructLocaleFromString( - dict.mOptions.mAttributes.get(DictionaryHeader.DICTIONARY_LOCALE_KEY)), - dict.mOptions.mAttributes)) { - throw new IOException("Cannot create dictionary file : " - + mDictPlacedDir.getAbsolutePath()); - } - final BinaryDictionary binaryDict = new BinaryDictionary(mDictPlacedDir.getAbsolutePath(), - 0l, mDictPlacedDir.length(), true /* useFullEditDistance */, - LocaleUtils.constructLocaleFromString(dict.mOptions.mAttributes.get( - DictionaryHeader.DICTIONARY_LOCALE_KEY)), - Dictionary.TYPE_USER /* Dictionary type. Does not matter for us */, - true /* isUpdatable */); - if (!binaryDict.isValidDictionary()) { - // Somehow createEmptyDictFile returned true, but the file was not created correctly - throw new IOException("Cannot create dictionary file"); - } - for (final WordProperty wordProperty : dict) { - // TODO: switch to addMultipleDictionaryEntries when they support shortcuts - if (null == wordProperty.mShortcutTargets || wordProperty.mShortcutTargets.isEmpty()) { - if (!binaryDict.addUnigramEntry(wordProperty.mWord, wordProperty.getProbability(), - null /* shortcutTarget */, 0 /* shortcutProbability */, - wordProperty.mIsBeginningOfSentence, wordProperty.mIsNotAWord, - wordProperty.mIsBlacklistEntry, 0 /* timestamp */)) { - MakedictLog.e("Cannot add unigram entry for " + wordProperty.mWord); - } - } else { - for (final WeightedString shortcutTarget : wordProperty.mShortcutTargets) { - if (!binaryDict.addUnigramEntry(wordProperty.mWord, - wordProperty.getProbability(), - shortcutTarget.mWord, shortcutTarget.getProbability(), - wordProperty.mIsBeginningOfSentence, wordProperty.mIsNotAWord, - wordProperty.mIsBlacklistEntry, 0 /* timestamp */)) { - MakedictLog.e("Cannot add unigram entry for " + wordProperty.mWord - + ", shortcutTarget: " + shortcutTarget.mWord); - return; - } - } - } - if (binaryDict.needsToRunGC(true /* mindsBlockByGC */)) { - if (!binaryDict.flushWithGC()) { - MakedictLog.e("Cannot flush dict with GC."); - return; - } - } - } - for (final WordProperty word0Property : dict) { - if (null == word0Property.mBigrams) continue; - for (final WeightedString word1 : word0Property.mBigrams) { - final PrevWordsInfo prevWordsInfo = - new PrevWordsInfo(new PrevWordsInfo.WordInfo(word0Property.mWord)); - if (!binaryDict.addNgramEntry(prevWordsInfo, word1.mWord, - word1.getProbability(), 0 /* timestamp */)) { - MakedictLog.e("Cannot add n-gram entry for " - + prevWordsInfo + " -> " + word1.mWord); - return; - } - if (binaryDict.needsToRunGC(true /* mindsBlockByGC */)) { - if (!binaryDict.flushWithGC()) { - MakedictLog.e("Cannot flush dict with GC."); - return; - } - } - } - } - if (!binaryDict.flushWithGC()) { - MakedictLog.e("Cannot flush dict with GC."); - return; - } - binaryDict.close(); - } - - @Override - public void setPosition(int position) { - } - - @Override - public int getPosition() { - return 0; - } - - @Override - public void writePtNodeCount(int ptNodeCount) { - } - - @Override - public void writeForwardLinkAddress(int forwardLinkAddress) { - } - - @Override - public void writePtNode(PtNode ptNode, FusionDictionary dict) { - } -} diff --git a/tests/src/com/android/inputmethod/latin/network/BlockingHttpClientTests.java b/tests/src/com/android/inputmethod/latin/network/BlockingHttpClientTests.java new file mode 100644 index 000000000..8f24cdb44 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/network/BlockingHttpClientTests.java @@ -0,0 +1,168 @@ +/* + * 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.network; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.inputmethod.latin.network.BlockingHttpClient.ResponseProcessor; + +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.util.Arrays; +import java.util.Random; + +/** + * Tests for {@link BlockingHttpClient}. + */ +@SmallTest +public class BlockingHttpClientTests extends AndroidTestCase { + @Mock HttpURLConnection mMockHttpConnection; + + @Override + protected void setUp() throws Exception { + super.setUp(); + MockitoAnnotations.initMocks(this); + } + + public void testError_badGateway() throws IOException, AuthException { + when(mMockHttpConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_BAD_GATEWAY); + final BlockingHttpClient client = new BlockingHttpClient(mMockHttpConnection); + final FakeErrorResponseProcessor processor = new FakeErrorResponseProcessor(); + + try { + client.execute(null /* empty request */, processor); + fail("Expecting an HttpException"); + } catch (HttpException e) { + // expected HttpException + assertEquals(HttpURLConnection.HTTP_BAD_GATEWAY, e.getHttpStatusCode()); + } + } + + public void testError_clientTimeout() throws Exception { + when(mMockHttpConnection.getResponseCode()).thenReturn( + HttpURLConnection.HTTP_CLIENT_TIMEOUT); + final BlockingHttpClient client = new BlockingHttpClient(mMockHttpConnection); + final FakeErrorResponseProcessor processor = new FakeErrorResponseProcessor(); + + try { + client.execute(null /* empty request */, processor); + fail("Expecting an HttpException"); + } catch (HttpException e) { + // expected HttpException + assertEquals(HttpURLConnection.HTTP_CLIENT_TIMEOUT, e.getHttpStatusCode()); + } + } + + public void testError_forbiddenWithRequest() throws Exception { + final OutputStream mockOutputStream = Mockito.mock(OutputStream.class); + when(mMockHttpConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_FORBIDDEN); + when(mMockHttpConnection.getOutputStream()).thenReturn(mockOutputStream); + final BlockingHttpClient client = new BlockingHttpClient(mMockHttpConnection); + final FakeErrorResponseProcessor processor = new FakeErrorResponseProcessor(); + + try { + client.execute(new byte[100], processor); + fail("Expecting an HttpException"); + } catch (HttpException e) { + assertEquals(HttpURLConnection.HTTP_FORBIDDEN, e.getHttpStatusCode()); + } + verify(mockOutputStream).write(any(byte[].class), eq(0), eq(100)); + } + + public void testSuccess_emptyRequest() throws Exception { + final Random rand = new Random(); + byte[] response = new byte[100]; + rand.nextBytes(response); + when(mMockHttpConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK); + when(mMockHttpConnection.getInputStream()).thenReturn(new ByteArrayInputStream(response)); + final BlockingHttpClient client = new BlockingHttpClient(mMockHttpConnection); + final FakeSuccessResponseProcessor processor = + new FakeSuccessResponseProcessor(response); + + client.execute(null /* empty request */, processor); + assertTrue("ResponseProcessor was not invoked", processor.mInvoked); + } + + public void testSuccess() throws Exception { + final OutputStream mockOutputStream = Mockito.mock(OutputStream.class); + final Random rand = new Random(); + byte[] response = new byte[100]; + rand.nextBytes(response); + when(mMockHttpConnection.getOutputStream()).thenReturn(mockOutputStream); + when(mMockHttpConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK); + when(mMockHttpConnection.getInputStream()).thenReturn(new ByteArrayInputStream(response)); + final BlockingHttpClient client = new BlockingHttpClient(mMockHttpConnection); + final FakeSuccessResponseProcessor processor = + new FakeSuccessResponseProcessor(response); + + client.execute(new byte[100], processor); + assertTrue("ResponseProcessor was not invoked", processor.mInvoked); + } + + static class FakeErrorResponseProcessor implements ResponseProcessor<Void> { + @Override + public Void onSuccess(InputStream response) { + fail("Expected an error but received success"); + return null; + } + } + + private static class FakeSuccessResponseProcessor implements ResponseProcessor<Void> { + private final byte[] mExpectedResponse; + + boolean mInvoked; + + FakeSuccessResponseProcessor(byte[] expectedResponse) { + mExpectedResponse = expectedResponse; + } + + @Override + public Void onSuccess(InputStream response) { + try { + mInvoked = true; + BufferedInputStream in = new BufferedInputStream(response); + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + int read = 0; + while ((read = in.read()) != -1) { + buffer.write(read); + } + byte[] actualResponse = buffer.toByteArray(); + in.close(); + assertTrue("Response doesn't match", + Arrays.equals(mExpectedResponse, actualResponse)); + } catch (IOException ex) { + fail("IOException in onSuccess"); + } + return null; + } + } +} diff --git a/tests/src/com/android/inputmethod/latin/network/HttpUrlConnectionBuilderTests.java b/tests/src/com/android/inputmethod/latin/network/HttpUrlConnectionBuilderTests.java new file mode 100644 index 000000000..5b3e78eaf --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/network/HttpUrlConnectionBuilderTests.java @@ -0,0 +1,154 @@ +/* + * 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.network; + +import static com.android.inputmethod.latin.network.HttpUrlConnectionBuilder.MODE_BI_DIRECTIONAL; +import static com.android.inputmethod.latin.network.HttpUrlConnectionBuilder.MODE_DOWNLOAD_ONLY; +import static com.android.inputmethod.latin.network.HttpUrlConnectionBuilder.MODE_UPLOAD_ONLY; + +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; + + +/** + * Tests for {@link HttpUrlConnectionBuilder}. + */ +@SmallTest +public class HttpUrlConnectionBuilderTests extends AndroidTestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + public void testSetUrl_malformed() { + HttpUrlConnectionBuilder builder = new HttpUrlConnectionBuilder(); + try { + builder.setUrl("dadasd!@%@!:11"); + fail("Expected a MalformedURLException."); + } catch (MalformedURLException e) { + // Expected + } + } + + public void testSetConnectTimeout_invalid() { + HttpUrlConnectionBuilder builder = new HttpUrlConnectionBuilder(); + try { + builder.setConnectTimeout(-1); + fail("Expected an IllegalArgumentException."); + } catch (IllegalArgumentException e) { + // Expected + } + } + + public void testSetConnectTimeout() throws IOException { + HttpUrlConnectionBuilder builder = new HttpUrlConnectionBuilder(); + builder.setUrl("https://www.example.com"); + builder.setConnectTimeout(8765); + HttpURLConnection connection = builder.build(); + assertEquals(8765, connection.getConnectTimeout()); + } + + public void testSetReadTimeout_invalid() { + HttpUrlConnectionBuilder builder = new HttpUrlConnectionBuilder(); + try { + builder.setReadTimeout(-1); + fail("Expected an IllegalArgumentException."); + } catch (IllegalArgumentException e) { + // Expected + } + } + + public void testSetReadTimeout() throws IOException { + HttpUrlConnectionBuilder builder = new HttpUrlConnectionBuilder(); + builder.setUrl("https://www.example.com"); + builder.setReadTimeout(8765); + HttpURLConnection connection = builder.build(); + assertEquals(8765, connection.getReadTimeout()); + } + + public void testAddHeader() throws IOException { + HttpUrlConnectionBuilder builder = new HttpUrlConnectionBuilder(); + builder.setUrl("http://www.example.com"); + builder.addHeader("some-random-key", "some-random-value"); + HttpURLConnection connection = builder.build(); + assertEquals("some-random-value", connection.getRequestProperty("some-random-key")); + } + + public void testSetUseCache_notSet() throws IOException { + HttpUrlConnectionBuilder builder = new HttpUrlConnectionBuilder(); + builder.setUrl("http://www.example.com"); + HttpURLConnection connection = builder.build(); + assertFalse(connection.getUseCaches()); + } + + public void testSetUseCache_false() throws IOException { + HttpUrlConnectionBuilder builder = new HttpUrlConnectionBuilder(); + builder.setUrl("http://www.example.com"); + HttpURLConnection connection = builder.build(); + connection.setUseCaches(false); + assertFalse(connection.getUseCaches()); + } + + public void testSetUseCache_true() throws IOException { + HttpUrlConnectionBuilder builder = new HttpUrlConnectionBuilder(); + builder.setUrl("http://www.example.com"); + HttpURLConnection connection = builder.build(); + connection.setUseCaches(true); + assertTrue(connection.getUseCaches()); + } + + public void testSetMode_uploadOnly() throws IOException { + HttpUrlConnectionBuilder builder = new HttpUrlConnectionBuilder(); + builder.setUrl("http://www.example.com"); + builder.setMode(MODE_UPLOAD_ONLY); + HttpURLConnection connection = builder.build(); + assertTrue(connection.getDoInput()); + assertFalse(connection.getDoOutput()); + } + + public void testSetMode_downloadOnly() throws IOException { + HttpUrlConnectionBuilder builder = new HttpUrlConnectionBuilder(); + builder.setUrl("https://www.example.com"); + builder.setMode(MODE_DOWNLOAD_ONLY); + HttpURLConnection connection = builder.build(); + assertFalse(connection.getDoInput()); + assertTrue(connection.getDoOutput()); + } + + public void testSetMode_bidirectional() throws IOException { + HttpUrlConnectionBuilder builder = new HttpUrlConnectionBuilder(); + builder.setUrl("https://www.example.com"); + builder.setMode(MODE_BI_DIRECTIONAL); + HttpURLConnection connection = builder.build(); + assertTrue(connection.getDoInput()); + assertTrue(connection.getDoOutput()); + } + + public void testSetAuthToken() throws IOException { + HttpUrlConnectionBuilder builder = new HttpUrlConnectionBuilder(); + builder.setUrl("https://www.example.com"); + builder.setAuthToken("some-random-auth-token"); + HttpURLConnection connection = builder.build(); + assertEquals("some-random-auth-token", + connection.getRequestProperty(HttpUrlConnectionBuilder.HTTP_HEADER_AUTHORIZATION)); + } +} diff --git a/tests/src/com/android/inputmethod/latin/personalization/ContextualDictionaryTests.java b/tests/src/com/android/inputmethod/latin/personalization/ContextualDictionaryTests.java deleted file mode 100644 index 565fadb2a..000000000 --- a/tests/src/com/android/inputmethod/latin/personalization/ContextualDictionaryTests.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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.personalization; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -import com.android.inputmethod.latin.Dictionary; -import com.android.inputmethod.latin.DictionaryFacilitator; -import com.android.inputmethod.latin.ExpandableBinaryDictionary; - -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; - -/** - * Unit tests for contextual dictionary - */ -@LargeTest -public class ContextualDictionaryTests extends AndroidTestCase { - private static final String TAG = ContextualDictionaryTests.class.getSimpleName(); - - private static final Locale LOCALE_EN_US = new Locale("en", "US"); - - private DictionaryFacilitator getDictionaryFacilitator() { - final ArrayList<String> dictTypes = new ArrayList<>(); - dictTypes.add(Dictionary.TYPE_CONTEXTUAL); - final DictionaryFacilitator dictionaryFacilitator = new DictionaryFacilitator(); - dictionaryFacilitator.resetDictionariesForTesting(getContext(), LOCALE_EN_US, dictTypes, - new HashMap<String, File>(), new HashMap<String, Map<String, String>>()); - return dictionaryFacilitator; - } - - public void testAddPhrase() { - final DictionaryFacilitator dictionaryFacilitator = getDictionaryFacilitator(); - final String[] phrase = new String[] {"a", "b", "c", "d"}; - final int probability = 100; - final int bigramProbabilityForWords = 150; - final int bigramProbabilityForPhrases = 200; - dictionaryFacilitator.addPhraseToContextualDictionary( - phrase, probability, bigramProbabilityForWords, bigramProbabilityForPhrases); - final ExpandableBinaryDictionary contextualDictionary = - dictionaryFacilitator.getSubDictForTesting(Dictionary.TYPE_CONTEXTUAL); - contextualDictionary.waitAllTasksForTests(); - // Word - assertTrue(contextualDictionary.isInDictionary("a")); - assertTrue(contextualDictionary.isInDictionary("b")); - assertTrue(contextualDictionary.isInDictionary("c")); - assertTrue(contextualDictionary.isInDictionary("d")); - // Phrase - assertTrue(contextualDictionary.isInDictionary("a b c d")); - assertTrue(contextualDictionary.isInDictionary("b c d")); - assertTrue(contextualDictionary.isInDictionary("c d")); - assertFalse(contextualDictionary.isInDictionary("a b c")); - assertFalse(contextualDictionary.isInDictionary("abcd")); - // TODO: Add tests for probability. - // TODO: Add tests for n-grams. - } -} diff --git a/tests/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryTests.java b/tests/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryTests.java deleted file mode 100644 index 0f2f9814b..000000000 --- a/tests/src/com/android/inputmethod/latin/personalization/PersonalizationDictionaryTests.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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.personalization; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import com.android.inputmethod.latin.BinaryDictionary; -import com.android.inputmethod.latin.Dictionary; -import com.android.inputmethod.latin.DictionaryFacilitator; -import com.android.inputmethod.latin.ExpandableBinaryDictionary; -import com.android.inputmethod.latin.ExpandableBinaryDictionary.AddMultipleDictionaryEntriesCallback; -import com.android.inputmethod.latin.makedict.CodePointUtils; -import com.android.inputmethod.latin.settings.SpacingAndPunctuations; - -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; -import android.util.Log; - -/** - * Unit tests for personalization dictionary - */ -@LargeTest -public class PersonalizationDictionaryTests extends AndroidTestCase { - private static final String TAG = PersonalizationDictionaryTests.class.getSimpleName(); - - private static final Locale LOCALE_EN_US = new Locale("en", "US"); - private static final String DUMMY_PACKAGE_NAME = "test.package.name"; - private static final long TIMEOUT_TO_WAIT_DICTIONARY_OPERATIONS_IN_SECONDS = 120; - - private DictionaryFacilitator getDictionaryFacilitator() { - final ArrayList<String> dictTypes = new ArrayList<>(); - dictTypes.add(Dictionary.TYPE_MAIN); - dictTypes.add(Dictionary.TYPE_PERSONALIZATION); - final DictionaryFacilitator dictionaryFacilitator = new DictionaryFacilitator(); - dictionaryFacilitator.resetDictionariesForTesting(getContext(), LOCALE_EN_US, dictTypes, - new HashMap<String, File>(), new HashMap<String, Map<String, String>>()); - return dictionaryFacilitator; - } - - public void testAddManyTokens() { - final DictionaryFacilitator dictionaryFacilitator = getDictionaryFacilitator(); - dictionaryFacilitator.clearPersonalizationDictionary(); - final int dataChunkCount = 20; - final int wordCountInOneChunk = 2000; - final Random random = new Random(System.currentTimeMillis()); - final int[] codePointSet = CodePointUtils.LATIN_ALPHABETS_LOWER; - - final SpacingAndPunctuations spacingAndPunctuations = - new SpacingAndPunctuations(getContext().getResources()); - - final int timeStampInSeconds = (int)TimeUnit.MILLISECONDS.toSeconds( - System.currentTimeMillis()); - - for (int i = 0; i < dataChunkCount; i++) { - final ArrayList<String> tokens = new ArrayList<>(); - for (int j = 0; j < wordCountInOneChunk; j++) { - tokens.add(CodePointUtils.generateWord(random, codePointSet)); - } - final PersonalizationDataChunk personalizationDataChunk = new PersonalizationDataChunk( - true /* inputByUser */, tokens, timeStampInSeconds, DUMMY_PACKAGE_NAME); - final CountDownLatch countDownLatch = new CountDownLatch(1); - final AddMultipleDictionaryEntriesCallback callback = - new AddMultipleDictionaryEntriesCallback() { - @Override - public void onFinished() { - countDownLatch.countDown(); - } - }; - dictionaryFacilitator.addEntriesToPersonalizationDictionary(personalizationDataChunk, - spacingAndPunctuations, callback); - try { - countDownLatch.await(TIMEOUT_TO_WAIT_DICTIONARY_OPERATIONS_IN_SECONDS, - TimeUnit.SECONDS); - } catch (InterruptedException e) { - Log.e(TAG, "Interrupted while waiting for finishing dictionary operations.", e); - } - } - dictionaryFacilitator.flushPersonalizationDictionary(); - try { - dictionaryFacilitator.waitForLoadingDictionariesForTesting( - TIMEOUT_TO_WAIT_DICTIONARY_OPERATIONS_IN_SECONDS, TimeUnit.SECONDS); - } catch (InterruptedException e) { - Log.e(TAG, "Interrupted while waiting for finishing dictionary operations.", e); - } - final String dictName = ExpandableBinaryDictionary.getDictName( - PersonalizationDictionary.NAME, LOCALE_EN_US, null /* dictFile */); - final File dictFile = ExpandableBinaryDictionary.getDictFile( - getContext(), dictName, null /* dictFile */); - - final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), - 0 /* offset */, 0 /* size */, - true /* useFullEditDistance */, LOCALE_EN_US, Dictionary.TYPE_PERSONALIZATION, - true /* isUpdatable */); - assertTrue(binaryDictionary.isValidDictionary()); - } -} diff --git a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java index f87f3b494..559f28642 100644 --- a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java +++ b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java @@ -21,19 +21,11 @@ import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; import com.android.inputmethod.latin.ExpandableBinaryDictionary; -import com.android.inputmethod.latin.PrevWordsInfo; -import com.android.inputmethod.latin.PrevWordsInfo.WordInfo; import com.android.inputmethod.latin.utils.BinaryDictionaryUtils; -import com.android.inputmethod.latin.utils.DistracterFilter; -import com.android.inputmethod.latin.utils.FileUtils; import java.io.File; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; import java.util.Locale; import java.util.Random; -import java.util.concurrent.TimeUnit; /** * Unit tests for UserHistoryDictionary @@ -41,22 +33,47 @@ import java.util.concurrent.TimeUnit; @LargeTest public class UserHistoryDictionaryTests extends AndroidTestCase { private static final String TAG = UserHistoryDictionaryTests.class.getSimpleName(); - - 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 WAIT_FOR_WRITING_FILE_IN_MILLISECONDS = 3000; + private static final String TEST_ACCOUNT = "account@example.com"; private int mCurrentTime = 0; + private static void printAllFiles(final File dir) { + Log.d(TAG, dir.getAbsolutePath()); + for (final File file : dir.listFiles()) { + Log.d(TAG, " " + file.getName()); + } + } + + private static void assertDictionaryExists(final UserHistoryDictionary dict, + final File dictFile) { + Log.d(TAG, "waiting for writing ..."); + dict.waitAllTasksForTests(); + if (!dictFile.exists()) { + try { + Log.d(TAG, dictFile + " is not existing. Wait " + + WAIT_FOR_WRITING_FILE_IN_MILLISECONDS + " ms for writing."); + printAllFiles(dictFile.getParentFile()); + Thread.sleep(WAIT_FOR_WRITING_FILE_IN_MILLISECONDS); + } catch (final InterruptedException e) { + Log.e(TAG, "Interrupted during waiting for writing the dict file."); + } + } + assertTrue("Following dictionary file doesn't exist: " + dictFile, dictFile.exists()); + } + @Override protected void setUp() throws Exception { super.setUp(); resetCurrentTimeForTestMode(); + UserHistoryDictionaryTestsHelper.removeAllTestDictFiles( + UserHistoryDictionaryTestsHelper.TEST_LOCALE_PREFIX, mContext); } @Override protected void tearDown() throws Exception { + UserHistoryDictionaryTestsHelper.removeAllTestDictFiles( + UserHistoryDictionaryTestsHelper.TEST_LOCALE_PREFIX, mContext); stopTestModeInNativeCode(); super.tearDown(); } @@ -66,20 +83,6 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { setCurrentTimeForTestMode(mCurrentTime); } - private void forcePassingShortTime() { - // 3 days. - final int timeToElapse = (int)TimeUnit.DAYS.toSeconds(3); - mCurrentTime += timeToElapse; - setCurrentTimeForTestMode(mCurrentTime); - } - - private void forcePassingLongTime() { - // 365 days. - final int timeToElapse = (int)TimeUnit.DAYS.toSeconds(365); - mCurrentTime += timeToElapse; - setCurrentTimeForTestMode(mCurrentTime); - } - private static int setCurrentTimeForTestMode(final int currentTime) { return BinaryDictionaryUtils.setCurrentTimeForTest(currentTime); } @@ -89,199 +92,122 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { } /** - * Generates a random word. - */ - private static 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; - } - return builder.toString(); - } - - private static List<String> generateWords(final int number, final Random random) { - final HashSet<String> wordSet = new HashSet<>(); - while (wordSet.size() < number) { - wordSet.add(generateWord(random.nextInt())); - } - return new ArrayList<>(wordSet); - } - - private static void addToDict(final UserHistoryDictionary dict, final List<String> words) { - PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; - for (String word : words) { - UserHistoryDictionary.addToDictionary(dict, prevWordsInfo, word, true, - (int)TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()), - DistracterFilter.EMPTY_DISTRACTER_FILTER); - prevWordsInfo = prevWordsInfo.getNextPrevWordsInfo(new WordInfo(word)); - } - } - - /** - * @param checkContents if true, checks whether written words are actually in the dictionary - * or not. - */ - 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( - mContext, locale); - // Add random words to the user history dictionary. - addToDict(dict, words); - if (checkContents) { - dict.waitAllTasksForTests(); - for (int i = 0; i < numberOfWords; ++i) { - final String word = words.get(i); - assertTrue(dict.isInDictionary(word)); - } - } - // write to file. - dict.close(); - } - - /** * Clear all entries in the user history dictionary. - * @param locale dummy locale for testing. + * @param dict the user history dictionary. */ - private void clearHistory(final Locale locale) { - final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary( - mContext, locale); + private static void clearHistory(final UserHistoryDictionary dict) { dict.waitAllTasksForTests(); dict.clear(); dict.close(); dict.waitAllTasksForTests(); } - /** - * Shut down executer and wait until all operations of user history are done. - * @param locale dummy locale for testing. - */ - private void waitForWriting(final Locale locale) { - final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary( - mContext, locale); - dict.waitAllTasksForTests(); - } - - public void testRandomWords() { + private void doTestRandomWords(final String testAccount) { Log.d(TAG, "This test can be used for profiling."); Log.d(TAG, "Usage: please set UserHistoryDictionary.PROFILE_SAVE_RESTORE to true."); - final Locale dummyLocale = new Locale("test_random_words" + System.currentTimeMillis()); - final String dictName = ExpandableBinaryDictionary.getDictName( - UserHistoryDictionary.NAME, dummyLocale, null /* dictFile */); + final Locale dummyLocale = UserHistoryDictionaryTestsHelper.getDummyLocale("random_words"); + final String dictName = UserHistoryDictionary.getUserHistoryDictName( + UserHistoryDictionary.NAME, dummyLocale, + null /* dictFile */, + testAccount /* account */); final File dictFile = ExpandableBinaryDictionary.getDictFile( mContext, dictName, null /* dictFile */); + final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary( + getContext(), dummyLocale, testAccount); + clearHistory(dict); final int numberOfWords = 1000; final Random random = new Random(123456); + assertTrue(UserHistoryDictionaryTestsHelper.addAndWriteRandomWords( + dict, numberOfWords, random, true /* checksContents */, mCurrentTime)); + assertDictionaryExists(dict, dictFile); + } - try { - clearHistory(dummyLocale); - addAndWriteRandomWords(dummyLocale, numberOfWords, random, - true /* checksContents */); - } finally { - Log.d(TAG, "waiting for writing ..."); - waitForWriting(dummyLocale); - assertTrue("check exisiting of " + dictFile, dictFile.exists()); - FileUtils.deleteRecursively(dictFile); - } + public void testRandomWords_NullAccount() { + doTestRandomWords(null /* testAccount */); + } + + public void testRandomWords() { + doTestRandomWords(TEST_ACCOUNT); } public void testStressTestForSwitchingLanguagesAndAddingWords() { + doTestStressTestForSwitchingLanguagesAndAddingWords(TEST_ACCOUNT); + } + + public void testStressTestForSwitchingLanguagesAndAddingWords_NullAccount() { + doTestStressTestForSwitchingLanguagesAndAddingWords(null /* testAccount */); + } + + private void doTestStressTestForSwitchingLanguagesAndAddingWords(final String testAccount) { final int numberOfLanguages = 2; final int numberOfLanguageSwitching = 80; final int numberOfWordsInsertedForEachLanguageSwitch = 100; final File dictFiles[] = new File[numberOfLanguages]; - final Locale dummyLocales[] = new Locale[numberOfLanguages]; + final UserHistoryDictionary dicts[] = new UserHistoryDictionary[numberOfLanguages]; + try { final Random random = new Random(123456); // Create filename suffixes for this test. for (int i = 0; i < numberOfLanguages; i++) { - dummyLocales[i] = new Locale("test_switching_languages" + i); - final String dictName = ExpandableBinaryDictionary.getDictName( - UserHistoryDictionary.NAME, dummyLocales[i], null /* dictFile */); + final Locale dummyLocale = + UserHistoryDictionaryTestsHelper.getDummyLocale("switching_languages" + i); + final String dictName = UserHistoryDictionary.getUserHistoryDictName( + UserHistoryDictionary.NAME, dummyLocale, null /* dictFile */, + testAccount /* account */); dictFiles[i] = ExpandableBinaryDictionary.getDictFile( mContext, dictName, null /* dictFile */); - clearHistory(dummyLocales[i]); + dicts[i] = PersonalizationHelper.getUserHistoryDictionary(getContext(), + dummyLocale, testAccount); + clearHistory(dicts[i]); } final long start = System.currentTimeMillis(); for (int i = 0; i < numberOfLanguageSwitching; i++) { final int index = i % numberOfLanguages; - // Switch languages to testFilenameSuffixes[index]. - addAndWriteRandomWords(dummyLocales[index], - numberOfWordsInsertedForEachLanguageSwitch, random, - false /* checksContents */); + // Switch to dicts[index]. + assertTrue(UserHistoryDictionaryTestsHelper.addAndWriteRandomWords(dicts[index], + numberOfWordsInsertedForEachLanguageSwitch, + random, + false /* checksContents */, + mCurrentTime)); } final long end = System.currentTimeMillis(); Log.d(TAG, "testStressTestForSwitchingLanguageAndAddingWords took " + (end - start) + " ms"); } finally { - Log.d(TAG, "waiting for writing ..."); for (int i = 0; i < numberOfLanguages; i++) { - waitForWriting(dummyLocales[i]); - } - for (final File dictFile : dictFiles) { - assertTrue("check exisiting of " + dictFile, dictFile.exists()); - FileUtils.deleteRecursively(dictFile); + assertDictionaryExists(dicts[i], dictFiles[i]); } } } public void testAddManyWords() { - final Locale dummyLocale = new Locale("test_random_words" + System.currentTimeMillis()); - final String dictName = ExpandableBinaryDictionary.getDictName( - UserHistoryDictionary.NAME, dummyLocale, null /* dictFile */); + doTestAddManyWords(TEST_ACCOUNT); + } + + public void testAddManyWords_NullAccount() { + doTestAddManyWords(null /* testAccount */); + } + + private void doTestAddManyWords(final String testAccount) { + final Locale dummyLocale = + UserHistoryDictionaryTestsHelper.getDummyLocale("many_random_words"); + final String dictName = UserHistoryDictionary.getUserHistoryDictName( + UserHistoryDictionary.NAME, dummyLocale, null /* dictFile */, testAccount); final File dictFile = ExpandableBinaryDictionary.getDictFile( mContext, dictName, null /* dictFile */); final int numberOfWords = 10000; final Random random = new Random(123456); - clearHistory(dummyLocale); - try { - addAndWriteRandomWords(dummyLocale, numberOfWords, random, true /* checksContents */); - } finally { - Log.d(TAG, "waiting for writing ..."); - 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(); - PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; - for (final String word : words) { - UserHistoryDictionary.addToDictionary(dict, prevWordsInfo, word, true, mCurrentTime, - DistracterFilter.EMPTY_DISTRACTER_FILTER); - prevWordsInfo = prevWordsInfo.getNextPrevWordsInfo(new WordInfo(word)); - dict.waitAllTasksForTests(); - assertTrue(dict.isInDictionary(word)); - } - forcePassingShortTime(); - dict.runGCIfRequired(); - dict.waitAllTasksForTests(); - for (final String word : words) { - assertTrue(dict.isInDictionary(word)); - } - forcePassingLongTime(); - dict.runGCIfRequired(); - dict.waitAllTasksForTests(); - for (final String word : words) { - assertFalse(dict.isInDictionary(word)); - } + final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary( + getContext(), dummyLocale, testAccount); + clearHistory(dict); + assertTrue(UserHistoryDictionaryTestsHelper.addAndWriteRandomWords(dict, + numberOfWords, random, true /* checksContents */, mCurrentTime)); + assertDictionaryExists(dict, dictFile); } -} +}
\ No newline at end of file diff --git a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTestsHelper.java b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTestsHelper.java new file mode 100644 index 000000000..4b7b9bc36 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTestsHelper.java @@ -0,0 +1,144 @@ +/* + * 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.personalization; + +import android.content.Context; + +import com.android.inputmethod.latin.BinaryDictionary; +import com.android.inputmethod.latin.NgramContext; +import com.android.inputmethod.latin.NgramContext.WordInfo; +import com.android.inputmethod.latin.common.FileUtils; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Random; + +/** + * Utility class for helping while running tests involving {@link UserHistoryDictionary}. + */ +public class UserHistoryDictionaryTestsHelper { + + /** + * Locale prefix for generating dummy locales for tests. + */ + public static final String TEST_LOCALE_PREFIX = "test-"; + + /** + * Characters for generating random words. + */ + 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" + }; + + /** + * Remove all the test dictionary files created for the given locale. + */ + public static void removeAllTestDictFiles(final String filter, final Context context) { + final FilenameFilter filenameFilter = new FilenameFilter() { + @Override + public boolean accept(final File dir, final String filename) { + return filename.startsWith(UserHistoryDictionary.NAME + "." + filter); + } + }; + FileUtils.deleteFilteredFiles(context.getFilesDir(), filenameFilter); + } + + /** + * Generates and writes random words to dictionary. Caller can be assured + * that the write tasks would be finished; and its success would be reflected + * in the returned boolean. + * + * @param dict {@link UserHistoryDictionary} to which words should be added. + * @param numberOfWords number of words to be added. + * @param random helps generate random words. + * @param checkContents if true, checks whether written words are actually in the dictionary. + * @param currentTime timestamp that would be used for adding the words. + * @returns true if all words have been written to dictionary successfully. + */ + public static boolean addAndWriteRandomWords(final UserHistoryDictionary dict, + final int numberOfWords, final Random random, final boolean checkContents, + final int currentTime) { + final List<String> words = generateWords(numberOfWords, random); + // Add random words to the user history dictionary. + addWordsToDictionary(dict, words, currentTime); + boolean success = true; + if (checkContents) { + dict.waitAllTasksForTests(); + for (int i = 0; i < numberOfWords; ++i) { + final String word = words.get(i); + if (!dict.isInDictionary(word)) { + success = false; + break; + } + } + } + // write to file. + dict.close(); + dict.waitAllTasksForTests(); + return success; + } + + private static void addWordsToDictionary(final UserHistoryDictionary dict, + final List<String> words, final int timestamp) { + NgramContext ngramContext = NgramContext.getEmptyPrevWordsContext( + BinaryDictionary.MAX_PREV_WORD_COUNT_FOR_N_GRAM); + for (final String word : words) { + UserHistoryDictionary.addToDictionary(dict, ngramContext, word, true, timestamp); + ngramContext = ngramContext.getNextNgramContext(new WordInfo(word)); + } + } + + /** + * Creates unique test locale for using within tests. + */ + public static Locale getDummyLocale(final String name) { + return new Locale(TEST_LOCALE_PREFIX + name + System.currentTimeMillis()); + } + + /** + * Generates random words. + * + * @param numberOfWords number of words to generate. + * @param random salt used for generating random words. + */ + public static List<String> generateWords(final int numberOfWords, final Random random) { + final HashSet<String> wordSet = new HashSet<>(); + while (wordSet.size() < numberOfWords) { + wordSet.add(generateWord(random.nextInt())); + } + return new ArrayList<>(wordSet); + } + + /** + * Generates a random word. + */ + private static String generateWord(final int value) { + final int lengthOfChars = CHARACTERS.length; + final StringBuilder builder = new StringBuilder(); + long lvalue = Math.abs((long)value); + while (lvalue > 0) { + builder.append(CHARACTERS[(int)(lvalue % lengthOfChars)]); + lvalue /= lengthOfChars; + } + return builder.toString(); + } +} diff --git a/tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java b/tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java new file mode 100644 index 000000000..7a019c364 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/settings/AccountsSettingsFragmentTests.java @@ -0,0 +1,171 @@ +/* + * 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 static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.MediumTest; +import android.view.View; +import android.widget.ListView; + +import com.android.inputmethod.latin.utils.ManagedProfileUtils; + +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +@MediumTest +public class AccountsSettingsFragmentTests + extends ActivityInstrumentationTestCase2<TestFragmentActivity> { + private static final String FRAG_NAME = AccountsSettingsFragment.class.getName(); + private static final long TEST_TIMEOUT_MILLIS = 5000; + + @Mock private ManagedProfileUtils mManagedProfileUtils; + + public AccountsSettingsFragmentTests() { + super(TestFragmentActivity.class); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + // Initialize the mocks. + MockitoAnnotations.initMocks(this); + ManagedProfileUtils.setTestInstance(mManagedProfileUtils); + + Intent intent = new Intent(); + intent.putExtra(TestFragmentActivity.EXTRA_SHOW_FRAGMENT, FRAG_NAME); + setActivityIntent(intent); + } + + @Override + public void tearDown() throws Exception { + ManagedProfileUtils.setTestInstance(null); + super.tearDown(); + } + + public void testEmptyAccounts() { + final AccountsSettingsFragment fragment = + (AccountsSettingsFragment) getActivity().mFragment; + try { + fragment.createAccountPicker(new String[0], null, null /* listener */); + fail("Expected IllegalArgumentException, never thrown"); + } catch (IllegalArgumentException expected) { + // Expected. + } + } + + private static class DialogHolder { + AlertDialog mDialog; + DialogHolder() {} + } + + public void testMultipleAccounts_noSettingsForManagedProfile() { + when(mManagedProfileUtils.hasWorkProfile(any(Context.class))).thenReturn(true); + + final AccountsSettingsFragment fragment = + (AccountsSettingsFragment) getActivity().mFragment; + final AlertDialog dialog = initDialog(fragment, null).mDialog; + final ListView lv = dialog.getListView(); + + // Nothing to check/uncheck. + assertNull(fragment.findPreference(AccountsSettingsFragment.PREF_ACCCOUNT_SWITCHER)); + } + + public void testMultipleAccounts_noCurrentAccount() { + when(mManagedProfileUtils.hasWorkProfile(any(Context.class))).thenReturn(false); + + final AccountsSettingsFragment fragment = + (AccountsSettingsFragment) getActivity().mFragment; + final AlertDialog dialog = initDialog(fragment, null).mDialog; + final ListView lv = dialog.getListView(); + + // The 1st account should be checked by default. + assertEquals("checked-item", 0, lv.getCheckedItemPosition()); + // There should be 4 accounts in the list. + assertEquals("count", 4, lv.getCount()); + // The sign-out button shouldn't exist + assertEquals(View.GONE, + dialog.getButton(DialogInterface.BUTTON_NEUTRAL).getVisibility()); + assertEquals(View.VISIBLE, + dialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility()); + assertEquals(View.VISIBLE, + dialog.getButton(DialogInterface.BUTTON_POSITIVE).getVisibility()); + } + + public void testMultipleAccounts_currentAccount() { + when(mManagedProfileUtils.hasWorkProfile(any(Context.class))).thenReturn(false); + + final AccountsSettingsFragment fragment = + (AccountsSettingsFragment) getActivity().mFragment; + final AlertDialog dialog = initDialog(fragment, "3@example.com").mDialog; + final ListView lv = dialog.getListView(); + + // The 3rd account should be checked by default. + assertEquals("checked-item", 2, lv.getCheckedItemPosition()); + // There should be 4 accounts in the list. + assertEquals("count", 4, lv.getCount()); + // The sign-out button should be shown + assertEquals(View.VISIBLE, + dialog.getButton(DialogInterface.BUTTON_NEUTRAL).getVisibility()); + assertEquals(View.VISIBLE, + dialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility()); + assertEquals(View.VISIBLE, + dialog.getButton(DialogInterface.BUTTON_POSITIVE).getVisibility()); + } + + private DialogHolder initDialog( + final AccountsSettingsFragment fragment, + final String selectedAccount) { + final DialogHolder dialogHolder = new DialogHolder(); + final CountDownLatch latch = new CountDownLatch(1); + + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + final AlertDialog dialog = fragment.createAccountPicker( + new String[] { + "1@example.com", + "2@example.com", + "3@example.com", + "4@example.com"}, + selectedAccount, null /* positiveButtonListner */); + dialog.show(); + dialogHolder.mDialog = dialog; + latch.countDown(); + } + }); + + try { + latch.await(TEST_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); + } catch (InterruptedException ex) { + fail(); + } + getInstrumentation().waitForIdleSync(); + return dialogHolder; + } +} diff --git a/tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java b/tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java index eb76032b1..ed632db68 100644 --- a/tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java +++ b/tests/src/com/android/inputmethod/latin/settings/SpacingAndPunctuationsTests.java @@ -20,9 +20,8 @@ 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.common.Constants; import com.android.inputmethod.latin.utils.RunInLocale; import junit.framework.AssertionFailedError; @@ -37,13 +36,11 @@ public class SpacingAndPunctuationsTests extends AndroidTestCase { private int mScreenMetrics; private boolean isPhone() { - return mScreenMetrics == Constants.SCREEN_METRICS_SMALL_PHONE - || mScreenMetrics == Constants.SCREEN_METRICS_LARGE_PHONE; + return Constants.isPhone(mScreenMetrics); } private boolean isTablet() { - return mScreenMetrics == Constants.SCREEN_METRICS_SMALL_TABLET - || mScreenMetrics == Constants.SCREEN_METRICS_LARGE_TABLET; + return Constants.isTablet(mScreenMetrics); } private SpacingAndPunctuations ENGLISH; @@ -70,7 +67,7 @@ public class SpacingAndPunctuationsTests extends AndroidTestCase { protected void setUp() throws Exception { super.setUp(); - mScreenMetrics = mContext.getResources().getInteger(R.integer.config_screen_metrics); + mScreenMetrics = Settings.readScreenMetrics(getContext().getResources()); // Language only ENGLISH = getSpacingAndPunctuations(Locale.ENGLISH); diff --git a/tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java b/tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java index 2272d6ba0..e7c48da19 100644 --- a/tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java +++ b/tests/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerServiceTest.java @@ -53,14 +53,8 @@ public class AndroidSpellCheckerServiceTest extends InputTestsBase { sleep(1000); final SpanGetter span = new SpanGetter(mEditText.getText(), SuggestionSpan.class); - // If no span, the following will crash - final String[] suggestions = span.getSuggestions(); - // For this test we consider "годп" should yield at least 2 suggestions (at this moment - // it yields 5). - assertTrue(suggestions.length >= 2); - // We also assume the top suggestion should be "года", which is the top word in the - // Russian dictionary. - assertEquals("", "года", suggestions[0]); + // We don't ship with Russian LM + assertNull(span.getSpan()); } public void testSpellcheckWithPeriods() { diff --git a/tests/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookupTest.java b/tests/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookupTest.java new file mode 100644 index 000000000..e5c813942 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookupTest.java @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2015 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.spellcheck; + +import android.annotation.SuppressLint; +import android.content.ContentResolver; +import android.database.Cursor; +import android.net.Uri; +import android.provider.UserDictionary; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; +import android.util.Log; + +import java.util.HashSet; +import java.util.Locale; + +/** + * Unit tests for {@link UserDictionaryLookup}. + * + * Note, this test doesn't mock out the ContentResolver, in order to make sure UserDictionaryLookup + * works in a real setting. + */ +@SmallTest +public class UserDictionaryLookupTest extends AndroidTestCase { + private static final String TAG = UserDictionaryLookupTest.class.getSimpleName(); + + private ContentResolver mContentResolver; + private HashSet<Uri> mAddedBackup; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mContentResolver = mContext.getContentResolver(); + mAddedBackup = new HashSet<Uri>(); + } + + @Override + protected void tearDown() throws Exception { + // Remove all entries added during this test. + for (Uri row : mAddedBackup) { + mContentResolver.delete(row, null, null); + } + mAddedBackup.clear(); + + super.tearDown(); + } + + /** + * Adds the given word to UserDictionary. + * + * @param word the word to add + * @param locale the locale of the word to add + * @param frequency the frequency of the word to add + * @return the Uri for the given word + */ + @SuppressLint("NewApi") + private Uri addWord(final String word, final Locale locale, int frequency) { + // Add the given word for the given locale. + UserDictionary.Words.addWord(mContext, word, frequency, null, locale); + // Obtain an Uri for the given word. + Cursor cursor = mContentResolver.query(UserDictionary.Words.CONTENT_URI, null, + UserDictionary.Words.WORD + "='" + word + "'", null, null); + assertTrue(cursor.moveToFirst()); + Uri uri = Uri.withAppendedPath(UserDictionary.Words.CONTENT_URI, + cursor.getString(cursor.getColumnIndex(UserDictionary.Words._ID))); + // Add the row to the backup for later clearing. + mAddedBackup.add(uri); + return uri; + } + + /** + * Deletes the entry for the given word from UserDictionary. + * + * @param uri the Uri for the word as returned by addWord + */ + private void deleteWord(Uri uri) { + // Remove the word from the backup so that it's not cleared again later. + mAddedBackup.remove(uri); + // Remove the word from UserDictionary. + mContentResolver.delete(uri, null, null); + } + + public void testExactLocaleMatch() { + Log.d(TAG, "testExactLocaleMatch"); + + // Insert "Foo" as capitalized in the UserDictionary under en_US locale. + addWord("Foo", Locale.US, 17); + + // Create the UserDictionaryLookup and wait until it's loaded. + UserDictionaryLookup lookup = new UserDictionaryLookup(mContext); + while (!lookup.isLoaded()) { + } + + // Any capitalization variation should match. + assertTrue(lookup.isValidWord("foo", Locale.US)); + assertTrue(lookup.isValidWord("Foo", Locale.US)); + assertTrue(lookup.isValidWord("FOO", Locale.US)); + // But similar looking words don't match. + assertFalse(lookup.isValidWord("fo", Locale.US)); + assertFalse(lookup.isValidWord("fop", Locale.US)); + assertFalse(lookup.isValidWord("fooo", Locale.US)); + // Other locales, including more general locales won't match. + assertFalse(lookup.isValidWord("foo", Locale.ENGLISH)); + assertFalse(lookup.isValidWord("foo", Locale.UK)); + assertFalse(lookup.isValidWord("foo", Locale.FRENCH)); + assertFalse(lookup.isValidWord("foo", new Locale(""))); + + lookup.close(); + } + + public void testSubLocaleMatch() { + Log.d(TAG, "testSubLocaleMatch"); + + // Insert "Foo" as capitalized in the UserDictionary under the en locale. + addWord("Foo", Locale.ENGLISH, 17); + + // Create the UserDictionaryLookup and wait until it's loaded. + UserDictionaryLookup lookup = new UserDictionaryLookup(mContext); + while (!lookup.isLoaded()) { + } + + // Any capitalization variation should match for both en and en_US. + assertTrue(lookup.isValidWord("foo", Locale.ENGLISH)); + assertTrue(lookup.isValidWord("foo", Locale.US)); + assertTrue(lookup.isValidWord("Foo", Locale.US)); + assertTrue(lookup.isValidWord("FOO", Locale.US)); + // But similar looking words don't match. + assertFalse(lookup.isValidWord("fo", Locale.US)); + assertFalse(lookup.isValidWord("fop", Locale.US)); + assertFalse(lookup.isValidWord("fooo", Locale.US)); + + lookup.close(); + } + + public void testAllLocalesMatch() { + Log.d(TAG, "testAllLocalesMatch"); + + // Insert "Foo" as capitalized in the UserDictionary under the all locales. + addWord("Foo", null, 17); + + // Create the UserDictionaryLookup and wait until it's loaded. + UserDictionaryLookup lookup = new UserDictionaryLookup(mContext); + while (!lookup.isLoaded()) { + } + + // Any capitalization variation should match for fr, en and en_US. + assertTrue(lookup.isValidWord("foo", new Locale(""))); + assertTrue(lookup.isValidWord("foo", Locale.FRENCH)); + assertTrue(lookup.isValidWord("foo", Locale.ENGLISH)); + assertTrue(lookup.isValidWord("foo", Locale.US)); + assertTrue(lookup.isValidWord("Foo", Locale.US)); + assertTrue(lookup.isValidWord("FOO", Locale.US)); + // But similar looking words don't match. + assertFalse(lookup.isValidWord("fo", Locale.US)); + assertFalse(lookup.isValidWord("fop", Locale.US)); + assertFalse(lookup.isValidWord("fooo", Locale.US)); + + lookup.close(); + } + + public void testMultipleLocalesMatch() { + Log.d(TAG, "testMultipleLocalesMatch"); + + // Insert "Foo" as capitalized in the UserDictionary under the en_US and en_CA and fr + // locales. + addWord("Foo", Locale.US, 17); + addWord("foO", Locale.CANADA, 17); + addWord("fOo", Locale.FRENCH, 17); + + // Create the UserDictionaryLookup and wait until it's loaded. + UserDictionaryLookup lookup = new UserDictionaryLookup(mContext); + while (!lookup.isLoaded()) { + } + + // Both en_CA and en_US match. + assertTrue(lookup.isValidWord("foo", Locale.CANADA)); + assertTrue(lookup.isValidWord("foo", Locale.US)); + assertTrue(lookup.isValidWord("foo", Locale.FRENCH)); + // Other locales, including more general locales won't match. + assertFalse(lookup.isValidWord("foo", Locale.ENGLISH)); + assertFalse(lookup.isValidWord("foo", Locale.UK)); + assertFalse(lookup.isValidWord("foo", new Locale(""))); + + lookup.close(); + } + + public void testReload() { + Log.d(TAG, "testReload"); + + // Insert "foo". + Uri uri = addWord("foo", Locale.US, 17); + + // Create the UserDictionaryLookup and wait until it's loaded. + UserDictionaryLookup lookup = new UserDictionaryLookup(mContext); + while (!lookup.isLoaded()) { + } + + // "foo" should match. + assertTrue(lookup.isValidWord("foo", Locale.US)); + + // "bar" shouldn't match. + assertFalse(lookup.isValidWord("bar", Locale.US)); + + // Now delete "foo" and add "bar". + deleteWord(uri); + addWord("bar", Locale.US, 18); + + // Wait a little bit before expecting a change. The time we wait should be greater than + // UserDictionaryLookup.RELOAD_DELAY_MS. + try { + Thread.sleep(UserDictionaryLookup.RELOAD_DELAY_MS + 1000); + } catch (InterruptedException e) { + } + + // Perform lookups again. Reload should have occured. + // + // "foo" should not match. + assertFalse(lookup.isValidWord("foo", Locale.US)); + + // "bar" should match. + assertTrue(lookup.isValidWord("bar", Locale.US)); + + lookup.close(); + } + + public void testClose() { + Log.d(TAG, "testClose"); + + // Insert "foo". + Uri uri = addWord("foo", Locale.US, 17); + + // Create the UserDictionaryLookup and wait until it's loaded. + UserDictionaryLookup lookup = new UserDictionaryLookup(mContext); + while (!lookup.isLoaded()) { + } + + // "foo" should match. + assertTrue(lookup.isValidWord("foo", Locale.US)); + + // "bar" shouldn't match. + assertFalse(lookup.isValidWord("bar", Locale.US)); + + // Now close (prevents further reloads). + lookup.close(); + + // Now delete "foo" and add "bar". + deleteWord(uri); + addWord("bar", Locale.US, 18); + + // Wait a little bit before expecting a change. The time we wait should be greater than + // UserDictionaryLookup.RELOAD_DELAY_MS. + try { + Thread.sleep(UserDictionaryLookup.RELOAD_DELAY_MS + 1000); + } catch (InterruptedException e) { + } + + // Perform lookups again. Reload should not have occurred. + // + // "foo" should stil match. + assertTrue(lookup.isValidWord("foo", Locale.US)); + + // "bar" should still not match. + assertFalse(lookup.isValidWord("bar", Locale.US)); + } +} diff --git a/tests/src/com/android/inputmethod/latin/touchinputconsumer/NullGestureConsumerTests.java b/tests/src/com/android/inputmethod/latin/touchinputconsumer/NullGestureConsumerTests.java new file mode 100644 index 000000000..ad6bcc3c4 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/touchinputconsumer/NullGestureConsumerTests.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.touchinputconsumer; + +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + +/** + * Tests for GestureConsumer.NULL_GESTURE_CONSUMER. + */ +@SmallTest +public class NullGestureConsumerTests extends AndroidTestCase { + /** + * Tests that GestureConsumer.NULL_GESTURE_CONSUMER indicates that it won't consume gesture data + * and that its methods don't raise exceptions even for invalid data. + */ + public void testNullGestureConsumer() { + assertFalse(GestureConsumer.NULL_GESTURE_CONSUMER.willConsume()); + GestureConsumer.NULL_GESTURE_CONSUMER.onInit(null, null); + GestureConsumer.NULL_GESTURE_CONSUMER.onGestureStarted(null, null); + GestureConsumer.NULL_GESTURE_CONSUMER.onGestureCanceled(); + GestureConsumer.NULL_GESTURE_CONSUMER.onGestureCompleted(null); + GestureConsumer.NULL_GESTURE_CONSUMER.onImeSuggestionsProcessed(null, -1, -1, null); + } + + /** + * Tests that newInstance returns NULL_GESTURE_CONSUMER for invalid input. + */ + public void testNewInstanceGivesNullGestureConsumerForInvalidInputs() { + assertSame(GestureConsumer.NULL_GESTURE_CONSUMER, + GestureConsumer.newInstance(null, null, null, null)); + } +} diff --git a/tests/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtilsTests.java index 91c9c3775..1db839506 100644 --- a/tests/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtilsTests.java @@ -16,6 +16,13 @@ package com.android.inputmethod.latin.utils; +import static com.android.inputmethod.latin.common.Constants.Subtype.KEYBOARD_MODE; +import static com.android.inputmethod.latin.common.Constants.Subtype.ExtraValue.ASCII_CAPABLE; +import static com.android.inputmethod.latin.common.Constants.Subtype.ExtraValue.EMOJI_CAPABLE; +import static com.android.inputmethod.latin.common.Constants.Subtype.ExtraValue.IS_ADDITIONAL_SUBTYPE; +import static com.android.inputmethod.latin.common.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET; +import static com.android.inputmethod.latin.common.Constants.Subtype.ExtraValue.UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME; + import android.content.Context; import android.os.Build; import android.test.AndroidTestCase; @@ -26,14 +33,6 @@ import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils; import java.util.Locale; -import static com.android.inputmethod.latin.Constants.Subtype.KEYBOARD_MODE; -import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.ASCII_CAPABLE; -import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.EMOJI_CAPABLE; -import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.IS_ADDITIONAL_SUBTYPE; -import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET; -import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue - .UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME; - @SmallTest public class AdditionalSubtypeUtilsTests extends AndroidTestCase { @@ -151,25 +150,25 @@ public class AdditionalSubtypeUtilsTests extends AndroidTestCase { } public void testRestorable() { - final InputMethodSubtype EN_UK_DVORAK = + final InputMethodSubtype EN_US_DVORAK = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( Locale.US.toString(), "dvorak"); final InputMethodSubtype ZZ_AZERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( SubtypeLocaleUtils.NO_LANGUAGE, "azerty"); - assertEnUsDvorak(EN_UK_DVORAK); + assertEnUsDvorak(EN_US_DVORAK); assertAzerty(ZZ_AZERTY); // Make sure the subtype can be stored and restored in a deterministic manner. - final InputMethodSubtype[] subtypes = { EN_UK_DVORAK, ZZ_AZERTY }; + final InputMethodSubtype[] subtypes = { EN_US_DVORAK, ZZ_AZERTY }; final String prefSubtype = AdditionalSubtypeUtils.createPrefSubtypes(subtypes); final InputMethodSubtype[] restoredSubtypes = AdditionalSubtypeUtils.createAdditionalSubtypesArray(prefSubtype); assertEquals(2, restoredSubtypes.length); - final InputMethodSubtype restored_EN_UK_DVORAK = restoredSubtypes[0]; + final InputMethodSubtype restored_EN_US_DVORAK = restoredSubtypes[0]; final InputMethodSubtype restored_ZZ_AZERTY = restoredSubtypes[1]; - assertEnUsDvorak(restored_EN_UK_DVORAK); + assertEnUsDvorak(restored_EN_US_DVORAK); assertAzerty(restored_ZZ_AZERTY); } } diff --git a/tests/src/com/android/inputmethod/latin/utils/AsyncResultHolderTests.java b/tests/src/com/android/inputmethod/latin/utils/AsyncResultHolderTests.java index 1501e942a..170d64383 100644 --- a/tests/src/com/android/inputmethod/latin/utils/AsyncResultHolderTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/AsyncResultHolderTests.java @@ -22,14 +22,14 @@ import android.util.Log; @MediumTest public class AsyncResultHolderTests extends AndroidTestCase { - private static final String TAG = AsyncResultHolderTests.class.getSimpleName(); + static final String TAG = AsyncResultHolderTests.class.getSimpleName(); private static final int TIMEOUT_IN_MILLISECONDS = 500; private static final int MARGIN_IN_MILLISECONDS = 250; private static final int DEFAULT_VALUE = 2; private static final int SET_VALUE = 1; - private <T> void setAfterGivenTime(final AsyncResultHolder<T> holder, final T value, + private static <T> void setAfterGivenTime(final AsyncResultHolder<T> holder, final T value, final long time) { new Thread(new Runnable() { @Override diff --git a/tests/src/com/android/inputmethod/latin/utils/BinaryDictionaryUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/BinaryDictionaryUtilsTests.java deleted file mode 100644 index a333ee9bc..000000000 --- a/tests/src/com/android/inputmethod/latin/utils/BinaryDictionaryUtilsTests.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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.test.AndroidTestCase; -import android.test.suitebuilder.annotation.LargeTest; - -import com.android.inputmethod.latin.BinaryDictionary; -import com.android.inputmethod.latin.makedict.DictionaryHeader; -import com.android.inputmethod.latin.makedict.FormatSpec; - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -@LargeTest -public class BinaryDictionaryUtilsTests extends AndroidTestCase { - private static final String TEST_DICT_FILE_EXTENSION = ".testDict"; - private static final String TEST_LOCALE = "test"; - - 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 createEmptyVer4DictionaryAndGetFile(final String dictId) throws IOException { - final File file = getDictFile(dictId); - FileUtils.deleteRecursively(file); - Map<String, String> attributeMap = new HashMap<>(); - 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 (BinaryDictionaryUtils.createEmptyDictFile(file.getAbsolutePath(), FormatSpec.VERSION4, - LocaleUtils.constructLocaleFromString(TEST_LOCALE), attributeMap)) { - return file; - } else { - throw new IOException("Empty dictionary " + file.getAbsolutePath() - + " cannot be created."); - } - } - - private File getDictFile(final String dictId) { - return new File(getContext().getCacheDir(), dictId + TEST_DICT_FILE_EXTENSION); - } - - public void testRenameDictionary() { - final int formatVersion = FormatSpec.VERSION4; - File dictFile0 = null; - try { - dictFile0 = createEmptyDictionaryAndGetFile("MoveFromDictionary", formatVersion); - } catch (IOException e) { - fail("IOException while writing an initial dictionary : " + e); - } - final File dictFile1 = getDictFile("MoveToDictionary"); - FileUtils.deleteRecursively(dictFile1); - assertTrue(BinaryDictionaryUtils.renameDict(dictFile0, dictFile1)); - assertFalse(dictFile0.exists()); - assertTrue(dictFile1.exists()); - BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile1.getAbsolutePath(), - 0 /* offset */, dictFile1.length(), true /* useFullEditDistance */, - Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); - assertTrue(binaryDictionary.isValidDictionary()); - assertTrue(binaryDictionary.getFormatVersion() == formatVersion); - binaryDictionary.close(); - } -} diff --git a/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java index c746c8345..9680d85b3 100644 --- a/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/CapsModeUtilsTests.java @@ -21,8 +21,8 @@ import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; import android.text.TextUtils; +import com.android.inputmethod.latin.common.LocaleUtils; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; -import com.android.inputmethod.latin.utils.LocaleUtils; import java.util.Locale; @@ -124,5 +124,29 @@ public class CapsModeUtilsTests extends AndroidTestCase { allPathsForCaps("Word. ", c | w, sp, false); // Armenian period : capitalize if MODE_SENTENCES allPathsForCaps("Word\u0589 ", c | w | s, sp, false); + + // Test for sentence terminators + sp = job.runInLocale(res, Locale.ENGLISH); + allPathsForCaps("Word? ", c | w | s, sp, false); + allPathsForCaps("Word?", c | w | s, sp, true); + allPathsForCaps("Word?", c, sp, false); + allPathsForCaps("Word! ", c | w | s, sp, false); + allPathsForCaps("Word!", c | w | s, sp, true); + allPathsForCaps("Word!", c, sp, false); + allPathsForCaps("Word; ", c | w, sp, false); + allPathsForCaps("Word;", c | w, sp, true); + allPathsForCaps("Word;", c, sp, false); + // Test for sentence terminators in Greek + sp = job.runInLocale(res, LocaleUtils.constructLocaleFromString("el")); + allPathsForCaps("Word? ", c | w | s, sp, false); + allPathsForCaps("Word?", c | w | s, sp, true); + allPathsForCaps("Word?", c, sp, false); + allPathsForCaps("Word! ", c | w | s, sp, false); + allPathsForCaps("Word!", c | w | s, sp, true); + allPathsForCaps("Word!", c, sp, false); + // In Greek ";" is the question mark and it terminates the sentence + allPathsForCaps("Word; ", c | w | s, sp, false); + allPathsForCaps("Word;", c | w | s, sp, true); + allPathsForCaps("Word;", c, sp, false); } } diff --git a/tests/src/com/android/inputmethod/latin/utils/CollectionUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/CollectionUtilsTests.java new file mode 100644 index 000000000..47fd5feaa --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/utils/CollectionUtilsTests.java @@ -0,0 +1,87 @@ +/* + * 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.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + +import com.android.inputmethod.latin.common.CollectionUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + +/** + * Tests for {@link CollectionUtils}. + */ +@SmallTest +public class CollectionUtilsTests extends AndroidTestCase { + /** + * Tests that {@link CollectionUtils#arrayAsList(Object[],int,int)} fails as expected + * with some invalid inputs. + */ + public void testArrayAsListFailure() { + final String[] array = { "0", "1" }; + // Negative start + try { + CollectionUtils.arrayAsList(array, -1, 1); + fail("Failed to catch start < 0"); + } catch (final IllegalArgumentException e) { + assertEquals("Invalid start: -1 end: 1 with array.length: 2", e.getMessage()); + } + // start > end + try { + CollectionUtils.arrayAsList(array, 1, -1); + fail("Failed to catch start > end"); + } catch (final IllegalArgumentException e) { + assertEquals("Invalid start: 1 end: -1 with array.length: 2", e.getMessage()); + } + // end > array.length + try { + CollectionUtils.arrayAsList(array, 1, 3); + fail("Failed to catch end > array.length"); + } catch (final IllegalArgumentException e) { + assertEquals("Invalid start: 1 end: 3 with array.length: 2", e.getMessage()); + } + } + + /** + * Tests that {@link CollectionUtils#arrayAsList(Object[],int,int)} gives the expected + * results for a few valid inputs. + */ + public void testArrayAsList() { + final ArrayList<String> empty = new ArrayList<>(); + assertEquals(empty, CollectionUtils.arrayAsList(new String[] { }, 0, 0)); + final String[] array = { "0", "1", "2", "3", "4" }; + assertEquals(empty, CollectionUtils.arrayAsList(array, 0, 0)); + assertEquals(empty, CollectionUtils.arrayAsList(array, 1, 1)); + assertEquals(empty, CollectionUtils.arrayAsList(array, array.length, array.length)); + final ArrayList<String> expected123 = new ArrayList<>(Arrays.asList("1", "2", "3")); + assertEquals(expected123, CollectionUtils.arrayAsList(array, 1, 4)); + } + + /** + * Tests that {@link CollectionUtils#isNullOrEmpty(java.util.Collection)} gives the expected + * results for a few cases. + */ + public void testIsNullOrEmpty() { + assertTrue(CollectionUtils.isNullOrEmpty(null)); + assertTrue(CollectionUtils.isNullOrEmpty(new ArrayList<>())); + assertTrue(CollectionUtils.isNullOrEmpty(Collections.EMPTY_SET)); + assertFalse(CollectionUtils.isNullOrEmpty(Collections.singleton("Not empty"))); + } +} diff --git a/tests/src/com/android/inputmethod/latin/utils/DictionaryInfoUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/DictionaryInfoUtilsTests.java index 6e716074c..812353cc4 100644 --- a/tests/src/com/android/inputmethod/latin/utils/DictionaryInfoUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/DictionaryInfoUtilsTests.java @@ -20,6 +20,7 @@ import android.content.res.Resources; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; +import com.android.inputmethod.latin.common.LocaleUtils; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import java.util.Locale; @@ -44,4 +45,21 @@ public class DictionaryInfoUtilsTests extends AndroidTestCase { sp)); assertFalse(DictionaryInfoUtils.looksValidForDictionaryInsertion("!!!", sp)); } + + public void testGetMainDictId() { + assertEquals("main:en", + DictionaryInfoUtils.getMainDictId(LocaleUtils.constructLocaleFromString("en"))); + assertEquals("main:en_us", + DictionaryInfoUtils.getMainDictId(LocaleUtils.constructLocaleFromString("en_US"))); + assertEquals("main:en_gb", + DictionaryInfoUtils.getMainDictId(LocaleUtils.constructLocaleFromString("en_GB"))); + + assertEquals("main:es", + DictionaryInfoUtils.getMainDictId(LocaleUtils.constructLocaleFromString("es"))); + assertEquals("main:es_us", + DictionaryInfoUtils.getMainDictId(LocaleUtils.constructLocaleFromString("es_US"))); + + assertEquals("main:en_us_posix", DictionaryInfoUtils.getMainDictId( + LocaleUtils.constructLocaleFromString("en_US_POSIX"))); + } } diff --git a/tests/src/com/android/inputmethod/latin/utils/EditDistanceTests.java b/tests/src/com/android/inputmethod/latin/utils/EditDistanceTests.java deleted file mode 100644 index 58312264b..000000000 --- a/tests/src/com/android/inputmethod/latin/utils/EditDistanceTests.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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.latin.utils; - -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -@SmallTest -public class EditDistanceTests extends AndroidTestCase { - /* - * dist(kitten, sitting) == 3 - * - * kitten- - * .|||.| - * sitting - */ - public void testExample1() { - final int dist = BinaryDictionaryUtils.editDistance("kitten", "sitting"); - assertEquals("edit distance between 'kitten' and 'sitting' is 3", - 3, dist); - } - - /* - * dist(Sunday, Saturday) == 3 - * - * Saturday - * | |.||| - * S--unday - */ - public void testExample2() { - final int dist = BinaryDictionaryUtils.editDistance("Saturday", "Sunday"); - assertEquals("edit distance between 'Saturday' and 'Sunday' is 3", - 3, dist); - } - - public void testBothEmpty() { - final int dist = BinaryDictionaryUtils.editDistance("", ""); - assertEquals("when both string are empty, no edits are needed", - 0, dist); - } - - public void testFirstArgIsEmpty() { - final int dist = BinaryDictionaryUtils.editDistance("", "aaaa"); - assertEquals("when only one string of the arguments is empty," - + " the edit distance is the length of the other.", - 4, dist); - } - - public void testSecoondArgIsEmpty() { - final int dist = BinaryDictionaryUtils.editDistance("aaaa", ""); - assertEquals("when only one string of the arguments is empty," - + " the edit distance is the length of the other.", - 4, dist); - } - - public void testSameStrings() { - final String arg1 = "The quick brown fox jumps over the lazy dog."; - final String arg2 = "The quick brown fox jumps over the lazy dog."; - final int dist = BinaryDictionaryUtils.editDistance(arg1, arg2); - assertEquals("when same strings are passed, distance equals 0.", - 0, dist); - } - - public void testSameReference() { - final String arg = "The quick brown fox jumps over the lazy dog."; - final int dist = BinaryDictionaryUtils.editDistance(arg, arg); - assertEquals("when same string references are passed, the distance equals 0.", - 0, dist); - } - - public void testNullArg() { - try { - BinaryDictionaryUtils.editDistance(null, "aaa"); - fail("IllegalArgumentException should be thrown."); - } catch (Exception e) { - assertTrue(e instanceof IllegalArgumentException); - } - try { - BinaryDictionaryUtils.editDistance("aaa", null); - fail("IllegalArgumentException should be thrown."); - } catch (Exception e) { - assertTrue(e instanceof IllegalArgumentException); - } - } -} diff --git a/tests/src/com/android/inputmethod/latin/utils/ExecutorUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/ExecutorUtilsTests.java index ae2623d12..86923059b 100644 --- a/tests/src/com/android/inputmethod/latin/utils/ExecutorUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/ExecutorUtilsTests.java @@ -25,18 +25,18 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** - * Unit tests for ExecutorUtils. + * Unit tests for {@link ExecutorUtils}. */ @MediumTest public class ExecutorUtilsTests extends AndroidTestCase { private static final String TAG = ExecutorUtilsTests.class.getSimpleName(); - private static final String TEST_EXECUTOR_ID = "test"; private static final int NUM_OF_TASKS = 10; private static final int DELAY_FOR_WAITING_TASKS_MILLISECONDS = 500; public void testExecute() { - final ExecutorService executor = ExecutorUtils.getExecutor(TEST_EXECUTOR_ID); + final ExecutorService executor = + ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD); final AtomicInteger v = new AtomicInteger(0); for (int i = 0; i < NUM_OF_TASKS; ++i) { executor.execute(new Runnable() { diff --git a/tests/src/com/android/inputmethod/latin/utils/ImportantNoticeUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/ImportantNoticeUtilsTests.java index 819d76328..e361c7704 100644 --- a/tests/src/com/android/inputmethod/latin/utils/ImportantNoticeUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/ImportantNoticeUtilsTests.java @@ -16,24 +16,32 @@ package com.android.inputmethod.latin.utils; -import static com.android.inputmethod.latin.utils.ImportantNoticeUtils.KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE; import static com.android.inputmethod.latin.utils.ImportantNoticeUtils.KEY_IMPORTANT_NOTICE_VERSION; +import static com.android.inputmethod.latin.utils.ImportantNoticeUtils.KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE; +import static org.mockito.Mockito.when; import android.content.Context; import android.content.SharedPreferences; import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; +import android.test.suitebuilder.annotation.MediumTest; import android.text.TextUtils; +import com.android.inputmethod.latin.settings.SettingsValues; + +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + import java.util.concurrent.TimeUnit; -@SmallTest +@MediumTest public class ImportantNoticeUtilsTests extends AndroidTestCase { // This should be aligned with R.integer.config_important_notice_version. private static final int CURRENT_IMPORTANT_NOTICE_VERSION = 1; private ImportantNoticePreferences mImportantNoticePreferences; + @Mock private SettingsValues mMockSettingsValues; + private static class ImportantNoticePreferences { private final SharedPreferences mPref; @@ -97,8 +105,10 @@ public class ImportantNoticeUtilsTests extends AndroidTestCase { @Override protected void setUp() throws Exception { super.setUp(); + MockitoAnnotations.initMocks(this); mImportantNoticePreferences = new ImportantNoticePreferences(getContext()); mImportantNoticePreferences.save(); + when(mMockSettingsValues.isPersonalizationEnabled()).thenReturn(true); } @Override @@ -112,11 +122,33 @@ public class ImportantNoticeUtilsTests extends AndroidTestCase { ImportantNoticeUtils.getCurrentImportantNoticeVersion(getContext())); } + public void testStateAfterFreshInstall() { + mImportantNoticePreferences.clear(); + + // Check internal state of {@link ImportantNoticeUtils.shouldShowImportantNotice(Context)} + // after fresh install. + assertEquals("Has new important notice after fresh install", true, + ImportantNoticeUtils.hasNewImportantNotice(getContext())); + assertEquals("Next important notice title after fresh install", false, TextUtils.isEmpty( + ImportantNoticeUtils.getNextImportantNoticeTitle(getContext()))); + assertEquals("Is in system setup wizard after fresh install", false, + ImportantNoticeUtils.isInSystemSetupWizard(getContext())); + final long currentTimeMillis = System.currentTimeMillis(); + assertEquals("Has timeout passed after fresh install", false, + ImportantNoticeUtils.hasTimeoutPassed(getContext(), currentTimeMillis)); + assertEquals("Timestamp of first important notice after fresh install", + (Long)currentTimeMillis, + mImportantNoticePreferences.getLong(KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE)); + + assertEquals("Current boolean before update", true, + ImportantNoticeUtils.shouldShowImportantNotice(getContext(), mMockSettingsValues)); + } + public void testUpdateVersion() { mImportantNoticePreferences.clear(); assertEquals("Current boolean before update", true, - ImportantNoticeUtils.shouldShowImportantNotice(getContext())); + ImportantNoticeUtils.shouldShowImportantNotice(getContext(), mMockSettingsValues)); assertEquals("Last version before update", 0, ImportantNoticeUtils.getLastImportantNoticeVersion(getContext())); assertEquals("Next version before update ", 1, @@ -129,7 +161,7 @@ public class ImportantNoticeUtilsTests extends AndroidTestCase { ImportantNoticeUtils.updateLastImportantNoticeVersion(getContext()); assertEquals("Current boolean after update", false, - ImportantNoticeUtils.shouldShowImportantNotice(getContext())); + ImportantNoticeUtils.shouldShowImportantNotice(getContext(), mMockSettingsValues)); assertEquals("Last version after update", 1, ImportantNoticeUtils.getLastImportantNoticeVersion(getContext())); assertEquals("Next version after update", 2, @@ -158,12 +190,12 @@ public class ImportantNoticeUtilsTests extends AndroidTestCase { // Call {@link ImportantNoticeUtils#shouldShowImportantNotice(Context)} before timeout. assertEquals("Current boolean before timeout 1", true, - ImportantNoticeUtils.shouldShowImportantNotice(getContext())); + ImportantNoticeUtils.shouldShowImportantNotice(getContext(), mMockSettingsValues)); assertEquals("Last version before timeout 1", 0, ImportantNoticeUtils.getLastImportantNoticeVersion(getContext())); assertEquals("Next version before timeout 1", 1, ImportantNoticeUtils.getNextImportantNoticeVersion(getContext())); - assertEquals("Last time before timeout 1", (Long)lastTime, + assertEquals("Timestamp of first important notice before timeout 1", (Long)lastTime, mImportantNoticePreferences.getLong(KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE)); assertEquals("Current title before timeout 1", false, TextUtils.isEmpty( ImportantNoticeUtils.getNextImportantNoticeTitle(getContext()))); @@ -175,12 +207,12 @@ public class ImportantNoticeUtilsTests extends AndroidTestCase { // Call {@link ImportantNoticeUtils#shouldShowImportantNotice(Context)} before timeout // again. assertEquals("Current boolean before timeout 2", true, - ImportantNoticeUtils.shouldShowImportantNotice(getContext())); + ImportantNoticeUtils.shouldShowImportantNotice(getContext(), mMockSettingsValues)); assertEquals("Last version before timeout 2", 0, ImportantNoticeUtils.getLastImportantNoticeVersion(getContext())); assertEquals("Next version before timeout 2", 1, ImportantNoticeUtils.getNextImportantNoticeVersion(getContext())); - assertEquals("Last time before timeout 2", (Long)lastTime, + assertEquals("Timestamp of first important notice before timeout 2", (Long)lastTime, mImportantNoticePreferences.getLong(KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE)); assertEquals("Current title before timeout 2", false, TextUtils.isEmpty( ImportantNoticeUtils.getNextImportantNoticeTitle(getContext()))); @@ -191,12 +223,12 @@ public class ImportantNoticeUtilsTests extends AndroidTestCase { // Call {@link ImportantNoticeUtils#shouldShowImportantNotice(Context)} after timeout. assertEquals("Current boolean after timeout 1", false, - ImportantNoticeUtils.shouldShowImportantNotice(getContext())); + ImportantNoticeUtils.shouldShowImportantNotice(getContext(), mMockSettingsValues)); assertEquals("Last version after timeout 1", 1, ImportantNoticeUtils.getLastImportantNoticeVersion(getContext())); assertEquals("Next version after timeout 1", 2, ImportantNoticeUtils.getNextImportantNoticeVersion(getContext())); - assertEquals("Last time aflter timeout 1", null, + assertEquals("Timestamp of first important notice after timeout 1", null, mImportantNoticePreferences.getLong(KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE)); assertEquals("Current title after timeout 1", true, TextUtils.isEmpty( ImportantNoticeUtils.getNextImportantNoticeTitle(getContext()))); @@ -207,16 +239,30 @@ public class ImportantNoticeUtilsTests extends AndroidTestCase { // Call {@link ImportantNoticeUtils#shouldShowImportantNotice(Context)} after timeout again. assertEquals("Current boolean after timeout 2", false, - ImportantNoticeUtils.shouldShowImportantNotice(getContext())); + ImportantNoticeUtils.shouldShowImportantNotice(getContext(), mMockSettingsValues)); assertEquals("Last version after timeout 2", 1, ImportantNoticeUtils.getLastImportantNoticeVersion(getContext())); assertEquals("Next version after timeout 2", 2, ImportantNoticeUtils.getNextImportantNoticeVersion(getContext())); - assertEquals("Last time aflter timeout 2", null, + assertEquals("Timestamp of first important notice after timeout 2", null, mImportantNoticePreferences.getLong(KEY_TIMESTAMP_OF_FIRST_IMPORTANT_NOTICE)); assertEquals("Current title after timeout 2", true, TextUtils.isEmpty( ImportantNoticeUtils.getNextImportantNoticeTitle(getContext()))); assertEquals("Current contents after timeout 2", true, TextUtils.isEmpty( ImportantNoticeUtils.getNextImportantNoticeContents(getContext()))); } + + public void testPersonalizationSetting() { + mImportantNoticePreferences.clear(); + + // Personalization enabled. + when(mMockSettingsValues.isPersonalizationEnabled()).thenReturn(true); + assertEquals("Current boolean with personalization enabled", true, + ImportantNoticeUtils.shouldShowImportantNotice(getContext(), mMockSettingsValues)); + + // Personalization disabled. + when(mMockSettingsValues.isPersonalizationEnabled()).thenReturn(false); + assertEquals("Current boolean with personalization disabled", false, + ImportantNoticeUtils.shouldShowImportantNotice(getContext(), mMockSettingsValues)); + } } diff --git a/tests/src/com/android/inputmethod/latin/utils/JsonUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/JsonUtilsTests.java new file mode 100644 index 000000000..194112070 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/utils/JsonUtilsTests.java @@ -0,0 +1,36 @@ +/* + * 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.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + +import java.util.Arrays; +import java.util.List; + +@SmallTest +public class JsonUtilsTests extends AndroidTestCase { + public void testJsonUtils() { + final Object[] objs = new Object[] { 1, "aaa", "bbb", 3 }; + final List<Object> objArray = Arrays.asList(objs); + 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/LanguageOnSpacebarUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/LanguageOnSpacebarUtilsTests.java new file mode 100644 index 000000000..e4b6a668c --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/utils/LanguageOnSpacebarUtilsTests.java @@ -0,0 +1,215 @@ +/* + * 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 static com.android.inputmethod.latin.utils.LanguageOnSpacebarUtils.FORMAT_TYPE_FULL_LOCALE; +import static com.android.inputmethod.latin.utils.LanguageOnSpacebarUtils.FORMAT_TYPE_LANGUAGE_ONLY; +import static com.android.inputmethod.latin.utils.LanguageOnSpacebarUtils.FORMAT_TYPE_NONE; + +import android.content.Context; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.latin.RichInputMethodManager; +import com.android.inputmethod.latin.RichInputMethodSubtype; +import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; +import com.android.inputmethod.latin.utils.LanguageOnSpacebarUtils; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; + +import java.util.ArrayList; +import java.util.Locale; + +import javax.annotation.Nonnull; + +@SmallTest +public class LanguageOnSpacebarUtilsTests extends AndroidTestCase { + private RichInputMethodManager mRichImm; + + RichInputMethodSubtype EN_US_QWERTY; + RichInputMethodSubtype EN_GB_QWERTY; + RichInputMethodSubtype FR_AZERTY; + RichInputMethodSubtype FR_CA_QWERTY; + RichInputMethodSubtype FR_CH_SWISS; + RichInputMethodSubtype FR_CH_QWERTY; + RichInputMethodSubtype FR_CH_QWERTZ; + RichInputMethodSubtype IW_HEBREW; + RichInputMethodSubtype ZZ_QWERTY; + + @Override + protected void setUp() throws Exception { + super.setUp(); + final Context context = getContext(); + RichInputMethodManager.init(context); + mRichImm = RichInputMethodManager.getInstance(); + + EN_US_QWERTY = findSubtypeOf(Locale.US.toString(), "qwerty"); + EN_GB_QWERTY = findSubtypeOf(Locale.UK.toString(), "qwerty"); + FR_AZERTY = findSubtypeOf(Locale.FRENCH.toString(), "azerty"); + FR_CA_QWERTY = findSubtypeOf(Locale.CANADA_FRENCH.toString(), "qwerty"); + FR_CH_SWISS = findSubtypeOf("fr_CH", "swiss"); + FR_CH_QWERTZ = new RichInputMethodSubtype( + AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype("fr_CH", "qwertz")); + FR_CH_QWERTY = new RichInputMethodSubtype( + AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype("fr_CH", "qwerty")); + IW_HEBREW = findSubtypeOf("iw", "hebrew"); + ZZ_QWERTY = findSubtypeOf(SubtypeLocaleUtils.NO_LANGUAGE, "qwerty"); + } + + @Nonnull + private RichInputMethodSubtype findSubtypeOf(final String localeString, + final String keyboardLayoutSetName) { + final InputMethodSubtype subtype = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + localeString, keyboardLayoutSetName); + if (subtype == null) { + throw new RuntimeException("Can't find subtype of " + localeString + " with " + + keyboardLayoutSetName); + } + return new RichInputMethodSubtype(subtype); + } + + private static void enableSubtypes(final RichInputMethodSubtype ... subtypes) { + final ArrayList<InputMethodSubtype> enabledSubtypes = new ArrayList<>(); + for (final RichInputMethodSubtype subtype : subtypes) { + enabledSubtypes.add(subtype.getRawSubtype()); + } + LanguageOnSpacebarUtils.setEnabledSubtypes(enabledSubtypes); + } + + private static void assertFormatType(final RichInputMethodSubtype subtype, + final boolean implicitlyEnabledSubtype, final Locale systemLocale, + final int expectedFormat) { + LanguageOnSpacebarUtils.onSubtypeChanged(subtype, implicitlyEnabledSubtype, systemLocale); + assertEquals(subtype.getLocale() + " implicitly=" + implicitlyEnabledSubtype + + " in " + systemLocale, expectedFormat, + LanguageOnSpacebarUtils.getLanguageOnSpacebarFormatType(subtype)); + } + + public void testOneSubtypeImplicitlyEnabled() { + enableSubtypes(EN_US_QWERTY); + assertFormatType(EN_US_QWERTY, true, Locale.US, FORMAT_TYPE_NONE); + + enableSubtypes(EN_GB_QWERTY); + assertFormatType(EN_GB_QWERTY, true, Locale.UK, FORMAT_TYPE_NONE); + + enableSubtypes(FR_AZERTY); + assertFormatType(FR_AZERTY, true, Locale.FRANCE, FORMAT_TYPE_NONE); + + enableSubtypes(FR_CA_QWERTY); + assertFormatType(FR_CA_QWERTY, true, Locale.CANADA_FRENCH, FORMAT_TYPE_NONE); + } + + public void testOneSubtypeExplicitlyEnabled() { + enableSubtypes(EN_US_QWERTY); + assertFormatType(EN_US_QWERTY, false, Locale.UK, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(EN_US_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); + + enableSubtypes(EN_GB_QWERTY); + assertFormatType(EN_GB_QWERTY, false, Locale.US, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(EN_GB_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); + + enableSubtypes(FR_AZERTY); + assertFormatType(FR_AZERTY, false, Locale.US, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_AZERTY, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); + + enableSubtypes(FR_CA_QWERTY); + assertFormatType(FR_CA_QWERTY, false, Locale.US, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CA_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); + } + + public void testOneSubtypeImplicitlyEnabledWithNoLanguageSubtype() { + final Locale Locale_IW = new Locale("iw"); + enableSubtypes(IW_HEBREW, ZZ_QWERTY); + // TODO: Should this be FORMAT_TYPE_NONE? + assertFormatType(IW_HEBREW, true, Locale_IW, FORMAT_TYPE_LANGUAGE_ONLY); + // TODO: Should this be FORMAT_TYPE_NONE? + assertFormatType(ZZ_QWERTY, true, Locale_IW, FORMAT_TYPE_FULL_LOCALE); + } + + public void testTwoSubtypesExplicitlyEnabled() { + enableSubtypes(EN_US_QWERTY, FR_AZERTY); + assertFormatType(EN_US_QWERTY, false, Locale.US, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_AZERTY, false, Locale.US, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(EN_US_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_AZERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(EN_US_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_AZERTY, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); + + enableSubtypes(EN_US_QWERTY, ZZ_QWERTY); + assertFormatType(EN_US_QWERTY, false, Locale.US, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(ZZ_QWERTY, false, Locale.US, FORMAT_TYPE_FULL_LOCALE); + assertFormatType(EN_US_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(ZZ_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_FULL_LOCALE); + + } + + public void testMultiSubtypeWithSameLanuageAndSameLayout() { + // Explicitly enable en_US, en_GB, fr_FR, and no language keyboards. + enableSubtypes(EN_US_QWERTY, EN_GB_QWERTY, FR_CA_QWERTY, ZZ_QWERTY); + + assertFormatType(EN_US_QWERTY, false, Locale.US, FORMAT_TYPE_FULL_LOCALE); + assertFormatType(EN_GB_QWERTY, false, Locale.US, FORMAT_TYPE_FULL_LOCALE); + assertFormatType(FR_CA_QWERTY, false, Locale.US, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(ZZ_QWERTY, false, Locale.US, FORMAT_TYPE_FULL_LOCALE); + + assertFormatType(EN_US_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_FULL_LOCALE); + assertFormatType(EN_GB_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_FULL_LOCALE); + assertFormatType(FR_CA_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(ZZ_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_FULL_LOCALE); + } + + public void testMultiSubtypesWithSameLanguageButHaveDifferentLayout() { + enableSubtypes(FR_AZERTY, FR_CA_QWERTY, FR_CH_SWISS, FR_CH_QWERTZ); + + assertFormatType(FR_AZERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CA_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CH_SWISS, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CH_QWERTZ, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); + + assertFormatType(FR_AZERTY, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CA_QWERTY, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CH_SWISS, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CH_QWERTZ, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); + + assertFormatType(FR_AZERTY, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CA_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CH_SWISS, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CH_QWERTZ, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); + } + + public void testMultiSubtypesWithSameLanguageAndMayHaveSameLayout() { + enableSubtypes(FR_AZERTY, FR_CA_QWERTY, FR_CH_SWISS, FR_CH_QWERTY, FR_CH_QWERTZ); + + assertFormatType(FR_AZERTY, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CA_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_FULL_LOCALE); + assertFormatType(FR_CH_SWISS, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CH_QWERTY, false, Locale.FRANCE, FORMAT_TYPE_FULL_LOCALE); + assertFormatType(FR_CH_QWERTZ, false, Locale.FRANCE, FORMAT_TYPE_LANGUAGE_ONLY); + + assertFormatType(FR_AZERTY, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CA_QWERTY, false, Locale.CANADA_FRENCH, FORMAT_TYPE_FULL_LOCALE); + assertFormatType(FR_CH_SWISS, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CH_QWERTY, false, Locale.CANADA_FRENCH, FORMAT_TYPE_FULL_LOCALE); + assertFormatType(FR_CH_QWERTZ, false, Locale.CANADA_FRENCH, FORMAT_TYPE_LANGUAGE_ONLY); + + assertFormatType(FR_AZERTY, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CA_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_FULL_LOCALE); + assertFormatType(FR_CH_SWISS, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); + assertFormatType(FR_CH_QWERTY, false, Locale.JAPAN, FORMAT_TYPE_FULL_LOCALE); + assertFormatType(FR_CH_QWERTZ, false, Locale.JAPAN, FORMAT_TYPE_LANGUAGE_ONLY); + } +} diff --git a/tests/src/com/android/inputmethod/latin/utils/RecapitalizeStatusTests.java b/tests/src/com/android/inputmethod/latin/utils/RecapitalizeStatusTests.java index a3f2ce586..9b826839f 100644 --- a/tests/src/com/android/inputmethod/latin/utils/RecapitalizeStatusTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/RecapitalizeStatusTests.java @@ -19,7 +19,7 @@ package com.android.inputmethod.latin.utils; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; -import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.common.Constants; import java.util.Locale; diff --git a/tests/src/com/android/inputmethod/latin/utils/SpacebarLanguagetUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/SpacebarLanguagetUtilsTests.java deleted file mode 100644 index fdde34251..000000000 --- a/tests/src/com/android/inputmethod/latin/utils/SpacebarLanguagetUtilsTests.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (C) 2011 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.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.RichInputMethodManager; - -import java.util.ArrayList; -import java.util.Locale; - -@SmallTest -public class SpacebarLanguagetUtilsTests extends AndroidTestCase { - // All input method subtypes of LatinIME. - private final ArrayList<InputMethodSubtype> mSubtypesList = new ArrayList<>(); - - private RichInputMethodManager mRichImm; - private Resources mRes; - - InputMethodSubtype EN_US; - InputMethodSubtype EN_GB; - InputMethodSubtype ES_US; - InputMethodSubtype FR; - InputMethodSubtype FR_CA; - InputMethodSubtype FR_CH; - InputMethodSubtype DE; - InputMethodSubtype DE_CH; - InputMethodSubtype ZZ; - InputMethodSubtype DE_QWERTY; - InputMethodSubtype FR_QWERTZ; - InputMethodSubtype EN_US_AZERTY; - InputMethodSubtype EN_UK_DVORAK; - InputMethodSubtype ES_US_COLEMAK; - InputMethodSubtype ZZ_AZERTY; - InputMethodSubtype ZZ_PC; - - @Override - protected void setUp() throws Exception { - super.setUp(); - final Context context = getContext(); - RichInputMethodManager.init(context); - mRichImm = RichInputMethodManager.getInstance(); - 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( - Locale.UK.toString(), "qwerty"); - ES_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( - "es_US", "spanish"); - FR = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( - 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.createAsciiEmojiCapableAdditionalSubtype( - Locale.GERMAN.toString(), "qwerty"); - FR_QWERTZ = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( - Locale.FRENCH.toString(), "qwertz"); - EN_US_AZERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( - Locale.US.toString(), "azerty"); - EN_UK_DVORAK = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( - Locale.UK.toString(), "dvorak"); - ES_US_COLEMAK = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( - "es_US", "colemak"); - ZZ_AZERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( - SubtypeLocaleUtils.NO_LANGUAGE, "azerty"); - ZZ_PC = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( - SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty"); - } - - public void testAllFullDisplayNameForSpacebar() { - for (final InputMethodSubtype subtype : mSubtypesList) { - final String subtypeName = SubtypeLocaleUtils - .getSubtypeDisplayNameInSystemLocale(subtype); - final String spacebarText = SpacebarLanguageUtils.getFullDisplayName(subtype); - final String languageName = SubtypeLocaleUtils - .getSubtypeLocaleDisplayName(subtype.getLocale()); - if (SubtypeLocaleUtils.isNoLanguage(subtype)) { - assertFalse(subtypeName, spacebarText.contains(languageName)); - } else { - assertTrue(subtypeName, spacebarText.contains(languageName)); - } - } - } - - public void testAllMiddleDisplayNameForSpacebar() { - for (final InputMethodSubtype subtype : mSubtypesList) { - final String subtypeName = SubtypeLocaleUtils - .getSubtypeDisplayNameInSystemLocale(subtype); - final String spacebarText = SpacebarLanguageUtils.getMiddleDisplayName(subtype); - if (SubtypeLocaleUtils.isNoLanguage(subtype)) { - assertEquals(subtypeName, - SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype), spacebarText); - } else { - final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype); - assertEquals(subtypeName, - SubtypeLocaleUtils.getSubtypeLocaleDisplayName(locale.getLanguage()), - spacebarText); - } - } - } - - // InputMethodSubtype's display name for spacebar text in its locale. - // isAdditionalSubtype (T=true, F=false) - // locale layout | Middle Full - // ------ ------- - --------- ---------------------- - // en_US qwerty F English English (US) exception - // en_GB qwerty F English English (UK) exception - // es_US spanish F Español Español (EE.UU.) exception - // fr azerty F Français Français - // fr_CA qwerty F Français Français (Canada) - // fr_CH swiss F Français Français (Suisse) - // de qwertz F Deutsch Deutsch - // de_CH swiss F Deutsch Deutsch (Schweiz) - // zz qwerty F QWERTY QWERTY - // fr qwertz T Français Français - // de qwerty T Deutsch Deutsch - // en_US azerty T English English (US) - // zz azerty T AZERTY AZERTY - - private final RunInLocale<Void> testsPredefinedSubtypesForSpacebar = new RunInLocale<Void>() { - @Override - protected Void job(final Resources res) { - assertEquals("en_US", "English (US)", - SpacebarLanguageUtils.getFullDisplayName(EN_US)); - assertEquals("en_GB", "English (UK)", - SpacebarLanguageUtils.getFullDisplayName(EN_GB)); - assertEquals("es_US", "Español (EE.UU.)", - SpacebarLanguageUtils.getFullDisplayName(ES_US)); - assertEquals("fr", "Français", - SpacebarLanguageUtils.getFullDisplayName(FR)); - assertEquals("fr_CA", "Français (Canada)", - SpacebarLanguageUtils.getFullDisplayName(FR_CA)); - assertEquals("fr_CH", "Français (Suisse)", - SpacebarLanguageUtils.getFullDisplayName(FR_CH)); - assertEquals("de", "Deutsch", - SpacebarLanguageUtils.getFullDisplayName(DE)); - assertEquals("de_CH", "Deutsch (Schweiz)", - SpacebarLanguageUtils.getFullDisplayName(DE_CH)); - assertEquals("zz", "QWERTY", - SpacebarLanguageUtils.getFullDisplayName(ZZ)); - - assertEquals("en_US", "English", - SpacebarLanguageUtils.getMiddleDisplayName(EN_US)); - assertEquals("en_GB", "English", - SpacebarLanguageUtils.getMiddleDisplayName(EN_GB)); - assertEquals("es_US", "Español", - SpacebarLanguageUtils.getMiddleDisplayName(ES_US)); - assertEquals("fr", "Français", - SpacebarLanguageUtils.getMiddleDisplayName(FR)); - assertEquals("fr_CA", "Français", - SpacebarLanguageUtils.getMiddleDisplayName(FR_CA)); - assertEquals("fr_CH", "Français", - SpacebarLanguageUtils.getMiddleDisplayName(FR_CH)); - assertEquals("de", "Deutsch", - SpacebarLanguageUtils.getMiddleDisplayName(DE)); - assertEquals("de_CH", "Deutsch", - SpacebarLanguageUtils.getMiddleDisplayName(DE_CH)); - assertEquals("zz", "QWERTY", - SpacebarLanguageUtils.getMiddleDisplayName(ZZ)); - return null; - } - }; - - private final RunInLocale<Void> testsAdditionalSubtypesForSpacebar = new RunInLocale<Void>() { - @Override - protected Void job(final Resources res) { - assertEquals("fr qwertz", "Français", - SpacebarLanguageUtils.getFullDisplayName(FR_QWERTZ)); - assertEquals("de qwerty", "Deutsch", - SpacebarLanguageUtils.getFullDisplayName(DE_QWERTY)); - assertEquals("en_US azerty", "English (US)", - SpacebarLanguageUtils.getFullDisplayName(EN_US_AZERTY)); - assertEquals("en_UK dvorak", "English (UK)", - SpacebarLanguageUtils.getFullDisplayName(EN_UK_DVORAK)); - assertEquals("es_US colemak", "Español (EE.UU.)", - SpacebarLanguageUtils.getFullDisplayName(ES_US_COLEMAK)); - assertEquals("zz azerty", "AZERTY", - SpacebarLanguageUtils.getFullDisplayName(ZZ_AZERTY)); - assertEquals("zz pc", "PC", - SpacebarLanguageUtils.getFullDisplayName(ZZ_PC)); - - assertEquals("fr qwertz", "Français", - SpacebarLanguageUtils.getMiddleDisplayName(FR_QWERTZ)); - assertEquals("de qwerty", "Deutsch", - SpacebarLanguageUtils.getMiddleDisplayName(DE_QWERTY)); - assertEquals("en_US azerty", "English", - SpacebarLanguageUtils.getMiddleDisplayName(EN_US_AZERTY)); - assertEquals("en_UK dvorak", "English", - SpacebarLanguageUtils.getMiddleDisplayName(EN_UK_DVORAK)); - assertEquals("es_US colemak", "Español", - SpacebarLanguageUtils.getMiddleDisplayName(ES_US_COLEMAK)); - assertEquals("zz azerty", "AZERTY", - SpacebarLanguageUtils.getMiddleDisplayName(ZZ_AZERTY)); - assertEquals("zz pc", "PC", - SpacebarLanguageUtils.getMiddleDisplayName(ZZ_PC)); - return null; - } - }; - - public void testPredefinedSubtypesForSpacebarInEnglish() { - testsPredefinedSubtypesForSpacebar.runInLocale(mRes, Locale.ENGLISH); - } - - public void testAdditionalSubtypeForSpacebarInEnglish() { - testsAdditionalSubtypesForSpacebar.runInLocale(mRes, Locale.ENGLISH); - } - - public void testPredefinedSubtypesForSpacebarInFrench() { - testsPredefinedSubtypesForSpacebar.runInLocale(mRes, Locale.FRENCH); - } - - public void testAdditionalSubtypeForSpacebarInFrench() { - testsAdditionalSubtypesForSpacebar.runInLocale(mRes, Locale.FRENCH); - } -} diff --git a/tests/src/com/android/inputmethod/latin/utils/SpannableStringUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/SpannableStringUtilsTests.java index fa6ad16c1..665d81ccd 100644 --- a/tests/src/com/android/inputmethod/latin/utils/SpannableStringUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/SpannableStringUtilsTests.java @@ -20,9 +20,10 @@ import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; import android.text.style.SuggestionSpan; import android.text.style.URLSpan; +import android.text.SpannableString; import android.text.SpannableStringBuilder; -import android.text.Spannable; import android.text.Spanned; +import android.text.SpannedString; @SmallTest public class SpannableStringUtilsTests extends AndroidTestCase { @@ -34,8 +35,8 @@ public class SpannableStringUtilsTests extends AndroidTestCase { for (int i = 0; i < N; ++i) { // Put a PARAGRAPH-flagged span that should not be found in the result. s.setSpan(new SuggestionSpan(getContext(), - new String[] {"" + i}, Spannable.SPAN_PARAGRAPH), - i * 12, i * 12 + 12, Spannable.SPAN_PARAGRAPH); + new String[] {"" + i}, Spanned.SPAN_PARAGRAPH), + i * 12, i * 12 + 12, Spanned.SPAN_PARAGRAPH); // Put a normal suggestion span that should be found in the result. s.setSpan(new SuggestionSpan(getContext(), new String[] {"" + i}, 0), i, i * 2, 0); // Put a URL span than should not be found in the result. @@ -51,8 +52,175 @@ public class SpannableStringUtilsTests extends AndroidTestCase { for (int i = 0; i < spans.length; i++) { final int flags = result.getSpanFlags(spans[i]); assertEquals("Should not find a span with PARAGRAPH flag", - flags & Spannable.SPAN_PARAGRAPH, 0); + flags & Spanned.SPAN_PARAGRAPH, 0); assertTrue("Should be a SuggestionSpan", spans[i] instanceof SuggestionSpan); } } + + private static void assertSpanCount(final int expectedCount, final CharSequence cs) { + final int actualCount; + if (cs instanceof Spanned) { + final Spanned spanned = (Spanned) cs; + actualCount = spanned.getSpans(0, spanned.length(), Object.class).length; + } else { + actualCount = 0; + } + assertEquals(expectedCount, actualCount); + } + + private static void assertSpan(final CharSequence cs, final Object expectedSpan, + final int expectedStart, final int expectedEnd, final int expectedFlags) { + assertTrue(cs instanceof Spanned); + final Spanned spanned = (Spanned) cs; + final Object[] actualSpans = spanned.getSpans(0, spanned.length(), Object.class); + for (Object actualSpan : actualSpans) { + if (actualSpan == expectedSpan) { + final int actualStart = spanned.getSpanStart(actualSpan); + final int actualEnd = spanned.getSpanEnd(actualSpan); + final int actualFlags = spanned.getSpanFlags(actualSpan); + assertEquals(expectedStart, actualStart); + assertEquals(expectedEnd, actualEnd); + assertEquals(expectedFlags, actualFlags); + return; + } + } + assertTrue(false); + } + + public void testSplitCharSequenceWithSpan() { + // text: " a bcd efg hij " + // span1: ^^^^^^^ + // span2: ^^^^^ + // span3: ^ + final SpannableString spannableString = new SpannableString(" a bcd efg hij "); + final Object span1 = new Object(); + final Object span2 = new Object(); + final Object span3 = new Object(); + final int SPAN1_FLAGS = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE; + final int SPAN2_FLAGS = Spanned.SPAN_EXCLUSIVE_INCLUSIVE; + final int SPAN3_FLAGS = Spanned.SPAN_INCLUSIVE_INCLUSIVE; + spannableString.setSpan(span1, 0, 7, SPAN1_FLAGS); + spannableString.setSpan(span2, 0, 5, SPAN2_FLAGS); + spannableString.setSpan(span3, 12, 13, SPAN3_FLAGS); + final CharSequence[] charSequencesFromSpanned = SpannableStringUtils.split( + spannableString, " ", true /* preserveTrailingEmptySegmengs */); + final CharSequence[] charSequencesFromString = SpannableStringUtils.split( + spannableString.toString(), " ", true /* preserveTrailingEmptySegmengs */); + + + assertEquals(7, charSequencesFromString.length); + assertEquals(7, charSequencesFromSpanned.length); + + // text: "" + // span1: ^ + // span2: ^ + // span3: + assertEquals("", charSequencesFromString[0].toString()); + assertSpanCount(0, charSequencesFromString[0]); + assertEquals("", charSequencesFromSpanned[0].toString()); + assertSpanCount(2, charSequencesFromSpanned[0]); + assertSpan(charSequencesFromSpanned[0], span1, 0, 0, SPAN1_FLAGS); + assertSpan(charSequencesFromSpanned[0], span2, 0, 0, SPAN2_FLAGS); + + // text: "a" + // span1: ^ + // span2: ^ + // span3: + assertEquals("a", charSequencesFromString[1].toString()); + assertSpanCount(0, charSequencesFromString[1]); + assertEquals("a", charSequencesFromSpanned[1].toString()); + assertSpanCount(2, charSequencesFromSpanned[1]); + assertSpan(charSequencesFromSpanned[1], span1, 0, 1, SPAN1_FLAGS); + assertSpan(charSequencesFromSpanned[1], span2, 0, 1, SPAN2_FLAGS); + + // text: "bcd" + // span1: ^^^ + // span2: ^^ + // span3: + assertEquals("bcd", charSequencesFromString[2].toString()); + assertSpanCount(0, charSequencesFromString[2]); + assertEquals("bcd", charSequencesFromSpanned[2].toString()); + assertSpanCount(2, charSequencesFromSpanned[2]); + assertSpan(charSequencesFromSpanned[2], span1, 0, 3, SPAN1_FLAGS); + assertSpan(charSequencesFromSpanned[2], span2, 0, 2, SPAN2_FLAGS); + + // text: "efg" + // span1: + // span2: + // span3: + assertEquals("efg", charSequencesFromString[3].toString()); + assertSpanCount(0, charSequencesFromString[3]); + assertEquals("efg", charSequencesFromSpanned[3].toString()); + assertSpanCount(0, charSequencesFromSpanned[3]); + + // text: "hij" + // span1: + // span2: + // span3: ^ + assertEquals("hij", charSequencesFromString[4].toString()); + assertSpanCount(0, charSequencesFromString[4]); + assertEquals("hij", charSequencesFromSpanned[4].toString()); + assertSpanCount(1, charSequencesFromSpanned[4]); + assertSpan(charSequencesFromSpanned[4], span3, 1, 2, SPAN3_FLAGS); + + // text: "" + // span1: + // span2: + // span3: + assertEquals("", charSequencesFromString[5].toString()); + assertSpanCount(0, charSequencesFromString[5]); + assertEquals("", charSequencesFromSpanned[5].toString()); + assertSpanCount(0, charSequencesFromSpanned[5]); + + // text: "" + // span1: + // span2: + // span3: + assertEquals("", charSequencesFromString[6].toString()); + assertSpanCount(0, charSequencesFromString[6]); + assertEquals("", charSequencesFromSpanned[6].toString()); + assertSpanCount(0, charSequencesFromSpanned[6]); + } + + public void testSplitCharSequencePreserveTrailingEmptySegmengs() { + assertEquals(1, SpannableStringUtils.split("", " ", + false /* preserveTrailingEmptySegmengs */).length); + assertEquals(1, SpannableStringUtils.split(new SpannedString(""), " ", + false /* preserveTrailingEmptySegmengs */).length); + + assertEquals(1, SpannableStringUtils.split("", " ", + true /* preserveTrailingEmptySegmengs */).length); + assertEquals(1, SpannableStringUtils.split(new SpannedString(""), " ", + true /* preserveTrailingEmptySegmengs */).length); + + assertEquals(0, SpannableStringUtils.split(" ", " ", + false /* preserveTrailingEmptySegmengs */).length); + assertEquals(0, SpannableStringUtils.split(new SpannedString(" "), " ", + false /* preserveTrailingEmptySegmengs */).length); + + assertEquals(2, SpannableStringUtils.split(" ", " ", + true /* preserveTrailingEmptySegmengs */).length); + assertEquals(2, SpannableStringUtils.split(new SpannedString(" "), " ", + true /* preserveTrailingEmptySegmengs */).length); + + assertEquals(3, SpannableStringUtils.split("a b c ", " ", + false /* preserveTrailingEmptySegmengs */).length); + assertEquals(3, SpannableStringUtils.split(new SpannedString("a b c "), " ", + false /* preserveTrailingEmptySegmengs */).length); + + assertEquals(5, SpannableStringUtils.split("a b c ", " ", + true /* preserveTrailingEmptySegmengs */).length); + assertEquals(5, SpannableStringUtils.split(new SpannedString("a b c "), " ", + true /* preserveTrailingEmptySegmengs */).length); + + assertEquals(6, SpannableStringUtils.split("a b ", " ", + false /* preserveTrailingEmptySegmengs */).length); + assertEquals(6, SpannableStringUtils.split(new SpannedString("a b "), " ", + false /* preserveTrailingEmptySegmengs */).length); + + assertEquals(7, SpannableStringUtils.split("a b ", " ", + true /* preserveTrailingEmptySegmengs */).length); + assertEquals(7, SpannableStringUtils.split(new SpannedString("a b "), " ", + true /* preserveTrailingEmptySegmengs */).length); + } } diff --git a/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java deleted file mode 100644 index ba2e99802..000000000 --- a/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * 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.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.utils.StringUtils; - -import java.util.Locale; - -@SmallTest -public class StringUtilsTests extends AndroidTestCase { - private static final Locale US = Locale.US; - private static final Locale GERMAN = Locale.GERMAN; - private static final Locale TURKEY = new Locale("tr", "TR"); - private static final Locale GREECE = new Locale("el", "GR"); - - private static void assert_toUpperCaseOfStringForLocale(final Locale locale, - final String lowerCase, final String expected) { - assertEquals(lowerCase + " in " + locale, expected, - StringUtils.toUpperCaseOfStringForLocale( - lowerCase, true /* needsToUpperCase */, locale)); - } - - public void test_toUpperCaseOfStringForLocale() { - assert_toUpperCaseOfStringForLocale(US, null, null); - assert_toUpperCaseOfStringForLocale(US, "", ""); - assert_toUpperCaseOfStringForLocale(US, "aeiou", "AEIOU"); - // U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE - // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE - // U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX - // U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS - // U+016B: "ū" LATIN SMALL LETTER U WITH MACRON - // U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE - // U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA - // U+00C0: "À" LATIN CAPITAL LETTER A WITH GRAVE - // U+00C8: "È" LATIN CAPITAL LETTER E WITH GRAVE - // U+00CE: "Î" LATIN CAPITAL LETTER I WITH CIRCUMFLEX - // U+00D6: "Ö" LATIN CAPITAL LETTER O WITH DIAERESIS - // U+016A: "Ū" LATIN CAPITAL LETTER U WITH MACRON - // U+00D1: "Ñ" LATIN CAPITAL LETTER N WITH TILDE - // U+00C7: "Ç" LATIN CAPITAL LETTER C WITH CEDILLA - assert_toUpperCaseOfStringForLocale(US, - "\u00E0\u00E8\u00EE\u00F6\u016B\u00F1\u00E7", - "\u00C0\u00C8\u00CE\u00D6\u016A\u00D1\u00C7"); - // U+00DF: "ß" LATIN SMALL LETTER SHARP S - // U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE - // U+0161: "š" LATIN SMALL LETTER S WITH CARON - // U+015A: "Ś" LATIN CAPITAL LETTER S WITH ACUTE - // U+0160: "Š" LATIN CAPITAL LETTER S WITH CARONZ - assert_toUpperCaseOfStringForLocale(GERMAN, - "\u00DF\u015B\u0161", - "SS\u015A\u0160"); - // U+0259: "ə" LATIN SMALL LETTER SCHWA - // U+0069: "i" LATIN SMALL LETTER I - // U+0131: "ı" LATIN SMALL LETTER DOTLESS I - // U+018F: "Ə" LATIN SMALL LETTER SCHWA - // U+0130: "İ" LATIN SMALL LETTER I WITH DOT ABOVE - // U+0049: "I" LATIN SMALL LETTER I - assert_toUpperCaseOfStringForLocale(TURKEY, - "\u0259\u0069\u0131", - "\u018F\u0130\u0049"); - // U+03C3: "σ" GREEK SMALL LETTER SIGMA - // U+03C2: "ς" GREEK SMALL LETTER FINAL SIGMA - // U+03A3: "Σ" GREEK CAPITAL LETTER SIGMA - assert_toUpperCaseOfStringForLocale(GREECE, - "\u03C3\u03C2", - "\u03A3\u03A3"); - // U+03AC: "ά" GREEK SMALL LETTER ALPHA WITH TONOS - // U+03AD: "έ" GREEK SMALL LETTER EPSILON WITH TONOS - // U+03AE: "ή" GREEK SMALL LETTER ETA WITH TONOS - // U+03AF: "ί" GREEK SMALL LETTER IOTA WITH TONOS - // U+03CC: "ό" GREEK SMALL LETTER OMICRON WITH TONOS - // U+03CD: "ύ" GREEK SMALL LETTER UPSILON WITH TONOS - // U+03CE: "ώ" GREEK SMALL LETTER OMEGA WITH TONOS - // U+0386: "Ά" GREEK CAPITAL LETTER ALPHA WITH TONOS - // U+0388: "Έ" GREEK CAPITAL LETTER EPSILON WITH TONOS - // U+0389: "Ή" GREEK CAPITAL LETTER ETA WITH TONOS - // U+038A: "Ί" GREEK CAPITAL LETTER IOTA WITH TONOS - // U+038C: "Ό" GREEK CAPITAL LETTER OMICRON WITH TONOS - // U+038E: "Ύ" GREEK CAPITAL LETTER UPSILON WITH TONOS - // U+038F: "Ώ" GREEK CAPITAL LETTER OMEGA WITH TONOS - assert_toUpperCaseOfStringForLocale(GREECE, - "\u03AC\u03AD\u03AE\u03AF\u03CC\u03CD\u03CE", - "\u0386\u0388\u0389\u038A\u038C\u038E\u038F"); - // U+03CA: "ϊ" GREEK SMALL LETTER IOTA WITH DIALYTIKA - // U+03CB: "ϋ" GREEK SMALL LETTER UPSILON WITH DIALYTIKA - // U+0390: "ΐ" GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS - // U+03B0: "ΰ" GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS - // U+03AA: "Ϊ" GREEK CAPITAL LETTER IOTA WITH DIALYTIKA - // U+03AB: "Ϋ" GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA - // U+0399: "Ι" GREEK CAPITAL LETTER IOTA - // U+03A5: "Υ" GREEK CAPITAL LETTER UPSILON - // U+0308: COMBINING DIAERESIS - // U+0301: COMBINING GRAVE ACCENT - assert_toUpperCaseOfStringForLocale(GREECE, - "\u03CA\u03CB\u0390\u03B0", - "\u03AA\u03AB\u0399\u0308\u0301\u03A5\u0308\u0301"); - } - - private static void assert_toUpperCaseOfCodeForLocale(final Locale locale, final int lowerCase, - final int expected) { - assertEquals(lowerCase + " in " + locale, expected, - StringUtils.toUpperCaseOfCodeForLocale( - lowerCase, true /* needsToUpperCase */, locale)); - } - - public void test_toUpperCaseOfCodeForLocale() { - assert_toUpperCaseOfCodeForLocale(US, Constants.CODE_ENTER, Constants.CODE_ENTER); - assert_toUpperCaseOfCodeForLocale(US, Constants.CODE_SPACE, Constants.CODE_SPACE); - assert_toUpperCaseOfCodeForLocale(US, Constants.CODE_COMMA, Constants.CODE_COMMA); - // U+0069: "i" LATIN SMALL LETTER I - // U+0131: "ı" LATIN SMALL LETTER DOTLESS I - // U+0130: "İ" LATIN SMALL LETTER I WITH DOT ABOVE - // U+0049: "I" LATIN SMALL LETTER I - assert_toUpperCaseOfCodeForLocale(US, 0x0069, 0x0049); // i -> I - assert_toUpperCaseOfCodeForLocale(US, 0x0131, 0x0049); // ı -> I - assert_toUpperCaseOfCodeForLocale(TURKEY, 0x0069, 0x0130); // i -> İ - assert_toUpperCaseOfCodeForLocale(TURKEY, 0x0131, 0x0049); // ı -> I - // U+00DF: "ß" LATIN SMALL LETTER SHARP S - // The title case of "ß" is "SS". - assert_toUpperCaseOfCodeForLocale(US, 0x00DF, Constants.CODE_UNSPECIFIED); - // U+03AC: "ά" GREEK SMALL LETTER ALPHA WITH TONOS - // U+0386: "Ά" GREEK CAPITAL LETTER ALPHA WITH TONOS - assert_toUpperCaseOfCodeForLocale(GREECE, 0x03AC, 0x0386); - // U+03CA: "ϊ" GREEK SMALL LETTER IOTA WITH DIALYTIKA - // U+03AA: "Ϊ" GREEK CAPITAL LETTER IOTA WITH DIALYTIKA - assert_toUpperCaseOfCodeForLocale(GREECE, 0x03CA, 0x03AA); - // U+03B0: "ΰ" GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS - // The title case of "ΰ" is "\u03A5\u0308\u0301". - assert_toUpperCaseOfCodeForLocale(GREECE, 0x03B0, Constants.CODE_UNSPECIFIED); - } - - private static void assert_capitalizeFirstCodePoint(final Locale locale, final String text, - final String expected) { - assertEquals(text + " in " + locale, expected, - StringUtils.capitalizeFirstCodePoint(text, locale)); - } - - public void test_capitalizeFirstCodePoint() { - assert_capitalizeFirstCodePoint(US, "", ""); - assert_capitalizeFirstCodePoint(US, "a", "A"); - assert_capitalizeFirstCodePoint(US, "à", "À"); - assert_capitalizeFirstCodePoint(US, "ß", "SS"); - assert_capitalizeFirstCodePoint(US, "text", "Text"); - assert_capitalizeFirstCodePoint(US, "iGoogle", "IGoogle"); - assert_capitalizeFirstCodePoint(TURKEY, "iyi", "İyi"); - assert_capitalizeFirstCodePoint(TURKEY, "ısırdı", "Isırdı"); - assert_capitalizeFirstCodePoint(GREECE, "ά", "Ά"); - assert_capitalizeFirstCodePoint(GREECE, "άνεση", "Άνεση"); - } - - private static void assert_capitalizeFirstAndDowncaseRest(final Locale locale, - final String text, final String expected) { - assertEquals(text + " in " + locale, expected, - StringUtils.capitalizeFirstAndDowncaseRest(text, locale)); - } - - public void test_capitalizeFirstAndDowncaseRest() { - assert_capitalizeFirstAndDowncaseRest(US, "", ""); - assert_capitalizeFirstAndDowncaseRest(US, "a", "A"); - assert_capitalizeFirstAndDowncaseRest(US, "à", "À"); - assert_capitalizeFirstAndDowncaseRest(US, "ß", "SS"); - assert_capitalizeFirstAndDowncaseRest(US, "text", "Text"); - assert_capitalizeFirstAndDowncaseRest(US, "iGoogle", "Igoogle"); - assert_capitalizeFirstAndDowncaseRest(US, "invite", "Invite"); - assert_capitalizeFirstAndDowncaseRest(US, "INVITE", "Invite"); - assert_capitalizeFirstAndDowncaseRest(TURKEY, "iyi", "İyi"); - assert_capitalizeFirstAndDowncaseRest(TURKEY, "İYİ", "İyi"); - assert_capitalizeFirstAndDowncaseRest(TURKEY, "ısırdı", "Isırdı"); - assert_capitalizeFirstAndDowncaseRest(TURKEY, "ISIRDI", "Isırdı"); - assert_capitalizeFirstAndDowncaseRest(GREECE, "ά", "Ά"); - assert_capitalizeFirstAndDowncaseRest(GREECE, "άνεση", "Άνεση"); - assert_capitalizeFirstAndDowncaseRest(GREECE, "ΆΝΕΣΗ", "Άνεση"); - } -} diff --git a/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java index ce3df7dd6..2297cacf8 100644 --- a/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java @@ -23,7 +23,9 @@ 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 com.android.inputmethod.latin.RichInputMethodSubtype; import java.util.ArrayList; import java.util.Locale; @@ -31,10 +33,11 @@ import java.util.Locale; @SmallTest public class SubtypeLocaleUtilsTests extends AndroidTestCase { // All input method subtypes of LatinIME. - private final ArrayList<InputMethodSubtype> mSubtypesList = new ArrayList<>(); + private final ArrayList<RichInputMethodSubtype> mSubtypesList = new ArrayList<>(); private RichInputMethodManager mRichImm; private Resources mRes; + private InputMethodSubtype mSavedAddtionalSubtypes[]; InputMethodSubtype EN_US; InputMethodSubtype EN_GB; @@ -44,6 +47,8 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { InputMethodSubtype FR_CH; InputMethodSubtype DE; InputMethodSubtype DE_CH; + InputMethodSubtype HI; + InputMethodSubtype SR; InputMethodSubtype ZZ; InputMethodSubtype DE_QWERTY; InputMethodSubtype FR_QWERTZ; @@ -53,20 +58,33 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { InputMethodSubtype ZZ_AZERTY; InputMethodSubtype ZZ_PC; + // These are preliminary subtypes and may not exist. + InputMethodSubtype HI_LATN; // Hinglish + InputMethodSubtype SR_LATN; // Serbian Latin + InputMethodSubtype HI_LATN_DVORAK; // Hinglis Dvorak + InputMethodSubtype SR_LATN_QWERTY; // Serbian Latin Qwerty + @Override protected void setUp() throws Exception { super.setUp(); final Context context = getContext(); + mRes = context.getResources(); RichInputMethodManager.init(context); mRichImm = RichInputMethodManager.getInstance(); - mRes = context.getResources(); - SubtypeLocaleUtils.init(context); + + // Save and reset additional subtypes + mSavedAddtionalSubtypes = mRichImm.getAdditionalSubtypes(); + final InputMethodSubtype[] predefinedAddtionalSubtypes = + AdditionalSubtypeUtils.createAdditionalSubtypesArray( + AdditionalSubtypeUtils.createPrefSubtypes( + mRes.getStringArray(R.array.predefined_subtypes))); + mRichImm.setAdditionalInputMethodSubtypes(predefinedAddtionalSubtypes); 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); + mSubtypesList.add(new RichInputMethodSubtype(subtype)); } EN_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( @@ -85,6 +103,10 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { Locale.GERMAN.toString(), "qwertz"); DE_CH = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( "de_CH", "swiss"); + HI = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + "hi", "hindi"); + SR = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + "sr", "south_slavic"); ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( SubtypeLocaleUtils.NO_LANGUAGE, "qwerty"); DE_QWERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( @@ -101,19 +123,37 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { SubtypeLocaleUtils.NO_LANGUAGE, "azerty"); ZZ_PC = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty"); + + HI_LATN = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet("hi_ZZ", "qwerty"); + if (HI_LATN != null) { + HI_LATN_DVORAK = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( + "hi_ZZ", "dvorak"); + } + SR_LATN = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet("sr_ZZ", "serbian_qwertz"); + if (SR_LATN != null) { + SR_LATN_QWERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype( + "sr_ZZ", "qwerty"); + } + } + + @Override + protected void tearDown() throws Exception { + // Restore additional subtypes. + mRichImm.setAdditionalInputMethodSubtypes(mSavedAddtionalSubtypes); + super.tearDown(); } public void testAllFullDisplayName() { - for (final InputMethodSubtype subtype : mSubtypesList) { + for (final RichInputMethodSubtype subtype : mSubtypesList) { final String subtypeName = SubtypeLocaleUtils - .getSubtypeDisplayNameInSystemLocale(subtype); - if (SubtypeLocaleUtils.isNoLanguage(subtype)) { + .getSubtypeDisplayNameInSystemLocale(subtype.getRawSubtype()); + if (subtype.isNoLanguage()) { final String layoutName = SubtypeLocaleUtils - .getKeyboardLayoutSetDisplayName(subtype); + .getKeyboardLayoutSetDisplayName(subtype.getRawSubtype()); assertTrue(subtypeName, subtypeName.contains(layoutName)); } else { final String languageName = SubtypeLocaleUtils - .getSubtypeLocaleDisplayNameInSystemLocale(subtype.getLocale()); + .getSubtypeLocaleDisplayNameInSystemLocale(subtype.getLocale().toString()); assertTrue(subtypeName, subtypeName.contains(languageName)); } } @@ -128,6 +168,8 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { assertEquals("fr_CH", "swiss", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR_CH)); assertEquals("de", "qwertz", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE)); assertEquals("de_CH", "swiss", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE_CH)); + assertEquals("hi", "hindi", SubtypeLocaleUtils.getKeyboardLayoutSetName(HI)); + assertEquals("sr", "south_slavic", SubtypeLocaleUtils.getKeyboardLayoutSetName(SR)); assertEquals("zz", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(ZZ)); assertEquals("de qwerty", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE_QWERTY)); @@ -140,27 +182,46 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { SubtypeLocaleUtils.getKeyboardLayoutSetName(ES_US_COLEMAK)); assertEquals("zz azerty", "azerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(ZZ_AZERTY)); + + // These are preliminary subtypes and may not exist. + if (HI_LATN != null) { + assertEquals("hi_ZZ", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(HI_LATN)); + assertEquals("hi_ZZ dvorak", "dvorak", + SubtypeLocaleUtils.getKeyboardLayoutSetName(HI_LATN_DVORAK)); + } + if (SR_LATN != null) { + assertEquals("sr_ZZ", "serbian_qwertz", + SubtypeLocaleUtils.getKeyboardLayoutSetName(SR_LATN)); + assertEquals("sr_ZZ qwerty", "qwerty", + SubtypeLocaleUtils.getKeyboardLayoutSetName(SR_LATN_QWERTY)); + } } // InputMethodSubtype's display name in system locale (en_US). - // isAdditionalSubtype (T=true, F=false) - // locale layout | display name - // ------ ------- - ---------------------- - // en_US qwerty F English (US) exception - // en_GB qwerty F English (UK) exception - // 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) - // en_US azerty T English (US) (AZERTY) exception - // en_UK dvorak T English (UK) (Dvorak) exception - // es_US colemak T Spanish (US) (Colemak) exception - // zz pc T Alphabet (PC) + // isAdditionalSubtype (T=true, F=false) + // locale layout | display name + // ------ -------------- - ---------------------- + // en_US qwerty F English (US) exception + // en_GB qwerty F English (UK) exception + // 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) + // hi hindi F Hindi + // hi_ZZ qwerty F Hinglish exception + // sr south_slavic F Serbian + // sr_ZZ serbian_qwertz F Serbian (Latin) exception + // zz qwerty F Alphabet (QWERTY) + // fr qwertz T French (QWERTZ) + // de qwerty T German (QWERTY) + // en_US azerty T English (US) (AZERTY) exception + // en_UK dvorak T English (UK) (Dvorak) exception + // es_US colemak T Spanish (US) (Colemak) exception + // hi_ZZ dvorak T Hinglish (Dvorka) exception + // sr_ZZ qwerty T Serbian (QWERTY) exception + // zz pc T Alphabet (PC) public void testPredefinedSubtypesInEnglishSystemLocale() { final RunInLocale<Void> tests = new RunInLocale<Void>() { @@ -182,8 +243,21 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE)); assertEquals("de_CH", "German (Switzerland)", SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_CH)); + assertEquals("hi", "Hindi", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(HI)); + assertEquals("sr", "Serbian", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(SR)); assertEquals("zz", "Alphabet (QWERTY)", SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ)); + // These are preliminary subtypes and may not exist. + if (HI_LATN != null) { + assertEquals("hi_ZZ", "Hinglish", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(HI_LATN)); + } + if (SR_LATN != null) { + assertEquals("sr_ZZ", "Serbian (Latin)", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(SR_LATN)); + } return null; } }; @@ -208,6 +282,15 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ_AZERTY)); assertEquals("zz pc", "Alphabet (PC)", SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ_PC)); + // These are preliminary subtypes and may not exist. + if (HI_LATN_DVORAK != null) { + assertEquals("hi_ZZ", "Hinglish (Dvorak)", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(HI_LATN_DVORAK)); + } + if (SR_LATN_QWERTY != null) { + assertEquals("sr_ZZ", "Serbian (QWERTY)", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(SR_LATN_QWERTY)); + } return null; } }; @@ -218,21 +301,27 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { // isAdditionalSubtype (T=true, F=false) // locale layout | display name // ------ ------- - ---------------------- - // en_US qwerty F Anglais (États-Unis) exception - // en_GB qwerty F Anglais (Royaume-Uni) exception - // 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 Alphabet latin (QWERTY) - // fr qwertz T Français (QWERTZ) - // de qwerty T Allemand (QWERTY) - // en_US azerty T Anglais (États-Unis) (AZERTY) exception - // en_UK dvorak T Anglais (Royaume-Uni) (Dvorak) exception - // es_US colemak T Espagnol (États-Unis) (Colemak) exception - // zz pc T Alphabet latin (PC) + // en_US qwerty F Anglais (États-Unis) exception + // en_GB qwerty F Anglais (Royaume-Uni) exception + // 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) + // hi hindi F Hindi exception + // hi_ZZ qwerty F Hindi/Anglais exception + // sr south_slavic F Serbe exception + // sr_ZZ serbian_qwertz F Serbe (latin) exception + // zz qwerty F Alphabet latin (QWERTY) + // fr qwertz T Français (QWERTZ) + // de qwerty T Allemand (QWERTY) + // en_US azerty T Anglais (États-Unis) (AZERTY) exception + // en_UK dvorak T Anglais (Royaume-Uni) (Dvorak) exception + // es_US colemak T Espagnol (États-Unis) (Colemak) exception + // hi_ZZ dvorak T Hindi/Anglais (Dvorka) exception + // sr_ZZ qwerty T Serbe (QWERTY) exception + // zz pc T Alphabet latin (PC) public void testPredefinedSubtypesInFrenchSystemLocale() { final RunInLocale<Void> tests = new RunInLocale<Void>() { @@ -254,8 +343,21 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE)); assertEquals("de_CH", "Allemand (Suisse)", SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_CH)); + assertEquals("hi", "Hindi", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(HI)); + assertEquals("sr", "Serbe", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(SR)); assertEquals("zz", "Alphabet latin (QWERTY)", SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ)); + // These are preliminary subtypes and may not exist. + if (HI_LATN != null) { + assertEquals("hi_ZZ", "Hindi/Anglais", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(HI_LATN)); + } + if (SR_LATN != null) { + assertEquals("sr_ZZ", "Serbe (latin)", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(SR_LATN)); + } return null; } }; @@ -280,12 +382,75 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ_AZERTY)); assertEquals("zz pc", "Alphabet latin (PC)", SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ_PC)); + // These are preliminary subtypes and may not exist. + if (HI_LATN_DVORAK != null) { + assertEquals("hi_ZZ", "Hindi/Anglais (Dvorak)", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(HI_LATN_DVORAK)); + } + if (SR_LATN_QWERTY != null) { + assertEquals("sr_ZZ", "Serbe (QWERTY)", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(SR_LATN_QWERTY)); + } return null; } }; tests.runInLocale(mRes, Locale.FRENCH); } + // InputMethodSubtype's display name in system locale (hi). + // isAdditionalSubtype (T=true, F=false) + // locale layout | display name + // ------ ------- - ---------------------- + // hi hindi F हिन्दी + // hi_ZZ qwerty F हिंग्लिश + // hi_ZZ dvorak T हिंग्लिश (Dvorak) + + public void testHinglishSubtypesInHindiSystemLocale() { + final RunInLocale<Void> tests = new RunInLocale<Void>() { + @Override + protected Void job (final Resources res) { + assertEquals("hi", "हिन्दी", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(HI)); + // These are preliminary subtypes and may not exist. + if (HI_LATN != null) { + assertEquals("hi_ZZ", "हिंग्लिश", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(HI_LATN)); + assertEquals("hi_ZZ", "हिंग्लिश (Dvorak)", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(HI_LATN_DVORAK)); + } + return null; + } + }; + tests.runInLocale(mRes, new Locale("hi")); + } + + // InputMethodSubtype's display name in system locale (sr). + // isAdditionalSubtype (T=true, F=false) + // locale layout | display name + // ------ -------------- - ---------------------- + // sr south_slavic F Српски + // sr_ZZ serbian_qwertz F Српски (латиница) + // sr_ZZ qwerty T Српски (QWERTY) + + public void testSerbianLatinSubtypesInSerbianSystemLocale() { + final RunInLocale<Void> tests = new RunInLocale<Void>() { + @Override + protected Void job (final Resources res) { + assertEquals("sr", "Српски", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(SR)); + // These are preliminary subtypes and may not exist. + if (SR_LATN != null) { + assertEquals("sr_ZZ", "Српски (латиница)", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(SR_LATN)); + assertEquals("sr_ZZ", "Српски (QWERTY)", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(SR_LATN_QWERTY)); + } + return null; + } + }; + tests.runInLocale(mRes, new Locale("sr")); + } + public void testIsRtlLanguage() { // Known Right-to-Left language subtypes. final InputMethodSubtype ARABIC = mRichImm @@ -298,13 +463,15 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { .findSubtypeByLocaleAndKeyboardLayoutSet("iw", "hebrew"); assertNotNull("Hebrew", HEBREW); - for (final InputMethodSubtype subtype : mSubtypesList) { + for (final RichInputMethodSubtype subtype : mSubtypesList) { + final InputMethodSubtype rawSubtype = subtype.getRawSubtype(); final String subtypeName = SubtypeLocaleUtils - .getSubtypeDisplayNameInSystemLocale(subtype); - if (subtype.equals(ARABIC) || subtype.equals(FARSI) || subtype.equals(HEBREW)) { - assertTrue(subtypeName, SubtypeLocaleUtils.isRtlLanguage(subtype)); + .getSubtypeDisplayNameInSystemLocale(rawSubtype); + if (rawSubtype.equals(ARABIC) || rawSubtype.equals(FARSI) + || rawSubtype.equals(HEBREW)) { + assertTrue(subtypeName, subtype.isRtlSubtype()); } else { - assertFalse(subtypeName, SubtypeLocaleUtils.isRtlLanguage(subtype)); + assertFalse(subtypeName, subtype.isRtlSubtype()); } } } |