Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5cb4eaee authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka
Browse files

Reorganize suggestion related unit test

Bug: 3414081
Change-Id: Ie98c7935b25d17f1547955f8fb6ba2c5c1edb997
parent d94de207
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -7,6 +7,11 @@ LOCAL_CERTIFICATE := shared

LOCAL_JAVA_LIBRARIES := android.test.runner

# Do not compress dictionary files to mmap dict data runtime
LOCAL_AAPT_FLAGS += -0 .dict
# Do not compress test data file
LOCAL_AAPT_FLAGS += -0 .txt

# Include all test java files.
LOCAL_SRC_FILES := $(call all-java-files-under, src)

+10 −9
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ public class SubtypeLocaleTests extends AndroidTestCase {
    private static final String PACKAGE = LatinIME.class.getPackage().getName();

    private Resources mRes;
    private List<InputMethodSubtype> mKeyboardSubtypes;
    private List<InputMethodSubtype> mKeyboardSubtypes = new ArrayList<InputMethodSubtype>();

    @Override
    protected void setUp() throws Exception {
@@ -60,11 +60,6 @@ public class SubtypeLocaleTests extends AndroidTestCase {
        assertTrue("Can not find keyboard subtype", mKeyboardSubtypes.size() > 0);
    }

    // Copied from {@link java.junit.Assert#format(String, Object, Object)}
    private static String format(String message, Object expected, Object actual) {
        return message + " expected:<" + expected + "> but was:<" + actual + ">";
    }

    private String getStringWithLocale(int resId, Locale locale) {
        final Locale savedLocale = Locale.getDefault();
        try {
@@ -76,6 +71,8 @@ public class SubtypeLocaleTests extends AndroidTestCase {
    }

    public void testSubtypeLocale() {
        final StringBuilder messages = new StringBuilder();
        int failedCount = 0;
        for (final InputMethodSubtype subtype : mKeyboardSubtypes) {
            final String localeCode = subtype.getLocale();
            final Locale locale = new Locale(localeCode);
@@ -85,9 +82,13 @@ public class SubtypeLocaleTests extends AndroidTestCase {
            // The subtype name in its locale.  For example 'English (US) Keyboard' or
            // 'Clavier Francais (Canada)'.  (c=\u008d)
            final String subtypeName = getStringWithLocale(subtype.getNameResId(), locale);
            assertTrue(
                    format("subtype display name of " + localeCode + ":", subtypeName, displayName),
                    subtypeName.contains(displayName));
            if (subtypeName.contains(displayName)) {
                failedCount++;
                messages.append(String.format(
                        "subtype name is '%s' and should contain locale '%s' name '%s'\n",
                        subtypeName, localeCode, displayName));
            }
        }
        assertEquals(messages.toString(), 0, failedCount);
    }
}
+74 −146
Original line number Diff line number Diff line
@@ -16,98 +16,105 @@

package com.android.inputmethod.latin;

import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.KeyDetector;
import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.keyboard.LatinKeyboard;
import com.android.inputmethod.keyboard.ProximityKeyDetector;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.android.inputmethod.latin.Suggest;
import com.android.inputmethod.latin.UserBigramDictionary;
import com.android.inputmethod.latin.WordComposer;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.Channels;

import java.io.File;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;

public class SuggestHelper {
    private Suggest mSuggest;
    private UserBigramDictionary mUserBigram;
    private final String TAG;

    /** Uses main dictionary only **/
    public SuggestHelper(String tag, Context context, int resId) {
        TAG = tag;
        mSuggest = new Suggest(context, resId);
    protected final Suggest mSuggest;
    private final LatinKeyboard mKeyboard;
    private final KeyDetector mKeyDetector;

    public SuggestHelper(Context context, int dictionaryId, KeyboardId keyboardId) {
        mSuggest = new Suggest(context, dictionaryId);
        mKeyboard = new LatinKeyboard(context, keyboardId);
        mKeyDetector = new ProximityKeyDetector();
        init();
    }

    protected SuggestHelper(Context context, File dictionaryPath, long startOffset, long length,
            KeyboardId keyboardId) {
        mSuggest = new Suggest(dictionaryPath, startOffset, length);
        mKeyboard = new LatinKeyboard(context, keyboardId);
        mKeyDetector = new ProximityKeyDetector();
        init();
    }

    private void init() {
        mSuggest.setQuickFixesEnabled(false);
        mSuggest.setCorrectionMode(Suggest.CORRECTION_FULL_BIGRAM);
        mSuggest.setCorrectionMode(Suggest.CORRECTION_FULL);
        mKeyDetector.setKeyboard(mKeyboard, 0, 0);
        mKeyDetector.setProximityCorrectionEnabled(true);
        mKeyDetector.setProximityThreshold(KeyDetector.getMostCommonKeyWidth(mKeyboard));
    }

    /** Uses both main dictionary and user-bigram dictionary **/
    public SuggestHelper(String tag, Context context, int resId, int userBigramMax,
            int userBigramDelete) {
        this(tag, context, resId);
        mUserBigram = new UserBigramDictionary(context, null, Locale.US.toString(),
                Suggest.DIC_USER);
        mUserBigram.setDatabaseMax(userBigramMax);
        mUserBigram.setDatabaseDelete(userBigramDelete);
        mSuggest.setUserBigramDictionary(mUserBigram);
    public void setCorrectionMode(int correctionMode) {
        mSuggest.setCorrectionMode(correctionMode);
    }

    void changeUserBigramLocale(Context context, Locale locale) {
        if (mUserBigram != null) {
            flushUserBigrams();
            mUserBigram.close();
            mUserBigram = new UserBigramDictionary(context, null, locale.toString(),
                    Suggest.DIC_USER);
            mSuggest.setUserBigramDictionary(mUserBigram);
    public boolean hasMainDictionary() {
        return mSuggest.hasMainDictionary();
    }

    private int[] getProximityCodes(char c) {
        final List<Key> keys = mKeyboard.getKeys();
        for (final Key key : keys) {
            if (key.mCode == c) {
                final int x = key.mX + key.mWidth / 2;
                final int y = key.mY + key.mHeight / 2;
                final int[] codes = mKeyDetector.newCodeArray();
                mKeyDetector.getKeyIndexAndNearbyCodes(x, y, codes);
                return codes;
            }
        }
        return new int[] { c };
    }

    private WordComposer createWordComposer(CharSequence s) {
    protected WordComposer createWordComposer(CharSequence s) {
        WordComposer word = new WordComposer();
        for (int i = 0; i < s.length(); i++) {
            final char c = s.charAt(i);
            int[] codes;
            // If it's not a lowercase letter, don't find adjacent letters
            if (c < 'a' || c > 'z') {
                codes = new int[] { c };
            } else {
                codes = adjacents[c - 'a'];
            }
            word.add(c, codes);
            word.add(c, getProximityCodes(c));
        }
        return word;
    }

    private boolean isDefaultSuggestion(SuggestedWords suggestions, CharSequence word) {
        // Check if either the word is what you typed or the first alternative
        return suggestions.size() > 0 &&
                (/*TextUtils.equals(suggestions.get(0), word) || */
                  (suggestions.size() > 1 && TextUtils.equals(suggestions.getWord(1), word)));
    public boolean isValidWord(CharSequence typed) {
        return mSuggest.isValidWord(typed);
    }

    boolean isDefaultSuggestion(CharSequence typed, CharSequence expected) {
    public CharSequence getFirstSuggestion(CharSequence typed) {
        WordComposer word = createWordComposer(typed);
        SuggestedWords suggestions = mSuggest.getSuggestions(null, word, null);
        return isDefaultSuggestion(suggestions, expected);
        // Note that suggestions.getWord(0) is the word user typed.
        return suggestions.size() > 1 ? suggestions.getWord(1) : null;
    }

    boolean isDefaultCorrection(CharSequence typed, CharSequence expected) {
    public CharSequence getAutoCorrection(CharSequence typed) {
        WordComposer word = createWordComposer(typed);
        SuggestedWords suggestions = mSuggest.getSuggestions(null, word, null);
        return isDefaultSuggestion(suggestions, expected) && mSuggest.hasAutoCorrection();
        // Note that suggestions.getWord(0) is the word user typed.
        return (suggestions.size() > 1 && mSuggest.hasAutoCorrection())
                ? suggestions.getWord(1) : null;
    }

    boolean isASuggestion(CharSequence typed, CharSequence expected) {
    public int getSuggestIndex(CharSequence typed, CharSequence expected) {
        WordComposer word = createWordComposer(typed);
        SuggestedWords suggestions = mSuggest.getSuggestions(null, word, null);
        // Note that suggestions.getWord(0) is the word user typed.
        for (int i = 1; i < suggestions.size(); i++) {
            if (TextUtils.equals(suggestions.getWord(i), expected)) return true;
            if (TextUtils.equals(suggestions.getWord(i), expected))
                return i;
        }
        return false;
        return -1;
    }

    private void getBigramSuggestions(CharSequence previous, CharSequence typed) {
@@ -117,109 +124,30 @@ public class SuggestHelper {
        }
    }

    boolean isDefaultNextSuggestion(CharSequence previous, CharSequence typed,
            CharSequence expected) {
    public CharSequence getBigramFirstSuggestion(CharSequence previous, CharSequence typed) {
        WordComposer word = createWordComposer(typed);
        getBigramSuggestions(previous, typed);
        SuggestedWords suggestions = mSuggest.getSuggestions(null, word, previous);
        return isDefaultSuggestion(suggestions, expected);
        return suggestions.size() > 1 ? suggestions.getWord(1) : null;
    }

    boolean isDefaultNextCorrection(CharSequence previous, CharSequence typed,
            CharSequence expected) {
    public CharSequence getBigramAutoCorrection(CharSequence previous, CharSequence typed) {
        WordComposer word = createWordComposer(typed);
        getBigramSuggestions(previous, typed);
        SuggestedWords suggestions = mSuggest.getSuggestions(null, word, previous);
        return isDefaultSuggestion(suggestions, expected) && mSuggest.hasAutoCorrection();
        return (suggestions.size() > 1 && mSuggest.hasAutoCorrection())
                ? suggestions.getWord(1) : null;
    }

    boolean isASuggestion(CharSequence previous, CharSequence typed,
    public int searchBigramSuggestion(CharSequence previous, CharSequence typed,
            CharSequence expected) {
        WordComposer word = createWordComposer(typed);
        getBigramSuggestions(previous, typed);
        SuggestedWords suggestions = mSuggest.getSuggestions(null, word, previous);
        for (int i = 1; i < suggestions.size(); i++) {
            if (TextUtils.equals(suggestions.getWord(i), expected)) return true;
            if (TextUtils.equals(suggestions.getWord(i), expected))
                return i;
        }
        return false;
        return -1;
    }

    boolean isValid(CharSequence typed) {
        return mSuggest.isValidWord(typed);
    }

    boolean isUserBigramSuggestion(CharSequence previous, char typed,
           CharSequence expected) {
        if (mUserBigram == null) return false;

        flushUserBigrams();
        if (!TextUtils.isEmpty(previous) && !TextUtils.isEmpty(Character.toString(typed))) {
            WordComposer firstChar = createWordComposer(Character.toString(typed));
            mSuggest.getSuggestions(null, firstChar, previous);
            boolean reloading = mUserBigram.reloadDictionaryIfRequired();
            if (reloading) mUserBigram.waitForDictionaryLoading();
            mUserBigram.getBigrams(firstChar, previous, mSuggest, null);
        }

        List<CharSequence> suggestions = mSuggest.mBigramSuggestions;
        for (int i = 0; i < suggestions.size(); i++) {
            if (TextUtils.equals(suggestions.get(i), expected)) return true;
        }

        return false;
    }

    void addToUserBigram(String sentence) {
        StringTokenizer st = new StringTokenizer(sentence);
        String previous = null;
        while (st.hasMoreTokens()) {
            String current = st.nextToken();
            if (previous != null) {
                addToUserBigram(new String[] {previous, current});
            }
            previous = current;
        }
    }

    void addToUserBigram(String[] pair) {
        if (mUserBigram != null && pair.length == 2) {
            mUserBigram.addBigrams(pair[0], pair[1]);
        }
    }

    void flushUserBigrams() {
        if (mUserBigram != null) {
            mUserBigram.flushPendingWrites();
            mUserBigram.waitUntilUpdateDBDone();
        }
    }

    final int[][] adjacents = {
                               {'a','s','w','q',-1},
                               {'b','h','v','n','g','j',-1},
                               {'c','v','f','x','g',},
                               {'d','f','r','e','s','x',-1},
                               {'e','w','r','s','d',-1},
                               {'f','g','d','c','t','r',-1},
                               {'g','h','f','y','t','v',-1},
                               {'h','j','u','g','b','y',-1},
                               {'i','o','u','k',-1},
                               {'j','k','i','h','u','n',-1},
                               {'k','l','o','j','i','m',-1},
                               {'l','k','o','p',-1},
                               {'m','k','n','l',-1},
                               {'n','m','j','k','b',-1},
                               {'o','p','i','l',-1},
                               {'p','o',-1},
                               {'q','w',-1},
                               {'r','t','e','f',-1},
                               {'s','d','e','w','a','z',-1},
                               {'t','y','r',-1},
                               {'u','y','i','h','j',-1},
                               {'v','b','g','c','h',-1},
                               {'w','e','q',-1},
                               {'x','c','d','z','f',-1},
                               {'y','u','t','h','g',-1},
                               {'z','s','x','a','d',-1},
                              };
}
+54 −48
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 * Copyright (C) 2010,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
@@ -15,70 +15,76 @@
 */

package com.android.inputmethod.latin;

import android.test.AndroidTestCase;
import android.util.Log;
import com.android.inputmethod.latin.tests.R;
import java.io.InputStreamReader;
import java.io.InputStream;

import android.content.res.AssetFileDescriptor;
import android.text.TextUtils;
import android.util.Slog;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class SuggestPerformanceTests extends AndroidTestCase {
    private static final String TAG = "SuggestPerformanceTests";
public class SuggestPerformanceTests extends SuggestTestsBase {
    private static final String TAG = SuggestPerformanceTests.class.getSimpleName();

    private String mTestText;
    private SuggestHelper sh;
    private SuggestHelper mHelper;

    @Override
    protected void setUp() {
        // TODO Figure out a way to directly using the dictionary rather than copying it over

        // For testing with real dictionary, TEMPORARILY COPY main dictionary into test directory.
        // DO NOT SUBMIT real dictionary under test directory.
        //int resId = R.raw.main;

        int resId = R.raw.test;

        sh = new SuggestHelper(TAG, getTestContext(), resId);
        loadString();
    protected void setUp() throws Exception {
        super.setUp();
        final AssetFileDescriptor dict = openTestRawResourceFd(R.raw.test);
        mHelper = new SuggestHelper(
                getContext(), mTestPackageFile, dict.getStartOffset(), dict.getLength(),
                US_KEYBOARD_ID);
        loadString(R.raw.testtext);
    }

    private void loadString() {
    private void loadString(int testFileId) {
        final String testFile = getTestContext().getResources().getResourceName(testFileId);
        BufferedReader reader = null;
        try {
            InputStream is = getTestContext().getResources().openRawResource(R.raw.testtext);
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line = reader.readLine();
            while (line != null) {
                sb.append(line + " ");
                line = reader.readLine();
            reader = new BufferedReader(
                    new InputStreamReader(openTestRawResource(testFileId)));
            final StringBuilder sb = new StringBuilder();
            String line;
            Slog.i(TAG, "Reading test file " + testFile);
            while ((line = reader.readLine()) != null) {
                sb.append(line);
                sb.append(" ");
            }
            mTestText = sb.toString();
        } catch (Exception e) {
            Slog.e(TAG, "Can not read " + testFile);
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (Exception e) {
                    Slog.e(TAG, "Closing " + testFile + " failed");
                }
            }
        }
    }

    /************************** Helper functions ************************/
    private int lookForSuggestion(String prevWord, String currentWord) {
    private int lookForBigramSuggestion(String prevWord, String currentWord) {
        for (int i = 1; i < currentWord.length(); i++) {
            if (i == 1) {
                if (sh.isDefaultNextSuggestion(prevWord, currentWord.substring(0, i),
                        currentWord)) {
                    return i;
                }
            } else {
                if (sh.isDefaultNextCorrection(prevWord, currentWord.substring(0, i),
                        currentWord)) {
            final CharSequence prefix = currentWord.substring(0, i);
            final CharSequence word = (i == 1)
                    ? mHelper.getBigramFirstSuggestion(prevWord, prefix)
                    : mHelper.getBigramAutoCorrection(prevWord, prefix);
            if (TextUtils.equals(word, currentWord))
                return i;
        }
            }
        }
        return currentWord.length();
    }

    private double runText(boolean withBigrams) {
        mHelper.setCorrectionMode(
                withBigrams ? Suggest.CORRECTION_FULL_BIGRAM : Suggest.CORRECTION_FULL);
        StringTokenizer st = new StringTokenizer(mTestText);
        String prevWord = null;
        int typeCount = 0;
@@ -92,9 +98,9 @@ public class SuggestPerformanceTests extends AndroidTestCase {
                endCheck = true;
            }
            if (withBigrams && prevWord != null) {
                typeCount += lookForSuggestion(prevWord, currentWord);
                typeCount += lookForBigramSuggestion(prevWord, currentWord);
            } else {
                typeCount += lookForSuggestion(null, currentWord);
                typeCount += lookForBigramSuggestion(null, currentWord);
            }
            characterCount += currentWord.length();
            if (!endCheck) prevWord = currentWord;
@@ -103,14 +109,14 @@ public class SuggestPerformanceTests extends AndroidTestCase {

        double result = (double) (characterCount - typeCount) / characterCount * 100;
        if (withBigrams) {
            Log.i(TAG, "with bigrams -> "  + result + " % saved!");
            Slog.i(TAG, "with bigrams -> "  + result + " % saved!");
        } else {
            Log.i(TAG, "without bigrams  -> "  + result + " % saved!");
            Slog.i(TAG, "without bigrams  -> "  + result + " % saved!");
        }
        Log.i(TAG, "\ttotal number of words: " + wordCount);
        Log.i(TAG, "\ttotal number of characters: " + mTestText.length());
        Log.i(TAG, "\ttotal number of characters without space: " + characterCount);
        Log.i(TAG, "\ttotal number of characters typed: " + typeCount);
        Slog.i(TAG, "\ttotal number of words: " + wordCount);
        Slog.i(TAG, "\ttotal number of characters: " + mTestText.length());
        Slog.i(TAG, "\ttotal number of characters without space: " + characterCount);
        Slog.i(TAG, "\ttotal number of characters typed: " + typeCount);
        return result;
    }

+66 −55

File changed.

Preview size limit exceeded, changes collapsed.

Loading