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