112d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani/* 212d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * Copyright (C) 2014 The Android Open Source Project 312d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * 412d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * Licensed under the Apache License, Version 2.0 (the "License"); 512d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * you may not use this file except in compliance with the License. 612d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * You may obtain a copy of the License at 712d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * 812d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * http://www.apache.org/licenses/LICENSE-2.0 912d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * 1012d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * Unless required by applicable law or agreed to in writing, software 1112d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * distributed under the License is distributed on an "AS IS" BASIS, 1212d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1312d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * See the License for the specific language governing permissions and 1412d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * limitations under the License. 1512d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani */ 1612d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani 1712d63820d459edd71a46fa2495fea98b3c785f2dJatin Matanipackage com.android.inputmethod.latin.personalization; 1812d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani 1912d63820d459edd71a46fa2495fea98b3c785f2dJatin Mataniimport android.content.Context; 2012d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani 21f4686092232588781910cc4e64406c4958577e86Mohammadinamul Sheikimport com.android.inputmethod.latin.BinaryDictionary; 2212d63820d459edd71a46fa2495fea98b3c785f2dJatin Mataniimport com.android.inputmethod.latin.NgramContext; 2312d63820d459edd71a46fa2495fea98b3c785f2dJatin Mataniimport com.android.inputmethod.latin.NgramContext.WordInfo; 2412d63820d459edd71a46fa2495fea98b3c785f2dJatin Mataniimport com.android.inputmethod.latin.common.FileUtils; 2512d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani 2612d63820d459edd71a46fa2495fea98b3c785f2dJatin Mataniimport java.io.File; 2712d63820d459edd71a46fa2495fea98b3c785f2dJatin Mataniimport java.io.FilenameFilter; 2812d63820d459edd71a46fa2495fea98b3c785f2dJatin Mataniimport java.util.ArrayList; 2912d63820d459edd71a46fa2495fea98b3c785f2dJatin Mataniimport java.util.HashSet; 3012d63820d459edd71a46fa2495fea98b3c785f2dJatin Mataniimport java.util.List; 3112d63820d459edd71a46fa2495fea98b3c785f2dJatin Mataniimport java.util.Locale; 3212d63820d459edd71a46fa2495fea98b3c785f2dJatin Mataniimport java.util.Random; 3312d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani 3412d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani/** 3512d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * Utility class for helping while running tests involving {@link UserHistoryDictionary}. 3612d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani */ 3712d63820d459edd71a46fa2495fea98b3c785f2dJatin Matanipublic class UserHistoryDictionaryTestsHelper { 3812d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani 3912d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani /** 4012d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * Locale prefix for generating dummy locales for tests. 4112d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani */ 4212d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani public static final String TEST_LOCALE_PREFIX = "test-"; 4312d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani 4412d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani /** 4512d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * Characters for generating random words. 4612d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani */ 4712d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani private static final String[] CHARACTERS = { 4812d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", 4912d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" 5012d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani }; 5112d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani 5212d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani /** 5312d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * Remove all the test dictionary files created for the given locale. 5412d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani */ 5512d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani public static void removeAllTestDictFiles(final String filter, final Context context) { 5612d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani final FilenameFilter filenameFilter = new FilenameFilter() { 5712d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani @Override 5812d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani public boolean accept(final File dir, final String filename) { 5912d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani return filename.startsWith(UserHistoryDictionary.NAME + "." + filter); 6012d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani } 6112d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani }; 6212d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani FileUtils.deleteFilteredFiles(context.getFilesDir(), filenameFilter); 6312d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani } 6412d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani 6512d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani /** 6612d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * Generates and writes random words to dictionary. Caller can be assured 6712d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * that the write tasks would be finished; and its success would be reflected 6812d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * in the returned boolean. 6912d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * 7012d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * @param dict {@link UserHistoryDictionary} to which words should be added. 7112d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * @param numberOfWords number of words to be added. 7212d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * @param random helps generate random words. 7312d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * @param checkContents if true, checks whether written words are actually in the dictionary. 7412d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * @param currentTime timestamp that would be used for adding the words. 7512d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * @returns true if all words have been written to dictionary successfully. 7612d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani */ 7712d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani public static boolean addAndWriteRandomWords(final UserHistoryDictionary dict, 7812d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani final int numberOfWords, final Random random, final boolean checkContents, 7912d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani final int currentTime) { 8012d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani final List<String> words = generateWords(numberOfWords, random); 8112d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani // Add random words to the user history dictionary. 8212d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani addWordsToDictionary(dict, words, currentTime); 8312d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani boolean success = true; 8412d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani if (checkContents) { 8512d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani dict.waitAllTasksForTests(); 8612d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani for (int i = 0; i < numberOfWords; ++i) { 8712d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani final String word = words.get(i); 8812d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani if (!dict.isInDictionary(word)) { 8912d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani success = false; 9012d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani break; 9112d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani } 9212d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani } 9312d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani } 9412d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani // write to file. 9512d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani dict.close(); 9612d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani dict.waitAllTasksForTests(); 9712d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani return success; 9812d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani } 9912d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani 10012d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani private static void addWordsToDictionary(final UserHistoryDictionary dict, 10112d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani final List<String> words, final int timestamp) { 102f4686092232588781910cc4e64406c4958577e86Mohammadinamul Sheik NgramContext ngramContext = NgramContext.getEmptyPrevWordsContext( 103f4686092232588781910cc4e64406c4958577e86Mohammadinamul Sheik BinaryDictionary.MAX_PREV_WORD_COUNT_FOR_N_GRAM); 10412d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani for (final String word : words) { 105644a709a5fec65c3ac1c96f18af397458fac7658Dan Zivkovic UserHistoryDictionary.addToDictionary(dict, ngramContext, word, true, timestamp); 10612d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani ngramContext = ngramContext.getNextNgramContext(new WordInfo(word)); 10712d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani } 10812d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani } 10912d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani 11012d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani /** 11112d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * Creates unique test locale for using within tests. 11212d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani */ 11312d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani public static Locale getDummyLocale(final String name) { 11412d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani return new Locale(TEST_LOCALE_PREFIX + name + System.currentTimeMillis()); 11512d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani } 11612d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani 11712d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani /** 11812d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * Generates random words. 11912d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * 12012d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * @param numberOfWords number of words to generate. 12112d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * @param random salt used for generating random words. 12212d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani */ 12312d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani public static List<String> generateWords(final int numberOfWords, final Random random) { 12412d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani final HashSet<String> wordSet = new HashSet<>(); 12512d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani while (wordSet.size() < numberOfWords) { 12612d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani wordSet.add(generateWord(random.nextInt())); 12712d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani } 12812d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani return new ArrayList<>(wordSet); 12912d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani } 13012d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani 13112d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani /** 13212d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani * Generates a random word. 13312d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani */ 13412d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani private static String generateWord(final int value) { 13512d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani final int lengthOfChars = CHARACTERS.length; 13612d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani final StringBuilder builder = new StringBuilder(); 13712d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani long lvalue = Math.abs((long)value); 13812d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani while (lvalue > 0) { 13912d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani builder.append(CHARACTERS[(int)(lvalue % lengthOfChars)]); 14012d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani lvalue /= lengthOfChars; 14112d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani } 14212d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani return builder.toString(); 14312d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani } 14412d63820d459edd71a46fa2495fea98b3c785f2dJatin Matani} 145