1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.inputmethod.latin.personalization; 18 19 import android.content.Context; 20 21 import com.android.inputmethod.latin.BinaryDictionary; 22 import com.android.inputmethod.latin.NgramContext; 23 import com.android.inputmethod.latin.NgramContext.WordInfo; 24 import com.android.inputmethod.latin.common.FileUtils; 25 26 import java.io.File; 27 import java.io.FilenameFilter; 28 import java.util.ArrayList; 29 import java.util.HashSet; 30 import java.util.List; 31 import java.util.Locale; 32 import java.util.Random; 33 34 /** 35 * Utility class for helping while running tests involving {@link UserHistoryDictionary}. 36 */ 37 public class UserHistoryDictionaryTestsHelper { 38 39 /** 40 * Locale prefix for generating placeholder locales for tests. 41 */ 42 public static final String TEST_LOCALE_PREFIX = "test-"; 43 44 /** 45 * Characters for generating random words. 46 */ 47 private static final String[] CHARACTERS = { 48 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", 49 "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" 50 }; 51 52 /** 53 * Remove all the test dictionary files created for the given locale. 54 */ removeAllTestDictFiles(final String filter, final Context context)55 public static void removeAllTestDictFiles(final String filter, final Context context) { 56 final FilenameFilter filenameFilter = new FilenameFilter() { 57 @Override 58 public boolean accept(final File dir, final String filename) { 59 return filename.startsWith(UserHistoryDictionary.NAME + "." + filter); 60 } 61 }; 62 FileUtils.deleteFilteredFiles(context.getFilesDir(), filenameFilter); 63 } 64 65 /** 66 * Generates and writes random words to dictionary. Caller can be assured 67 * that the write tasks would be finished; and its success would be reflected 68 * in the returned boolean. 69 * 70 * @param dict {@link UserHistoryDictionary} to which words should be added. 71 * @param numberOfWords number of words to be added. 72 * @param random helps generate random words. 73 * @param checkContents if true, checks whether written words are actually in the dictionary. 74 * @param currentTime timestamp that would be used for adding the words. 75 * @returns true if all words have been written to dictionary successfully. 76 */ addAndWriteRandomWords(final UserHistoryDictionary dict, final int numberOfWords, final Random random, final boolean checkContents, final int currentTime)77 public static boolean addAndWriteRandomWords(final UserHistoryDictionary dict, 78 final int numberOfWords, final Random random, final boolean checkContents, 79 final int currentTime) { 80 final List<String> words = generateWords(numberOfWords, random); 81 // Add random words to the user history dictionary. 82 addWordsToDictionary(dict, words, currentTime); 83 boolean success = true; 84 if (checkContents) { 85 dict.waitAllTasksForTests(); 86 for (int i = 0; i < numberOfWords; ++i) { 87 final String word = words.get(i); 88 if (!dict.isInDictionary(word)) { 89 success = false; 90 break; 91 } 92 } 93 } 94 // write to file. 95 dict.close(); 96 dict.waitAllTasksForTests(); 97 return success; 98 } 99 addWordsToDictionary(final UserHistoryDictionary dict, final List<String> words, final int timestamp)100 private static void addWordsToDictionary(final UserHistoryDictionary dict, 101 final List<String> words, final int timestamp) { 102 NgramContext ngramContext = NgramContext.getEmptyPrevWordsContext( 103 BinaryDictionary.MAX_PREV_WORD_COUNT_FOR_N_GRAM); 104 for (final String word : words) { 105 UserHistoryDictionary.addToDictionary(dict, ngramContext, word, true, timestamp); 106 ngramContext = ngramContext.getNextNgramContext(new WordInfo(word)); 107 } 108 } 109 110 /** 111 * Creates unique test locale for using within tests. 112 */ getFakeLocale(final String name)113 public static Locale getFakeLocale(final String name) { 114 return new Locale(TEST_LOCALE_PREFIX + name + System.currentTimeMillis()); 115 } 116 117 /** 118 * Generates random words. 119 * 120 * @param numberOfWords number of words to generate. 121 * @param random salt used for generating random words. 122 */ generateWords(final int numberOfWords, final Random random)123 public static List<String> generateWords(final int numberOfWords, final Random random) { 124 final HashSet<String> wordSet = new HashSet<>(); 125 while (wordSet.size() < numberOfWords) { 126 wordSet.add(generateWord(random.nextInt())); 127 } 128 return new ArrayList<>(wordSet); 129 } 130 131 /** 132 * Generates a random word. 133 */ generateWord(final int value)134 private static String generateWord(final int value) { 135 final int lengthOfChars = CHARACTERS.length; 136 final StringBuilder builder = new StringBuilder(); 137 long lvalue = Math.abs((long)value); 138 while (lvalue > 0) { 139 builder.append(CHARACTERS[(int)(lvalue % lengthOfChars)]); 140 lvalue /= lengthOfChars; 141 } 142 return builder.toString(); 143 } 144 } 145