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

Commit 195e0f71 authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka Committed by Android (Google) Code Review
Browse files

Merge "Reorganize suggestion related unit test"

parents 75fa4b8c 5cb4eaee
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