Home | History | Annotate | Download | only in utils
      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