1 /* 2 * Copyright (C) 2012 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.utils; 18 19 import android.content.Context; 20 import android.test.AndroidTestCase; 21 import android.test.suitebuilder.annotation.LargeTest; 22 import android.util.Log; 23 24 import com.android.inputmethod.latin.makedict.DictDecoder; 25 import com.android.inputmethod.latin.makedict.DictEncoder; 26 import com.android.inputmethod.latin.makedict.FormatSpec; 27 import com.android.inputmethod.latin.makedict.FusionDictionary; 28 import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode; 29 import com.android.inputmethod.latin.makedict.Ver3DictDecoder; 30 import com.android.inputmethod.latin.makedict.Ver3DictEncoder; 31 import com.android.inputmethod.latin.personalization.UserHistoryDictionaryBigramList; 32 import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils.BigramDictionaryInterface; 33 import com.android.inputmethod.latin.utils.UserHistoryDictIOUtils.OnAddWordListener; 34 35 import java.io.File; 36 import java.io.FileNotFoundException; 37 import java.io.IOException; 38 import java.util.ArrayList; 39 import java.util.Collections; 40 import java.util.HashMap; 41 42 /** 43 * Unit tests for UserHistoryDictIOUtils 44 */ 45 @LargeTest 46 public class UserHistoryDictIOUtilsTests extends AndroidTestCase 47 implements BigramDictionaryInterface { 48 49 private static final String TAG = UserHistoryDictIOUtilsTests.class.getSimpleName(); 50 private static final int UNIGRAM_FREQUENCY = 50; 51 private static final int BIGRAM_FREQUENCY = 100; 52 private static final ArrayList<String> NOT_HAVE_BIGRAM = new ArrayList<String>(); 53 private static final FormatSpec.FormatOptions FORMAT_OPTIONS = new FormatSpec.FormatOptions(2); 54 private static final String TEST_DICT_FILE_EXTENSION = ".testDict"; 55 56 /** 57 * Return same frequency for all words and bigrams 58 */ 59 @Override 60 public int getFrequency(String word1, String word2) { 61 if (word1 == null) return UNIGRAM_FREQUENCY; 62 return BIGRAM_FREQUENCY; 63 } 64 65 // Utilities for Testing 66 67 private void addWord(final String word, 68 final HashMap<String, ArrayList<String> > addedWords) { 69 if (!addedWords.containsKey(word)) { 70 addedWords.put(word, new ArrayList<String>()); 71 } 72 } 73 74 private void addBigram(final String word1, final String word2, 75 final HashMap<String, ArrayList<String> > addedWords) { 76 addWord(word1, addedWords); 77 addWord(word2, addedWords); 78 addedWords.get(word1).add(word2); 79 } 80 81 private void addBigramToBigramList(final String word1, final String word2, 82 final HashMap<String, ArrayList<String> > addedWords, 83 final UserHistoryDictionaryBigramList bigramList) { 84 bigramList.addBigram(null, word1); 85 bigramList.addBigram(word1, word2); 86 87 addBigram(word1, word2, addedWords); 88 } 89 90 private void checkWordInFusionDict(final FusionDictionary dict, final String word, 91 final ArrayList<String> expectedBigrams) { 92 final PtNode ptNode = FusionDictionary.findWordInTree(dict.mRootNodeArray, word); 93 assertNotNull(ptNode); 94 assertTrue(ptNode.isTerminal()); 95 96 for (final String bigram : expectedBigrams) { 97 assertNotNull(ptNode.getBigram(bigram)); 98 } 99 } 100 101 private void checkWordsInFusionDict(final FusionDictionary dict, 102 final HashMap<String, ArrayList<String> > bigrams) { 103 for (final String word : bigrams.keySet()) { 104 if (bigrams.containsKey(word)) { 105 checkWordInFusionDict(dict, word, bigrams.get(word)); 106 } else { 107 checkWordInFusionDict(dict, word, NOT_HAVE_BIGRAM); 108 } 109 } 110 } 111 112 private void checkWordInBigramList( 113 final UserHistoryDictionaryBigramList bigramList, final String word, 114 final ArrayList<String> expectedBigrams) { 115 // check unigram 116 final HashMap<String,Byte> unigramMap = bigramList.getBigrams(null); 117 assertTrue(unigramMap.containsKey(word)); 118 119 // check bigrams 120 final ArrayList<String> actualBigrams = new ArrayList<String>( 121 bigramList.getBigrams(word).keySet()); 122 123 Collections.sort(expectedBigrams); 124 Collections.sort(actualBigrams); 125 assertEquals(expectedBigrams, actualBigrams); 126 } 127 128 private void checkWordsInBigramList(final UserHistoryDictionaryBigramList bigramList, 129 final HashMap<String, ArrayList<String> > addedWords) { 130 for (final String word : addedWords.keySet()) { 131 if (addedWords.containsKey(word)) { 132 checkWordInBigramList(bigramList, word, addedWords.get(word)); 133 } else { 134 checkWordInBigramList(bigramList, word, NOT_HAVE_BIGRAM); 135 } 136 } 137 } 138 139 private void writeDictToFile(final File file, 140 final UserHistoryDictionaryBigramList bigramList) { 141 final DictEncoder dictEncoder = new Ver3DictEncoder(file); 142 UserHistoryDictIOUtils.writeDictionary(dictEncoder, this, bigramList, FORMAT_OPTIONS); 143 } 144 145 private void readDictFromFile(final File file, final OnAddWordListener listener) { 146 final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, DictDecoder.USE_BYTEARRAY); 147 try { 148 dictDecoder.openDictBuffer(); 149 } catch (FileNotFoundException e) { 150 Log.e(TAG, "file not found", e); 151 } catch (IOException e) { 152 Log.e(TAG, "IOException", e); 153 } 154 UserHistoryDictIOUtils.readDictionaryBinary(dictDecoder, listener); 155 } 156 157 public void testGenerateFusionDictionary() { 158 final UserHistoryDictionaryBigramList originalList = new UserHistoryDictionaryBigramList(); 159 160 final HashMap<String, ArrayList<String> > addedWords = 161 new HashMap<String, ArrayList<String>>(); 162 addBigramToBigramList("this", "is", addedWords, originalList); 163 addBigramToBigramList("this", "was", addedWords, originalList); 164 addBigramToBigramList("hello", "world", addedWords, originalList); 165 166 final FusionDictionary fusionDict = 167 UserHistoryDictIOUtils.constructFusionDictionary(this, originalList); 168 169 checkWordsInFusionDict(fusionDict, addedWords); 170 } 171 172 public void testReadAndWrite() { 173 final Context context = getContext(); 174 175 File file = null; 176 try { 177 file = File.createTempFile("testReadAndWrite", TEST_DICT_FILE_EXTENSION, 178 getContext().getCacheDir()); 179 } catch (IOException e) { 180 Log.d(TAG, "IOException while creating a temporary file", e); 181 } 182 assertNotNull(file); 183 184 // make original dictionary 185 final UserHistoryDictionaryBigramList originalList = new UserHistoryDictionaryBigramList(); 186 final HashMap<String, ArrayList<String>> addedWords = CollectionUtils.newHashMap(); 187 addBigramToBigramList("this" , "is" , addedWords, originalList); 188 addBigramToBigramList("this" , "was" , addedWords, originalList); 189 addBigramToBigramList("is" , "not" , addedWords, originalList); 190 addBigramToBigramList("hello", "world", addedWords, originalList); 191 192 // write to file 193 writeDictToFile(file, originalList); 194 195 // make result dict. 196 final UserHistoryDictionaryBigramList resultList = new UserHistoryDictionaryBigramList(); 197 final OnAddWordListener listener = new OnAddWordListener() { 198 @Override 199 public void setUnigram(final String word, final String shortcutTarget, 200 final int frequency, final int shortcutFreq) { 201 Log.d(TAG, "in: setUnigram: " + word + "," + frequency); 202 resultList.addBigram(null, word, (byte)frequency); 203 } 204 @Override 205 public void setBigram(final String word1, final String word2, final int frequency) { 206 Log.d(TAG, "in: setBigram: " + word1 + "," + word2 + "," + frequency); 207 resultList.addBigram(word1, word2, (byte)frequency); 208 } 209 }; 210 211 // load from file 212 readDictFromFile(file, listener); 213 checkWordsInBigramList(resultList, addedWords); 214 215 // add new bigram 216 addBigramToBigramList("hello", "java", addedWords, resultList); 217 218 // rewrite 219 writeDictToFile(file, resultList); 220 final UserHistoryDictionaryBigramList resultList2 = new UserHistoryDictionaryBigramList(); 221 final OnAddWordListener listener2 = new OnAddWordListener() { 222 @Override 223 public void setUnigram(final String word, final String shortcutTarget, 224 final int frequency, final int shortcutFreq) { 225 Log.d(TAG, "in: setUnigram: " + word + "," + frequency); 226 resultList2.addBigram(null, word, (byte)frequency); 227 } 228 @Override 229 public void setBigram(final String word1, final String word2, final int frequency) { 230 Log.d(TAG, "in: setBigram: " + word1 + "," + word2 + "," + frequency); 231 resultList2.addBigram(word1, word2, (byte)frequency); 232 } 233 }; 234 235 // load from file 236 readDictFromFile(file, listener2); 237 checkWordsInBigramList(resultList2, addedWords); 238 } 239 } 240