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