1a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard/* 2a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard * Copyright (C) 2013 The Android Open Source Project 3a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard * 4a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard * Licensed under the Apache License, Version 2.0 (the "License"); 5a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard * you may not use this file except in compliance with the License. 6a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard * You may obtain a copy of the License at 7a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard * 8a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard * http://www.apache.org/licenses/LICENSE-2.0 9a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard * 10a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard * Unless required by applicable law or agreed to in writing, software 11a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard * distributed under the License is distributed on an "AS IS" BASIS, 12a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard * See the License for the specific language governing permissions and 14a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard * limitations under the License. 15a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard */ 16a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard 17a411595b169c1f136d09d114a458def1f99f91d9Jean Chalardpackage com.android.inputmethod.latin.makedict; 18a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard 19f14cf3e64caea68419969deb71793b367b1bbce2Keisuke Kuroyanagiimport com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions; 20a411595b169c1f136d09d114a458def1f99f91d9Jean Chalardimport com.android.inputmethod.latin.makedict.FusionDictionary; 21576f625ee1b22e26baab46cc4ad3138e901383e2Yuichiro Hanadaimport com.android.inputmethod.latin.makedict.FusionDictionary.PtNode; 22af30cbf0ee8370763edf22822ea34a282e882084Jean Chalardimport com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray; 235f5feeba13f6f1a907d90365d8037a361d0ff5daKeisuke Kuroyanagiimport com.android.inputmethod.latin.makedict.WordProperty; 24a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard 25a411595b169c1f136d09d114a458def1f99f91d9Jean Chalardimport junit.framework.TestCase; 26a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard 27a411595b169c1f136d09d114a458def1f99f91d9Jean Chalardimport java.util.ArrayList; 28a411595b169c1f136d09d114a458def1f99f91d9Jean Chalardimport java.util.HashMap; 29a411595b169c1f136d09d114a458def1f99f91d9Jean Chalardimport java.util.Random; 30a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard 31a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard/** 3294460eba11019ec4658c42b4bcc0379d70f41770Yuichiro Hanada * Unit tests for FusionDictionary. 33a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard */ 34a411595b169c1f136d09d114a458def1f99f91d9Jean Chalardpublic class FusionDictionaryTest extends TestCase { 35a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka private static final ArrayList<String> sWords = new ArrayList<>(); 36a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard private static final int MAX_UNIGRAMS = 1000; 37a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard 38a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard private void prepare(final long seed) { 39a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard System.out.println("Seed is " + seed); 40a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard final Random random = new Random(seed); 41a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard sWords.clear(); 42a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard generateWords(MAX_UNIGRAMS, random); 43a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard } 44a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard 45a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard /** 46a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard * Generates a random word. 47a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard */ 48a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard private String generateWord(final Random random) { 49a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard StringBuilder builder = new StringBuilder("a"); 50a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard int count = random.nextInt() % 30; 51a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard while (count > 0) { 52a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard final long r = Math.abs(random.nextInt()); 53a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard if (r < 0) continue; 54a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard // Don't insert 0~20, but insert any other code point. 55a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard // Code points are in the range 0~0x10FFFF. 56a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard if (builder.length() < 7) 57a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard builder.appendCodePoint((int)(20 +r % (0x10FFFF - 20))); 58a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard --count; 59a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard } 60a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard if (builder.length() == 1) return generateWord(random); 61a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard return builder.toString(); 62a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard } 63a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard 64a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard private void generateWords(final int number, final Random random) { 65a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard while (sWords.size() < number) { 66a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard sWords.add(generateWord(random)); 67a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard } 68a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard } 69a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard 705f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka private static void checkDictionary(final FusionDictionary dict, final ArrayList<String> words, 715f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka final int limit) { 72a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard assertNotNull(dict); 735f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka int count = limit; 74a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard for (final String word : words) { 755f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka if (--count < 0) return; 76576f625ee1b22e26baab46cc4ad3138e901383e2Yuichiro Hanada final PtNode ptNode = FusionDictionary.findWordInTree(dict.mRootNodeArray, word); 77576f625ee1b22e26baab46cc4ad3138e901383e2Yuichiro Hanada assertNotNull(ptNode); 78a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard } 79a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard } 80a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard 815f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka private static String dumpWord(final String word) { 82a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard final StringBuilder sb = new StringBuilder(""); 83a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard for (int i = 0; i < word.length(); i = word.offsetByCodePoints(i, 1)) { 84a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard sb.append(word.codePointAt(i)); 85a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard sb.append(" "); 86a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard } 87a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard return sb.toString(); 88a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard } 89a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard 905f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka private static void dumpDict(final FusionDictionary dict) { 915f5feeba13f6f1a907d90365d8037a361d0ff5daKeisuke Kuroyanagi for (WordProperty wordProperty : dict) { 925f5feeba13f6f1a907d90365d8037a361d0ff5daKeisuke Kuroyanagi System.out.println("Word " + dumpWord(wordProperty.mWord)); 93a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard } 94a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard } 95a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard 96a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard // Test the flattened array contains the expected number of nodes, and 97a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard // that it does not contain any duplicates. 98a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard public void testFusion() { 99af30cbf0ee8370763edf22822ea34a282e882084Jean Chalard final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), 1007b55cd3e2b4966150fa4c44dd43ebfeb77058a43Jean Chalard new DictionaryOptions(new HashMap<String, String>())); 101a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard final long time = System.currentTimeMillis(); 102a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard prepare(time); 103a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard for (int i = 0; i < sWords.size(); ++i) { 104a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard System.out.println("Adding in pos " + i + " : " + dumpWord(sWords.get(i))); 10505172bf1a5693c2e108e91436b98ecd35d2dadadAdrian Velicu dict.add(sWords.get(i), new ProbabilityInfo(180), null, false, 10605172bf1a5693c2e108e91436b98ecd35d2dadadAdrian Velicu false /* isPossiblyOffensive */); 107a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard dumpDict(dict); 108a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard checkDictionary(dict, sWords, i); 109a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard } 110a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard } 111a411595b169c1f136d09d114a458def1f99f91d9Jean Chalard} 112