diff options
author | 2013-12-13 17:09:16 +0900 | |
---|---|---|
committer | 2013-12-13 17:13:32 +0900 | |
commit | 2fa3693c264a4c150ac307d9bb7f6f8f18cc4ffc (patch) | |
tree | 56a5652edf71dd19d04161f72e3e013608cc2a9c /tests/src/com/android/inputmethod/latin | |
parent | 18d033405c18a8dc28f60ca22d1d0df23a679384 (diff) | |
download | latinime-2fa3693c264a4c150ac307d9bb7f6f8f18cc4ffc.tar.gz latinime-2fa3693c264a4c150ac307d9bb7f6f8f18cc4ffc.tar.xz latinime-2fa3693c264a4c150ac307d9bb7f6f8f18cc4ffc.zip |
Reset to 9bd6dac4708ad94fd0257c53e977df62b152e20c
The bulk merge from -bayo to klp-dev should not have been merged to master.
Change-Id: I527a03a76f5247e4939a672f27c314dc11cbb854
Diffstat (limited to 'tests/src/com/android/inputmethod/latin')
13 files changed, 1191 insertions, 526 deletions
diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java index cd5384ea4..e0276513a 100644 --- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java +++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryDecayingTests.java @@ -22,6 +22,7 @@ import android.util.Pair; import com.android.inputmethod.latin.makedict.CodePointUtils; import com.android.inputmethod.latin.makedict.FormatSpec; +import com.android.inputmethod.latin.utils.FileUtils; import java.io.File; import java.io.IOException; @@ -30,6 +31,7 @@ import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.Random; +import java.util.concurrent.TimeUnit; @LargeTest public class BinaryDictionaryDecayingTests extends AndroidTestCase { @@ -37,61 +39,146 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase { private static final String TEST_LOCALE = "test"; // Note that these are corresponding definitions in native code in - // latinime::DynamicPatriciaTriePolicy. - private static final String SET_NEEDS_TO_DECAY_FOR_TESTING_KEY = - "SET_NEEDS_TO_DECAY_FOR_TESTING"; + // latinime::Ver4PatriciaTriePolicy. + private static final String SET_CURRENT_TIME_FOR_TESTING_QUERY = + "SET_CURRENT_TIME_FOR_TESTING"; + private static final String GET_CURRENT_TIME_QUERY = "GET_CURRENT_TIME"; + private static final String QUIT_TIMEKEEPER_TEST_MODE_QUERY = "QUIT_TIMEKEEPER_TEST_MODE"; private static final int DUMMY_PROBABILITY = 0; + private int mCurrentTime = 0; + @Override protected void setUp() throws Exception { super.setUp(); + mCurrentTime = 0; } @Override protected void tearDown() throws Exception { super.tearDown(); + try { + final File dictFile = + createEmptyDictionaryAndGetFile("TestBinaryDictionary", FormatSpec.VERSION4); + final BinaryDictionary binaryDictionary = + new BinaryDictionary(dictFile.getAbsolutePath(), 0 /* offset */, + dictFile.length(), true /* useFullEditDistance */, Locale.getDefault(), + TEST_LOCALE, true /* isUpdatable */); + binaryDictionary.getPropertyForTests(QUIT_TIMEKEEPER_TEST_MODE_QUERY); + } catch (IOException e) { + fail("IOException while writing an initial dictionary : " + e); + } + } + + private void addUnigramWord(final BinaryDictionary binaryDictionary, final String word, + final int probability) { + binaryDictionary.addUnigramWord(word, probability, "" /* shortcutTarget */, + BinaryDictionary.NOT_A_PROBABILITY /* shortcutProbability */, + false /* isNotAWord */, false /* isBlacklisted */, + mCurrentTime /* timestamp */); + } + + private void addBigramWords(final BinaryDictionary binaryDictionary, final String word0, + final String word1, final int probability) { + binaryDictionary.addBigramWords(word0, word1, probability, + mCurrentTime /* timestamp */); } private void forcePassingShortTime(final BinaryDictionary binaryDictionary) { - // Entries having low probability would be suppressed once in 3 GCs. - final int count = 3; - for (int i = 0; i < count; i++) { - binaryDictionary.getPropertyForTests(SET_NEEDS_TO_DECAY_FOR_TESTING_KEY); - binaryDictionary.flushWithGC(); - } + // 4 days. + final int timeToElapse = (int)TimeUnit.SECONDS.convert(4, TimeUnit.DAYS); + mCurrentTime += timeToElapse; + setCurrentTime(binaryDictionary, mCurrentTime); + binaryDictionary.flushWithGC(); } private void forcePassingLongTime(final BinaryDictionary binaryDictionary) { - // Currently, probabilities are decayed when GC is run. All entries that have never been - // typed in 128 GCs would be removed. - final int count = 128; - for (int i = 0; i < count; i++) { - binaryDictionary.getPropertyForTests(SET_NEEDS_TO_DECAY_FOR_TESTING_KEY); - binaryDictionary.flushWithGC(); - } + // 60 days. + final int timeToElapse = (int)TimeUnit.SECONDS.convert(60, TimeUnit.DAYS); + mCurrentTime += timeToElapse; + setCurrentTime(binaryDictionary, mCurrentTime); + binaryDictionary.flushWithGC(); } - private File createEmptyDictionaryAndGetFile(final String filename) throws IOException { - final File file = File.createTempFile(filename, TEST_DICT_FILE_EXTENSION, + private File createEmptyDictionaryAndGetFile(final String dictId, + final int formatVersion) throws IOException { + if (formatVersion == FormatSpec.VERSION4) { + return createEmptyVer4DictionaryAndGetFile(dictId); + } else { + throw new IOException("Dictionary format version " + formatVersion + + " is not supported."); + } + } + private File createEmptyVer4DictionaryAndGetFile(final String dictId) throws IOException { + final File file = File.createTempFile(dictId, TEST_DICT_FILE_EXTENSION, getContext().getCacheDir()); + FileUtils.deleteRecursively(file); Map<String, String> attributeMap = new HashMap<String, String>(); attributeMap.put(FormatSpec.FileHeader.SUPPORTS_DYNAMIC_UPDATE_ATTRIBUTE, FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE); attributeMap.put(FormatSpec.FileHeader.USES_FORGETTING_CURVE_ATTRIBUTE, FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE); + attributeMap.put(FormatSpec.FileHeader.HAS_HISTORICAL_INFO_ATTRIBUTE, + FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE); + final String headerFileName = file.getName() + FormatSpec.HEADER_FILE_EXTENSION; if (BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(), - 3 /* dictVersion */, attributeMap)) { + FormatSpec.VERSION4, attributeMap)) { return file; } else { - throw new IOException("Empty dictionary cannot be created."); + throw new IOException("Empty dictionary " + file.getAbsolutePath() + " " + + headerFileName + " cannot be created."); } } + private static int getCurrentTime(final BinaryDictionary binaryDictionary) { + return Integer.parseInt(binaryDictionary.getPropertyForTests(GET_CURRENT_TIME_QUERY)); + } + + private static void setCurrentTime(final BinaryDictionary binaryDictionary, + final int currentTime) { + final String query = SET_CURRENT_TIME_FOR_TESTING_QUERY + ":" + currentTime; + binaryDictionary.getPropertyForTests(query); + } + + public void testControlCurrentTime() { + testControlCurrentTime(FormatSpec.VERSION4); + } + + private void testControlCurrentTime(final int formatVersion) { + final int TEST_COUNT = 1000; + final long seed = System.currentTimeMillis(); + final Random random = new Random(seed); + File dictFile = null; + try { + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); + } catch (IOException e) { + fail("IOException while writing an initial dictionary : " + e); + } + BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), + 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, + Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + binaryDictionary.getPropertyForTests(QUIT_TIMEKEEPER_TEST_MODE_QUERY); + final int startTime = getCurrentTime(binaryDictionary); + for (int i = 0; i < TEST_COUNT; i++) { + final int currentTime = random.nextInt(Integer.MAX_VALUE); + setCurrentTime(binaryDictionary, currentTime); + assertEquals(currentTime, getCurrentTime(binaryDictionary)); + } + binaryDictionary.getPropertyForTests(QUIT_TIMEKEEPER_TEST_MODE_QUERY); + final int endTime = getCurrentTime(binaryDictionary); + final int MAX_ALLOWED_ELAPSED_TIME = 10; + assertTrue(startTime <= endTime && endTime <= startTime + MAX_ALLOWED_ELAPSED_TIME); + } + public void testAddValidAndInvalidWords() { + testAddValidAndInvalidWords(FormatSpec.VERSION4); + } + + private void testAddValidAndInvalidWords(final int formatVersion) { File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } @@ -99,36 +186,35 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase { 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); - binaryDictionary.addUnigramWord("a", Dictionary.NOT_A_PROBABILITY); + addUnigramWord(binaryDictionary, "a", Dictionary.NOT_A_PROBABILITY); assertFalse(binaryDictionary.isValidWord("a")); - binaryDictionary.addUnigramWord("a", Dictionary.NOT_A_PROBABILITY); + addUnigramWord(binaryDictionary, "a", Dictionary.NOT_A_PROBABILITY); assertFalse(binaryDictionary.isValidWord("a")); - binaryDictionary.addUnigramWord("a", Dictionary.NOT_A_PROBABILITY); + addUnigramWord(binaryDictionary, "a", Dictionary.NOT_A_PROBABILITY); assertFalse(binaryDictionary.isValidWord("a")); - binaryDictionary.addUnigramWord("a", Dictionary.NOT_A_PROBABILITY); + addUnigramWord(binaryDictionary, "a", Dictionary.NOT_A_PROBABILITY); assertTrue(binaryDictionary.isValidWord("a")); - binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY); assertTrue(binaryDictionary.isValidWord("b")); - final int unigramProbability = binaryDictionary.getFrequency("a"); - binaryDictionary.addBigramWords("a", "b", Dictionary.NOT_A_PROBABILITY); + addBigramWords(binaryDictionary, "a", "b", Dictionary.NOT_A_PROBABILITY); assertFalse(binaryDictionary.isValidBigram("a", "b")); - binaryDictionary.addBigramWords("a", "b", Dictionary.NOT_A_PROBABILITY); + addBigramWords(binaryDictionary, "a", "b", Dictionary.NOT_A_PROBABILITY); assertFalse(binaryDictionary.isValidBigram("a", "b")); - binaryDictionary.addBigramWords("a", "b", Dictionary.NOT_A_PROBABILITY); + addBigramWords(binaryDictionary, "a", "b", Dictionary.NOT_A_PROBABILITY); assertFalse(binaryDictionary.isValidBigram("a", "b")); - binaryDictionary.addBigramWords("a", "b", Dictionary.NOT_A_PROBABILITY); + addBigramWords(binaryDictionary, "a", "b", Dictionary.NOT_A_PROBABILITY); assertTrue(binaryDictionary.isValidBigram("a", "b")); - binaryDictionary.addUnigramWord("c", DUMMY_PROBABILITY); - binaryDictionary.addBigramWords("a", "c", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "c", DUMMY_PROBABILITY); + addBigramWords(binaryDictionary, "a", "c", DUMMY_PROBABILITY); assertTrue(binaryDictionary.isValidBigram("a", "c")); // Add bigrams of not valid unigrams. - binaryDictionary.addBigramWords("x", "y", Dictionary.NOT_A_PROBABILITY); + addBigramWords(binaryDictionary, "x", "y", Dictionary.NOT_A_PROBABILITY); assertFalse(binaryDictionary.isValidBigram("x", "y")); - binaryDictionary.addBigramWords("x", "y", DUMMY_PROBABILITY); + addBigramWords(binaryDictionary, "x", "y", DUMMY_PROBABILITY); assertFalse(binaryDictionary.isValidBigram("x", "y")); binaryDictionary.close(); @@ -136,9 +222,13 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase { } public void testDecayingProbability() { + testDecayingProbability(FormatSpec.VERSION4); + } + + private void testDecayingProbability(final int formatVersion) { File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } @@ -146,39 +236,44 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase { 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); - binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY); assertTrue(binaryDictionary.isValidWord("a")); forcePassingShortTime(binaryDictionary); assertFalse(binaryDictionary.isValidWord("a")); - binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY); - binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY); - binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY); - binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY); + assertTrue(binaryDictionary.isValidWord("a")); forcePassingShortTime(binaryDictionary); assertTrue(binaryDictionary.isValidWord("a")); forcePassingLongTime(binaryDictionary); assertFalse(binaryDictionary.isValidWord("a")); - binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY); - binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY); - binaryDictionary.addBigramWords("a", "b", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY); + addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY); assertTrue(binaryDictionary.isValidBigram("a", "b")); forcePassingShortTime(binaryDictionary); assertFalse(binaryDictionary.isValidBigram("a", "b")); - binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY); - binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY); - binaryDictionary.addBigramWords("a", "b", DUMMY_PROBABILITY); - binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY); - binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY); - binaryDictionary.addBigramWords("a", "b", DUMMY_PROBABILITY); - binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY); - binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY); - binaryDictionary.addBigramWords("a", "b", DUMMY_PROBABILITY); - binaryDictionary.addUnigramWord("a", DUMMY_PROBABILITY); - binaryDictionary.addUnigramWord("b", DUMMY_PROBABILITY); - binaryDictionary.addBigramWords("a", "b", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY); + addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY); + addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY); + addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY); + addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "a", DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, "b", DUMMY_PROBABILITY); + addBigramWords(binaryDictionary, "a", "b", DUMMY_PROBABILITY); assertTrue(binaryDictionary.isValidBigram("a", "b")); forcePassingShortTime(binaryDictionary); assertTrue(binaryDictionary.isValidBigram("a", "b")); @@ -190,6 +285,10 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase { } public void testAddManyUnigramsToDecayingDict() { + testAddManyUnigramsToDecayingDict(FormatSpec.VERSION4); + } + + private void testAddManyUnigramsToDecayingDict(final int formatVersion) { final int unigramCount = 30000; final int unigramTypedCount = 100000; final int codePointSetSize = 50; @@ -198,13 +297,14 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase { File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + setCurrentTime(binaryDictionary, mCurrentTime); final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); final ArrayList<String> words = new ArrayList<String>(); @@ -218,14 +318,14 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase { binaryDictionary.getPropertyForTests(BinaryDictionary.MAX_UNIGRAM_COUNT_QUERY)); for (int i = 0; i < unigramTypedCount; i++) { final String word = words.get(random.nextInt(words.size())); - binaryDictionary.addUnigramWord(word, DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, word, DUMMY_PROBABILITY); if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { final int unigramCountBeforeGC = Integer.parseInt(binaryDictionary.getPropertyForTests( BinaryDictionary.UNIGRAM_COUNT_QUERY)); while (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { - binaryDictionary.flushWithGC(); + forcePassingShortTime(binaryDictionary); } final int unigramCountAfterGC = Integer.parseInt(binaryDictionary.getPropertyForTests( @@ -238,9 +338,75 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase { BinaryDictionary.UNIGRAM_COUNT_QUERY)) > 0); assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTests( BinaryDictionary.UNIGRAM_COUNT_QUERY)) <= maxUnigramCount); + forcePassingLongTime(binaryDictionary); + assertEquals(0, Integer.parseInt(binaryDictionary.getPropertyForTests( + BinaryDictionary.UNIGRAM_COUNT_QUERY))); + } + + public void testOverflowUnigrams() { + testOverflowUnigrams(FormatSpec.VERSION4); + } + + private void testOverflowUnigrams(final int formatVersion) { + final int unigramCount = 20000; + final int eachUnigramTypedCount = 5; + final int strongUnigramTypedCount = 20; + final int weakUnigramTypedCount = 1; + final int codePointSetSize = 50; + final long seed = System.currentTimeMillis(); + final Random random = new Random(seed); + + File dictFile = null; + try { + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); + } catch (IOException e) { + fail("IOException while writing an initial dictionary : " + e); + } + BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), + 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, + Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + setCurrentTime(binaryDictionary, mCurrentTime); + final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); + + final String strong = "strong"; + final String weak = "weak"; + for (int j = 0; j < strongUnigramTypedCount; j++) { + addUnigramWord(binaryDictionary, strong, DUMMY_PROBABILITY); + } + for (int j = 0; j < weakUnigramTypedCount; j++) { + addUnigramWord(binaryDictionary, weak, DUMMY_PROBABILITY); + } + assertTrue(binaryDictionary.isValidWord(strong)); + assertTrue(binaryDictionary.isValidWord(weak)); + + for (int i = 0; i < unigramCount; i++) { + final String word = CodePointUtils.generateWord(random, codePointSet); + for (int j = 0; j < eachUnigramTypedCount; j++) { + addUnigramWord(binaryDictionary, word, DUMMY_PROBABILITY); + } + if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { + final int unigramCountBeforeGC = + Integer.parseInt(binaryDictionary.getPropertyForTests( + BinaryDictionary.UNIGRAM_COUNT_QUERY)); + assertTrue(binaryDictionary.isValidWord(strong)); + assertTrue(binaryDictionary.isValidWord(weak)); + binaryDictionary.flushWithGC(); + final int unigramCountAfterGC = + Integer.parseInt(binaryDictionary.getPropertyForTests( + BinaryDictionary.UNIGRAM_COUNT_QUERY)); + assertTrue(unigramCountBeforeGC > unigramCountAfterGC); + assertFalse(binaryDictionary.isValidWord(weak)); + assertTrue(binaryDictionary.isValidWord(strong)); + break; + } + } } public void testAddManyBigramsToDecayingDict() { + testAddManyBigramsToDecayingDict(FormatSpec.VERSION4); + } + + private void testAddManyBigramsToDecayingDict(final int formatVersion) { final int unigramCount = 5000; final int bigramCount = 30000; final int bigramTypedCount = 100000; @@ -250,13 +416,14 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase { File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + setCurrentTime(binaryDictionary, mCurrentTime); final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); final ArrayList<String> words = new ArrayList<String>(); @@ -282,16 +449,16 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase { binaryDictionary.getPropertyForTests(BinaryDictionary.MAX_BIGRAM_COUNT_QUERY)); for (int i = 0; i < bigramTypedCount; ++i) { final Pair<String, String> bigram = bigrams.get(random.nextInt(bigrams.size())); - binaryDictionary.addUnigramWord(bigram.first, DUMMY_PROBABILITY); - binaryDictionary.addUnigramWord(bigram.second, DUMMY_PROBABILITY); - binaryDictionary.addBigramWords(bigram.first, bigram.second, DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, bigram.first, DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, bigram.second, DUMMY_PROBABILITY); + addBigramWords(binaryDictionary, bigram.first, bigram.second, DUMMY_PROBABILITY); if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { final int bigramCountBeforeGC = Integer.parseInt(binaryDictionary.getPropertyForTests( BinaryDictionary.BIGRAM_COUNT_QUERY)); while (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { - binaryDictionary.flushWithGC(); + forcePassingShortTime(binaryDictionary); } final int bigramCountAfterGC = Integer.parseInt(binaryDictionary.getPropertyForTests( @@ -304,5 +471,87 @@ public class BinaryDictionaryDecayingTests extends AndroidTestCase { BinaryDictionary.BIGRAM_COUNT_QUERY)) > 0); assertTrue(Integer.parseInt(binaryDictionary.getPropertyForTests( BinaryDictionary.BIGRAM_COUNT_QUERY)) <= maxBigramCount); + forcePassingLongTime(binaryDictionary); + assertEquals(0, Integer.parseInt(binaryDictionary.getPropertyForTests( + BinaryDictionary.BIGRAM_COUNT_QUERY))); + } + + public void testOverflowBigrams() { + testOverflowBigrams(FormatSpec.VERSION4); + } + + private void testOverflowBigrams(final int formatVersion) { + final int bigramCount = 20000; + final int unigramCount = 1000; + final int unigramTypedCount = 20; + final int eachBigramTypedCount = 5; + final int strongBigramTypedCount = 20; + final int weakBigramTypedCount = 1; + final int codePointSetSize = 50; + final long seed = System.currentTimeMillis(); + final Random random = new Random(seed); + + File dictFile = null; + try { + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); + } catch (IOException e) { + fail("IOException while writing an initial dictionary : " + e); + } + BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), + 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, + Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + setCurrentTime(binaryDictionary, mCurrentTime); + final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); + + final ArrayList<String> words = new ArrayList<String>(); + for (int i = 0; i < unigramCount; i++) { + final String word = CodePointUtils.generateWord(random, codePointSet); + words.add(word); + for (int j = 0; j < unigramTypedCount; j++) { + addUnigramWord(binaryDictionary, word, DUMMY_PROBABILITY); + } + } + final String strong = "strong"; + final String weak = "weak"; + final String target = "target"; + for (int j = 0; j < unigramTypedCount; j++) { + addUnigramWord(binaryDictionary, strong, DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, weak, DUMMY_PROBABILITY); + addUnigramWord(binaryDictionary, target, DUMMY_PROBABILITY); + } + binaryDictionary.flushWithGC(); + for (int j = 0; j < strongBigramTypedCount; j++) { + addBigramWords(binaryDictionary, strong, target, DUMMY_PROBABILITY); + } + for (int j = 0; j < weakBigramTypedCount; j++) { + addBigramWords(binaryDictionary, weak, target, DUMMY_PROBABILITY); + } + assertTrue(binaryDictionary.isValidBigram(strong, target)); + assertTrue(binaryDictionary.isValidBigram(weak, target)); + + for (int i = 0; i < bigramCount; i++) { + final int word0Index = random.nextInt(words.size()); + final String word0 = words.get(word0Index); + final int index = random.nextInt(words.size() - 1); + final int word1Index = (index >= word0Index) ? index + 1 : index; + final String word1 = words.get(word1Index); + + for (int j = 0; j < eachBigramTypedCount; j++) { + addBigramWords(binaryDictionary, word0, word1, DUMMY_PROBABILITY); + } + if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { + final int bigramCountBeforeGC = + Integer.parseInt(binaryDictionary.getPropertyForTests( + BinaryDictionary.BIGRAM_COUNT_QUERY)); + binaryDictionary.flushWithGC(); + final int bigramCountAfterGC = + Integer.parseInt(binaryDictionary.getPropertyForTests( + BinaryDictionary.BIGRAM_COUNT_QUERY)); + assertTrue(bigramCountBeforeGC > bigramCountAfterGC); + assertTrue(binaryDictionary.isValidBigram(strong, target)); + assertFalse(binaryDictionary.isValidBigram(weak, target)); + break; + } + } } } diff --git a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java index 5b8f0e977..cfc4c762a 100644 --- a/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java +++ b/tests/src/com/android/inputmethod/latin/BinaryDictionaryTests.java @@ -21,8 +21,12 @@ import android.test.suitebuilder.annotation.LargeTest; import android.text.TextUtils; import android.util.Pair; +import com.android.inputmethod.latin.BinaryDictionary.LanguageModelParam; import com.android.inputmethod.latin.makedict.CodePointUtils; import com.android.inputmethod.latin.makedict.FormatSpec; +import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString; +import com.android.inputmethod.latin.utils.FileUtils; +import com.android.inputmethod.latin.utils.UnigramProperty; import java.io.File; import java.io.IOException; @@ -33,6 +37,7 @@ import java.util.Locale; import java.util.Map; import java.util.Random; +// TODO Use the seed passed as an argument for makedict test. @LargeTest public class BinaryDictionaryTests extends AndroidTestCase { private static final String TEST_DICT_FILE_EXTENSION = ".testDict"; @@ -48,24 +53,41 @@ public class BinaryDictionaryTests extends AndroidTestCase { super.tearDown(); } - private File createEmptyDictionaryAndGetFile(final String filename) throws IOException { - final File file = File.createTempFile(filename, TEST_DICT_FILE_EXTENSION, + private File createEmptyDictionaryAndGetFile(final String dictId, + final int formatVersion) throws IOException { + if (formatVersion == FormatSpec.VERSION4) { + return createEmptyVer4DictionaryAndGetFile(dictId); + } else { + throw new IOException("Dictionary format version " + formatVersion + + " is not supported."); + } + } + + private File createEmptyVer4DictionaryAndGetFile(final String dictId) throws IOException { + final File file = File.createTempFile(dictId, TEST_DICT_FILE_EXTENSION, getContext().getCacheDir()); + file.delete(); + file.mkdir(); Map<String, String> attributeMap = new HashMap<String, String>(); attributeMap.put(FormatSpec.FileHeader.SUPPORTS_DYNAMIC_UPDATE_ATTRIBUTE, FormatSpec.FileHeader.ATTRIBUTE_VALUE_TRUE); if (BinaryDictionary.createEmptyDictFile(file.getAbsolutePath(), - 3 /* dictVersion */, attributeMap)) { + FormatSpec.VERSION4, attributeMap)) { return file; } else { - throw new IOException("Empty dictionary cannot be created."); + throw new IOException("Empty dictionary " + file.getAbsolutePath() + + " cannot be created."); } } public void testIsValidDictionary() { + testIsValidDictionary(FormatSpec.VERSION4); + } + + private void testIsValidDictionary(final int formatVersion) { File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } @@ -77,7 +99,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { binaryDictionary.close(); assertFalse("binaryDictionary must be invalid after closing.", binaryDictionary.isValidDictionary()); - dictFile.delete(); + FileUtils.deleteRecursively(dictFile); binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); @@ -86,10 +108,28 @@ public class BinaryDictionaryTests extends AndroidTestCase { binaryDictionary.close(); } + private void addUnigramWord(final BinaryDictionary binaryDictionary, final String word, + final int probability) { + binaryDictionary.addUnigramWord(word, probability, "" /* shortcutTarget */, + BinaryDictionary.NOT_A_PROBABILITY /* shortcutProbability */, + false /* isNotAWord */, false /* isBlacklisted */, + BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); + } + + private void addBigramWords(final BinaryDictionary binaryDictionary, final String word0, + final String word1, final int probability) { + binaryDictionary.addBigramWords(word0, word1, probability, + BinaryDictionary.NOT_A_VALID_TIMESTAMP /* timestamp */); + } + public void testAddUnigramWord() { + testAddUnigramWord(FormatSpec.VERSION4); + } + + private void testAddUnigramWord(final int formatVersion) { File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } @@ -98,21 +138,21 @@ public class BinaryDictionaryTests extends AndroidTestCase { Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); final int probability = 100; - binaryDictionary.addUnigramWord("aaa", probability); + addUnigramWord(binaryDictionary, "aaa", probability); // Reallocate and create. - binaryDictionary.addUnigramWord("aab", probability); + addUnigramWord(binaryDictionary, "aab", probability); // Insert into children. - binaryDictionary.addUnigramWord("aac", probability); + addUnigramWord(binaryDictionary, "aac", probability); // Make terminal. - binaryDictionary.addUnigramWord("aa", probability); + addUnigramWord(binaryDictionary, "aa", probability); // Create children. - binaryDictionary.addUnigramWord("aaaa", probability); + addUnigramWord(binaryDictionary, "aaaa", probability); // Reallocate and make termianl. - binaryDictionary.addUnigramWord("a", probability); + addUnigramWord(binaryDictionary, "a", probability); final int updatedProbability = 200; // Update. - binaryDictionary.addUnigramWord("aaa", updatedProbability); + addUnigramWord(binaryDictionary, "aaa", updatedProbability); assertEquals(probability, binaryDictionary.getFrequency("aab")); assertEquals(probability, binaryDictionary.getFrequency("aac")); @@ -125,13 +165,17 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testRandomlyAddUnigramWord() { + testRandomlyAddUnigramWord(FormatSpec.VERSION4); + } + + private void testRandomlyAddUnigramWord(final int formatVersion) { final int wordCount = 1000; final int codePointSetSize = 50; final long seed = System.currentTimeMillis(); File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } @@ -148,7 +192,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { probabilityMap.put(word, random.nextInt(0xFF)); } for (String word : probabilityMap.keySet()) { - binaryDictionary.addUnigramWord(word, probabilityMap.get(word)); + addUnigramWord(binaryDictionary, word, probabilityMap.get(word)); } for (String word : probabilityMap.keySet()) { assertEquals(word, (int)probabilityMap.get(word), binaryDictionary.getFrequency(word)); @@ -157,9 +201,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testAddBigramWords() { + testAddBigramWords(FormatSpec.VERSION4); + } + + private void testAddBigramWords(final int formatVersion) { File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } @@ -170,13 +218,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { final int unigramProbability = 100; final int bigramProbability = 10; final int updatedBigramProbability = 15; - binaryDictionary.addUnigramWord("aaa", unigramProbability); - binaryDictionary.addUnigramWord("abb", unigramProbability); - binaryDictionary.addUnigramWord("bcc", unigramProbability); - binaryDictionary.addBigramWords("aaa", "abb", bigramProbability); - binaryDictionary.addBigramWords("aaa", "bcc", bigramProbability); - binaryDictionary.addBigramWords("abb", "aaa", bigramProbability); - binaryDictionary.addBigramWords("abb", "bcc", bigramProbability); + addUnigramWord(binaryDictionary, "aaa", unigramProbability); + addUnigramWord(binaryDictionary, "abb", unigramProbability); + addUnigramWord(binaryDictionary, "bcc", unigramProbability); + addBigramWords(binaryDictionary, "aaa", "abb", bigramProbability); + addBigramWords(binaryDictionary, "aaa", "bcc", bigramProbability); + addBigramWords(binaryDictionary, "abb", "aaa", bigramProbability); + addBigramWords(binaryDictionary, "abb", "bcc", bigramProbability); final int probability = binaryDictionary.calculateProbability(unigramProbability, bigramProbability); @@ -189,7 +237,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { assertEquals(probability, binaryDictionary.getBigramProbability("abb", "aaa")); assertEquals(probability, binaryDictionary.getBigramProbability("abb", "bcc")); - binaryDictionary.addBigramWords("aaa", "abb", updatedBigramProbability); + addBigramWords(binaryDictionary, "aaa", "abb", updatedBigramProbability); final int updatedProbability = binaryDictionary.calculateProbability(unigramProbability, updatedBigramProbability); assertEquals(updatedProbability, binaryDictionary.getBigramProbability("aaa", "abb")); @@ -205,22 +253,26 @@ public class BinaryDictionaryTests extends AndroidTestCase { binaryDictionary.getBigramProbability("aaa", "aaa")); // Testing bigram link. - binaryDictionary.addUnigramWord("abcde", unigramProbability); - binaryDictionary.addUnigramWord("fghij", unigramProbability); - binaryDictionary.addBigramWords("abcde", "fghij", bigramProbability); - binaryDictionary.addUnigramWord("fgh", unigramProbability); - binaryDictionary.addUnigramWord("abc", unigramProbability); - binaryDictionary.addUnigramWord("f", unigramProbability); + addUnigramWord(binaryDictionary, "abcde", unigramProbability); + addUnigramWord(binaryDictionary, "fghij", unigramProbability); + addBigramWords(binaryDictionary, "abcde", "fghij", bigramProbability); + addUnigramWord(binaryDictionary, "fgh", unigramProbability); + addUnigramWord(binaryDictionary, "abc", unigramProbability); + addUnigramWord(binaryDictionary, "f", unigramProbability); assertEquals(probability, binaryDictionary.getBigramProbability("abcde", "fghij")); assertEquals(Dictionary.NOT_A_PROBABILITY, binaryDictionary.getBigramProbability("abcde", "fgh")); - binaryDictionary.addBigramWords("abcde", "fghij", updatedBigramProbability); + addBigramWords(binaryDictionary, "abcde", "fghij", updatedBigramProbability); assertEquals(updatedProbability, binaryDictionary.getBigramProbability("abcde", "fghij")); dictFile.delete(); } public void testRandomlyAddBigramWords() { + testRandomlyAddBigramWords(FormatSpec.VERSION4); + } + + private void testRandomlyAddBigramWords(final int formatVersion) { final int wordCount = 100; final int bigramCount = 1000; final int codePointSetSize = 50; @@ -229,7 +281,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } @@ -249,7 +301,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { words.add(word); final int unigramProbability = random.nextInt(0xFF); unigramProbabilities.put(word, unigramProbability); - binaryDictionary.addUnigramWord(word, unigramProbability); + addUnigramWord(binaryDictionary, word, unigramProbability); } for (int i = 0; i < bigramCount; i++) { @@ -262,7 +314,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { bigramWords.add(bigram); final int bigramProbability = random.nextInt(0xF); bigramProbabilities.put(bigram, bigramProbability); - binaryDictionary.addBigramWords(word0, word1, bigramProbability); + addBigramWords(binaryDictionary, word0, word1, bigramProbability); } for (final Pair<String, String> bigram : bigramWords) { @@ -278,9 +330,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testRemoveBigramWords() { + testRemoveBigramWords(FormatSpec.VERSION4); + } + + private void testRemoveBigramWords(final int formatVersion) { File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } @@ -289,13 +345,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); final int unigramProbability = 100; final int bigramProbability = 10; - binaryDictionary.addUnigramWord("aaa", unigramProbability); - binaryDictionary.addUnigramWord("abb", unigramProbability); - binaryDictionary.addUnigramWord("bcc", unigramProbability); - binaryDictionary.addBigramWords("aaa", "abb", bigramProbability); - binaryDictionary.addBigramWords("aaa", "bcc", bigramProbability); - binaryDictionary.addBigramWords("abb", "aaa", bigramProbability); - binaryDictionary.addBigramWords("abb", "bcc", bigramProbability); + addUnigramWord(binaryDictionary, "aaa", unigramProbability); + addUnigramWord(binaryDictionary, "abb", unigramProbability); + addUnigramWord(binaryDictionary, "bcc", unigramProbability); + addBigramWords(binaryDictionary, "aaa", "abb", bigramProbability); + addBigramWords(binaryDictionary, "aaa", "bcc", bigramProbability); + addBigramWords(binaryDictionary, "abb", "aaa", bigramProbability); + addBigramWords(binaryDictionary, "abb", "bcc", bigramProbability); assertEquals(true, binaryDictionary.isValidBigram("aaa", "abb")); assertEquals(true, binaryDictionary.isValidBigram("aaa", "bcc")); @@ -304,7 +360,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { binaryDictionary.removeBigramWords("aaa", "abb"); assertEquals(false, binaryDictionary.isValidBigram("aaa", "abb")); - binaryDictionary.addBigramWords("aaa", "abb", bigramProbability); + addBigramWords(binaryDictionary, "aaa", "abb", bigramProbability); assertEquals(true, binaryDictionary.isValidBigram("aaa", "abb")); @@ -324,9 +380,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testFlushDictionary() { + testFlushDictionary(FormatSpec.VERSION4); + } + + private void testFlushDictionary(final int formatVersion) { File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } @@ -335,8 +395,8 @@ public class BinaryDictionaryTests extends AndroidTestCase { Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); final int probability = 100; - binaryDictionary.addUnigramWord("aaa", probability); - binaryDictionary.addUnigramWord("abcd", probability); + addUnigramWord(binaryDictionary, "aaa", probability); + addUnigramWord(binaryDictionary, "abcd", probability); // Close without flushing. binaryDictionary.close(); @@ -347,8 +407,8 @@ public class BinaryDictionaryTests extends AndroidTestCase { assertEquals(Dictionary.NOT_A_PROBABILITY, binaryDictionary.getFrequency("aaa")); assertEquals(Dictionary.NOT_A_PROBABILITY, binaryDictionary.getFrequency("abcd")); - binaryDictionary.addUnigramWord("aaa", probability); - binaryDictionary.addUnigramWord("abcd", probability); + addUnigramWord(binaryDictionary, "aaa", probability); + addUnigramWord(binaryDictionary, "abcd", probability); binaryDictionary.flush(); binaryDictionary.close(); @@ -358,7 +418,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { assertEquals(probability, binaryDictionary.getFrequency("aaa")); assertEquals(probability, binaryDictionary.getFrequency("abcd")); - binaryDictionary.addUnigramWord("bcde", probability); + addUnigramWord(binaryDictionary, "bcde", probability); binaryDictionary.flush(); binaryDictionary.close(); @@ -372,9 +432,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testFlushWithGCDictionary() { + testFlushWithGCDictionary(FormatSpec.VERSION4); + } + + private void testFlushWithGCDictionary(final int formatVersion) { File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } @@ -384,13 +448,13 @@ public class BinaryDictionaryTests extends AndroidTestCase { final int unigramProbability = 100; final int bigramProbability = 10; - binaryDictionary.addUnigramWord("aaa", unigramProbability); - binaryDictionary.addUnigramWord("abb", unigramProbability); - binaryDictionary.addUnigramWord("bcc", unigramProbability); - binaryDictionary.addBigramWords("aaa", "abb", bigramProbability); - binaryDictionary.addBigramWords("aaa", "bcc", bigramProbability); - binaryDictionary.addBigramWords("abb", "aaa", bigramProbability); - binaryDictionary.addBigramWords("abb", "bcc", bigramProbability); + addUnigramWord(binaryDictionary, "aaa", unigramProbability); + addUnigramWord(binaryDictionary, "abb", unigramProbability); + addUnigramWord(binaryDictionary, "bcc", unigramProbability); + addBigramWords(binaryDictionary, "aaa", "abb", bigramProbability); + addBigramWords(binaryDictionary, "aaa", "bcc", bigramProbability); + addBigramWords(binaryDictionary, "abb", "aaa", bigramProbability); + addBigramWords(binaryDictionary, "abb", "bcc", bigramProbability); binaryDictionary.flushWithGC(); binaryDictionary.close(); @@ -415,8 +479,12 @@ public class BinaryDictionaryTests extends AndroidTestCase { dictFile.delete(); } - // TODO: Evaluate performance of GC public void testAddBigramWordsAndFlashWithGC() { + testAddBigramWordsAndFlashWithGC(FormatSpec.VERSION4); + } + + // TODO: Evaluate performance of GC + private void testAddBigramWordsAndFlashWithGC(final int formatVersion) { final int wordCount = 100; final int bigramCount = 1000; final int codePointSetSize = 30; @@ -425,7 +493,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } @@ -446,7 +514,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { words.add(word); final int unigramProbability = random.nextInt(0xFF); unigramProbabilities.put(word, unigramProbability); - binaryDictionary.addUnigramWord(word, unigramProbability); + addUnigramWord(binaryDictionary, word, unigramProbability); } for (int i = 0; i < bigramCount; i++) { @@ -459,7 +527,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { bigramWords.add(bigram); final int bigramProbability = random.nextInt(0xF); bigramProbabilities.put(bigram, bigramProbability); - binaryDictionary.addBigramWords(word0, word1, bigramProbability); + addBigramWords(binaryDictionary, word0, word1, bigramProbability); } binaryDictionary.flushWithGC(); @@ -480,7 +548,11 @@ public class BinaryDictionaryTests extends AndroidTestCase { dictFile.delete(); } - public void testRandomOperetionsAndFlashWithGC() { + public void testRandomOperationsAndFlashWithGC() { + testRandomOperationsAndFlashWithGC(FormatSpec.VERSION4); + } + + private void testRandomOperationsAndFlashWithGC(final int formatVersion) { final int flashWithGCIterationCount = 50; final int operationCountInEachIteration = 200; final int initialUnigramCount = 100; @@ -494,7 +566,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } @@ -513,7 +585,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { words.add(word); final int unigramProbability = random.nextInt(0xFF); unigramProbabilities.put(word, unigramProbability); - binaryDictionary.addUnigramWord(word, unigramProbability); + addUnigramWord(binaryDictionary, word, unigramProbability); } binaryDictionary.flushWithGC(); binaryDictionary.close(); @@ -529,7 +601,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { words.add(word); final int unigramProbability = random.nextInt(0xFF); unigramProbabilities.put(word, unigramProbability); - binaryDictionary.addUnigramWord(word, unigramProbability); + addUnigramWord(binaryDictionary, word, unigramProbability); } // Add bigram. if (random.nextFloat() < addBigramProb && words.size() > 2) { @@ -547,7 +619,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { final Pair<String, String> bigram = new Pair<String, String>(word0, word1); bigramWords.add(bigram); bigramProbabilities.put(bigram, bigramProbability); - binaryDictionary.addBigramWords(word0, word1, bigramProbability); + addBigramWords(binaryDictionary, word0, word1, bigramProbability); } // Remove bigram. if (random.nextFloat() < removeBigramProb && !bigramWords.isEmpty()) { @@ -588,6 +660,10 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testAddManyUnigramsAndFlushWithGC() { + testAddManyUnigramsAndFlushWithGC(FormatSpec.VERSION4); + } + + private void testAddManyUnigramsAndFlushWithGC(final int formatVersion) { final int flashWithGCIterationCount = 3; final int codePointSetSize = 50; @@ -596,7 +672,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } @@ -615,7 +691,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { words.add(word); final int unigramProbability = random.nextInt(0xFF); unigramProbabilities.put(word, unigramProbability); - binaryDictionary.addUnigramWord(word, unigramProbability); + addUnigramWord(binaryDictionary, word, unigramProbability); } for (int j = 0; j < words.size(); j++) { @@ -632,6 +708,10 @@ public class BinaryDictionaryTests extends AndroidTestCase { } public void testUnigramAndBigramCount() { + testUnigramAndBigramCount(FormatSpec.VERSION4); + } + + private void testUnigramAndBigramCount(final int formatVersion) { final int flashWithGCIterationCount = 10; final int codePointSetSize = 50; final int unigramCountPerIteration = 1000; @@ -641,7 +721,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { File dictFile = null; try { - dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary"); + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } @@ -659,7 +739,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { final String word = CodePointUtils.generateWord(random, codePointSet); words.add(word); final int unigramProbability = random.nextInt(0xFF); - binaryDictionary.addUnigramWord(word, unigramProbability); + addUnigramWord(binaryDictionary, word, unigramProbability); } for (int j = 0; j < bigramCountPerIteration; j++) { final String word0 = words.get(random.nextInt(words.size())); @@ -669,7 +749,7 @@ public class BinaryDictionaryTests extends AndroidTestCase { } bigrams.add(new Pair<String, String>(word0, word1)); final int bigramProbability = random.nextInt(0xF); - binaryDictionary.addBigramWords(word0, word1, bigramProbability); + addBigramWords(binaryDictionary, word0, word1, bigramProbability); } assertEquals(new HashSet<String>(words).size(), Integer.parseInt( binaryDictionary.getPropertyForTests(BinaryDictionary.UNIGRAM_COUNT_QUERY))); @@ -685,4 +765,242 @@ public class BinaryDictionaryTests extends AndroidTestCase { dictFile.delete(); } + + public void testAddMultipleDictionaryEntries() { + testAddMultipleDictionaryEntries(FormatSpec.VERSION4); + } + + private void testAddMultipleDictionaryEntries(final int formatVersion) { + final int codePointSetSize = 20; + final int lmParamCount = 1000; + final double bigramContinueRate = 0.9; + final long seed = System.currentTimeMillis(); + final Random random = new Random(seed); + + File dictFile = null; + try { + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); + } catch (IOException e) { + fail("IOException while writing an initial dictionary : " + e); + } + + final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); + final HashMap<String, Integer> unigramProbabilities = new HashMap<String, Integer>(); + final HashMap<Pair<String, String>, Integer> bigramProbabilities = + new HashMap<Pair<String, String>, Integer>(); + + final LanguageModelParam[] languageModelParams = new LanguageModelParam[lmParamCount]; + String prevWord = null; + for (int i = 0; i < languageModelParams.length; i++) { + final String word = CodePointUtils.generateWord(random, codePointSet); + final int probability = random.nextInt(0xFF); + final int bigramProbability = random.nextInt(0xF); + unigramProbabilities.put(word, probability); + if (prevWord == null) { + languageModelParams[i] = new LanguageModelParam(word, probability, + BinaryDictionary.NOT_A_VALID_TIMESTAMP); + } else { + languageModelParams[i] = new LanguageModelParam(prevWord, word, probability, + bigramProbability, BinaryDictionary.NOT_A_VALID_TIMESTAMP); + bigramProbabilities.put(new Pair<String, String>(prevWord, word), + bigramProbability); + } + prevWord = (random.nextDouble() < bigramContinueRate) ? word : null; + } + + final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), + 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, + Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + binaryDictionary.addMultipleDictionaryEntries(languageModelParams); + + for (Map.Entry<String, Integer> entry : unigramProbabilities.entrySet()) { + assertEquals((int)entry.getValue(), binaryDictionary.getFrequency(entry.getKey())); + } + + for (Map.Entry<Pair<String, String>, Integer> entry : bigramProbabilities.entrySet()) { + final String word0 = entry.getKey().first; + final String word1 = entry.getKey().second; + final int unigramProbability = unigramProbabilities.get(word1); + final int bigramProbability = entry.getValue(); + final int probability = binaryDictionary.calculateProbability( + unigramProbability, bigramProbability); + assertEquals(probability, binaryDictionary.getBigramProbability(word0, word1)); + } + } + + public void testGetUnigramProperties() { + testGetUnigramProperties(FormatSpec.VERSION4); + } + + private void testGetUnigramProperties(final int formatVersion) { + final long seed = System.currentTimeMillis(); + final Random random = new Random(seed); + final int ITERATION_COUNT = 1000; + final int codePointSetSize = 20; + final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); + + File dictFile = null; + try { + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); + } catch (IOException e) { + fail("IOException while writing an initial dictionary : " + e); + } + final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), + 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, + Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + + final UnigramProperty invalidUnigramProperty = + binaryDictionary.getUnigramProperty("dummyWord"); + assertFalse(invalidUnigramProperty.isValid()); + + for (int i = 0; i < ITERATION_COUNT; i++) { + final String word = CodePointUtils.generateWord(random, codePointSet); + final int unigramProbability = random.nextInt(0xFF); + final boolean isNotAWord = random.nextBoolean(); + final boolean isBlacklisted = random.nextBoolean(); + // TODO: Add tests for historical info. + binaryDictionary.addUnigramWord(word, unigramProbability, + null /* shortcutTarget */, BinaryDictionary.NOT_A_PROBABILITY, + isNotAWord, isBlacklisted, BinaryDictionary.NOT_A_VALID_TIMESTAMP); + final UnigramProperty unigramProperty = + binaryDictionary.getUnigramProperty(word); + assertEquals(word, unigramProperty.mCodePoints); + assertTrue(unigramProperty.isValid()); + assertEquals(isNotAWord, unigramProperty.mIsNotAWord); + assertEquals(isBlacklisted, unigramProperty.mIsBlacklisted); + assertEquals(false, unigramProperty.mHasBigrams); + assertEquals(false, unigramProperty.mHasShortcuts); + assertEquals(unigramProbability, unigramProperty.mProbability); + assertTrue(unigramProperty.mShortcutTargets.isEmpty()); + } + } + + public void testAddShortcuts() { + testAddShortcuts(FormatSpec.VERSION4); + } + + private void testAddShortcuts(final int formatVersion) { + File dictFile = null; + try { + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); + } catch (IOException e) { + fail("IOException while writing an initial dictionary : " + e); + } + final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), + 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, + Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + + final int unigramProbability = 100; + final int shortcutProbability = 10; + binaryDictionary.addUnigramWord("aaa", unigramProbability, "zzz", + shortcutProbability, false /* isNotAWord */, false /* isBlacklisted */, + 0 /* timestamp */); + UnigramProperty unigramProperty = binaryDictionary.getUnigramProperty("aaa"); + assertEquals(1, unigramProperty.mShortcutTargets.size()); + assertEquals("zzz", unigramProperty.mShortcutTargets.get(0).mWord); + assertEquals(shortcutProbability, unigramProperty.mShortcutTargets.get(0).mFrequency); + final int updatedShortcutProbability = 2; + binaryDictionary.addUnigramWord("aaa", unigramProbability, "zzz", + updatedShortcutProbability, false /* isNotAWord */, false /* isBlacklisted */, + 0 /* timestamp */); + unigramProperty = binaryDictionary.getUnigramProperty("aaa"); + assertEquals(1, unigramProperty.mShortcutTargets.size()); + assertEquals("zzz", unigramProperty.mShortcutTargets.get(0).mWord); + assertEquals(updatedShortcutProbability, + unigramProperty.mShortcutTargets.get(0).mFrequency); + binaryDictionary.addUnigramWord("aaa", unigramProbability, "yyy", + shortcutProbability, false /* isNotAWord */, false /* isBlacklisted */, + 0 /* timestamp */); + final HashMap<String, Integer> shortcutTargets = new HashMap<String, Integer>(); + shortcutTargets.put("zzz", updatedShortcutProbability); + shortcutTargets.put("yyy", shortcutProbability); + unigramProperty = binaryDictionary.getUnigramProperty("aaa"); + assertEquals(2, unigramProperty.mShortcutTargets.size()); + for (WeightedString shortcutTarget : unigramProperty.mShortcutTargets) { + assertTrue(shortcutTargets.containsKey(shortcutTarget.mWord)); + assertEquals((int)shortcutTargets.get(shortcutTarget.mWord), shortcutTarget.mFrequency); + shortcutTargets.remove(shortcutTarget.mWord); + } + shortcutTargets.put("zzz", updatedShortcutProbability); + shortcutTargets.put("yyy", shortcutProbability); + binaryDictionary.flushWithGC(); + unigramProperty = binaryDictionary.getUnigramProperty("aaa"); + assertEquals(2, unigramProperty.mShortcutTargets.size()); + for (WeightedString shortcutTarget : unigramProperty.mShortcutTargets) { + assertTrue(shortcutTargets.containsKey(shortcutTarget.mWord)); + assertEquals((int)shortcutTargets.get(shortcutTarget.mWord), shortcutTarget.mFrequency); + shortcutTargets.remove(shortcutTarget.mWord); + } + } + + public void testAddManyShortcuts() { + testAddManyShortcuts(FormatSpec.VERSION4); + } + + private void testAddManyShortcuts(final int formatVersion) { + final long seed = System.currentTimeMillis(); + final Random random = new Random(seed); + final int UNIGRAM_COUNT = 1000; + final int SHORTCUT_COUNT = 10000; + final int codePointSetSize = 20; + final int[] codePointSet = CodePointUtils.generateCodePointSet(codePointSetSize, random); + + final ArrayList<String> words = new ArrayList<String>(); + final HashMap<String, Integer> unigramProbabilities = new HashMap<String, Integer>(); + final HashMap<String, HashMap<String, Integer>> shortcutTargets = + new HashMap<String, HashMap<String, Integer>>(); + + File dictFile = null; + try { + dictFile = createEmptyDictionaryAndGetFile("TestBinaryDictionary", formatVersion); + } catch (IOException e) { + fail("IOException while writing an initial dictionary : " + e); + } + final BinaryDictionary binaryDictionary = new BinaryDictionary(dictFile.getAbsolutePath(), + 0 /* offset */, dictFile.length(), true /* useFullEditDistance */, + Locale.getDefault(), TEST_LOCALE, true /* isUpdatable */); + + for (int i = 0; i < UNIGRAM_COUNT; i++) { + final String word = CodePointUtils.generateWord(random, codePointSet); + final int unigramProbability = random.nextInt(0xFF); + addUnigramWord(binaryDictionary, word, unigramProbability); + words.add(word); + unigramProbabilities.put(word, unigramProbability); + if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { + binaryDictionary.flushWithGC(); + } + } + for (int i = 0; i < SHORTCUT_COUNT; i++) { + final String shortcutTarget = CodePointUtils.generateWord(random, codePointSet); + final int shortcutProbability = random.nextInt(0xF); + final String word = words.get(random.nextInt(words.size())); + final int unigramProbability = unigramProbabilities.get(word); + binaryDictionary.addUnigramWord(word, unigramProbability, shortcutTarget, + shortcutProbability, false /* isNotAWord */, false /* isBlacklisted */, + 0 /* timestamp */); + if (shortcutTargets.containsKey(word)) { + final HashMap<String, Integer> shortcutTargetsOfWord = shortcutTargets.get(word); + shortcutTargetsOfWord.put(shortcutTarget, shortcutProbability); + } else { + final HashMap<String, Integer> shortcutTargetsOfWord = + new HashMap<String, Integer>(); + shortcutTargetsOfWord.put(shortcutTarget, shortcutProbability); + shortcutTargets.put(word, shortcutTargetsOfWord); + } + if (binaryDictionary.needsToRunGC(true /* mindsBlockByGC */)) { + binaryDictionary.flushWithGC(); + } + } + + for (final String word : words) { + final UnigramProperty unigramProperty = binaryDictionary.getUnigramProperty(word); + assertEquals((int)unigramProbabilities.get(word), unigramProperty.mProbability); + assertEquals(shortcutTargets.get(word).size(), unigramProperty.mShortcutTargets.size()); + for (final WeightedString shortcutTarget : unigramProperty.mShortcutTargets) { + final String targetCodePonts = shortcutTarget.mWord; + assertEquals((int)shortcutTargets.get(word).get(targetCodePonts), + shortcutTarget.mFrequency); + } + } + } } diff --git a/tests/src/com/android/inputmethod/latin/ExpandableDictionaryTests.java b/tests/src/com/android/inputmethod/latin/ExpandableDictionaryTests.java deleted file mode 100644 index 6aae1044e..000000000 --- a/tests/src/com/android/inputmethod/latin/ExpandableDictionaryTests.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.inputmethod.latin; - -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -/** - * Unit test for ExpandableDictionary - */ -@SmallTest -public class ExpandableDictionaryTests extends AndroidTestCase { - - private final static int UNIGRAM_FREQ = 50; - // See UserBinaryDictionary for more information about this variable. - // For tests, its actual value does not matter. - private final static int SHORTCUT_FREQ = 14; - - public void testAddWordAndGetWordFrequency() { - final ExpandableDictionary dict = new ExpandableDictionary(Dictionary.TYPE_USER); - - // Add words - dict.addWord("abcde", "abcde", UNIGRAM_FREQ, SHORTCUT_FREQ); - dict.addWord("abcef", null, UNIGRAM_FREQ + 1, 0); - - // Check words - assertFalse(dict.isValidWord("abcde")); - assertEquals(UNIGRAM_FREQ, dict.getWordFrequency("abcde")); - assertTrue(dict.isValidWord("abcef")); - assertEquals(UNIGRAM_FREQ+1, dict.getWordFrequency("abcef")); - - dict.addWord("abc", null, UNIGRAM_FREQ + 2, 0); - assertTrue(dict.isValidWord("abc")); - assertEquals(UNIGRAM_FREQ + 2, dict.getWordFrequency("abc")); - - // Add existing word with lower frequency - dict.addWord("abc", null, UNIGRAM_FREQ, 0); - assertEquals(UNIGRAM_FREQ + 2, dict.getWordFrequency("abc")); - - // Add existing word with higher frequency - dict.addWord("abc", null, UNIGRAM_FREQ + 3, 0); - assertEquals(UNIGRAM_FREQ + 3, dict.getWordFrequency("abc")); - } -} diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java index b9b52a6f3..aaad740e4 100644 --- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java +++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java @@ -30,6 +30,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; +import android.view.inputmethod.InputMethodSubtype; import android.widget.EditText; import android.widget.FrameLayout; @@ -37,15 +38,20 @@ import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.utils.LocaleUtils; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import java.util.Locale; public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { private static final String PREF_DEBUG_MODE = "debug_mode"; + private static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold"; + // Default value for auto-correction threshold. This is the string representation of the + // index in the resources array of auto-correction threshold settings. + private static final String DEFAULT_AUTO_CORRECTION_THRESHOLD = "1"; - // The message that sets the underline is posted with a 200 ms delay - protected static final int DELAY_TO_WAIT_FOR_UNDERLINE = 200; + // The message that sets the underline is posted with a 500 ms delay + protected static final int DELAY_TO_WAIT_FOR_UNDERLINE = 500; // The message that sets predictions is posted with a 200 ms delay protected static final int DELAY_TO_WAIT_FOR_PREDICTIONS = 200; @@ -54,6 +60,8 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { protected MyEditText mEditText; protected View mInputView; protected InputConnection mInputConnection; + private boolean mPreviousDebugSetting; + private String mPreviousAutoCorrectSetting; // A helper class to ease span tests public static class SpanGetter { @@ -135,7 +143,17 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { final boolean previousSetting = prefs.getBoolean(key, defaultValue); final SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean(key, value); - editor.commit(); + editor.apply(); + return previousSetting; + } + + protected String setStringPreference(final String key, final String value, + final String defaultValue) { + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mLatinIME); + final String previousSetting = prefs.getString(key, defaultValue); + final SharedPreferences.Editor editor = prefs.edit(); + editor.putString(key, value); + editor.apply(); return previousSetting; } @@ -154,9 +172,10 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { mEditText.setEnabled(true); setupService(); mLatinIME = getService(); - final boolean previousDebugSetting = setDebugMode(true); + mPreviousDebugSetting = setDebugMode(true); + mPreviousAutoCorrectSetting = setStringPreference(PREF_AUTO_CORRECTION_THRESHOLD, + DEFAULT_AUTO_CORRECTION_THRESHOLD, DEFAULT_AUTO_CORRECTION_THRESHOLD); mLatinIME.onCreate(); - setDebugMode(previousDebugSetting); final EditorInfo ei = new EditorInfo(); final InputConnection ic = mEditText.onCreateInputConnection(ei); final LayoutInflater inflater = @@ -172,6 +191,14 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { changeLanguage("en_US"); } + @Override + protected void tearDown() { + mLatinIME.mHandler.removeAllMessages(); + setStringPreference(PREF_AUTO_CORRECTION_THRESHOLD, mPreviousAutoCorrectSetting, + DEFAULT_AUTO_CORRECTION_THRESHOLD); + setDebugMode(mPreviousDebugSetting); + } + // We need to run the messages added to the handler from LatinIME. The only way to do // that is to call Looper#loop() on the right looper, so we're going to get the looper // object and call #loop() here. The messages in the handler actually run on the UI @@ -244,7 +271,18 @@ public class InputTestsBase extends ServiceTestCase<LatinIMEForTests> { protected void changeLanguageWithoutWait(final String locale) { mEditText.mCurrentLocale = LocaleUtils.constructLocaleFromString(locale); - SubtypeSwitcher.getInstance().forceLocale(mEditText.mCurrentLocale); + final InputMethodSubtype subtype = new InputMethodSubtype( + R.string.subtype_no_language_qwerty, R.drawable.ic_ime_switcher_dark, + locale, "keyboard", "KeyboardLayoutSet=" + // TODO: this is forcing a QWERTY keyboard for all locales, which is wrong. + // It's still better than using whatever keyboard is the current one, but we + // should actually use the default keyboard for this locale. + + SubtypeLocaleUtils.QWERTY + + "," + Constants.Subtype.ExtraValue.ASCII_CAPABLE + + "," + Constants.Subtype.ExtraValue.ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE + + "," + Constants.Subtype.ExtraValue.EMOJI_CAPABLE, + false /* isAuxiliary */, false /* overridesImplicitlyEnabledSubtype */); + SubtypeSwitcher.getInstance().forceSubtype(subtype); mLatinIME.loadKeyboard(); runMessages(); mKeyboard = mLatinIME.mKeyboardSwitcher.getKeyboard(); diff --git a/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java b/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java index c0dd9933c..6ad125053 100644 --- a/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java +++ b/tests/src/com/android/inputmethod/latin/RichInputConnectionAndTextRangeTests.java @@ -16,6 +16,7 @@ package com.android.inputmethod.latin; +import com.android.inputmethod.latin.settings.SettingsValues; import com.android.inputmethod.latin.utils.TextRange; import android.inputmethodservice.InputMethodService; @@ -39,7 +40,8 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase { // The following is meant to be a reasonable default for // the "word_separators" resource. - private static final String sSeparators = ".,:;!?-"; + private static final SettingsValues sSettings = + SettingsValues.makeDummySettingsValuesForTest(Locale.ENGLISH); @Override protected void setUp() throws Exception { @@ -137,9 +139,9 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase { */ public void testGetPreviousWord() { // If one of the following cases breaks, the bigram suggestions won't work. - assertEquals(RichInputConnection.getNthPreviousWord("abc def", sSeparators, 2), "abc"); - assertNull(RichInputConnection.getNthPreviousWord("abc", sSeparators, 2)); - assertNull(RichInputConnection.getNthPreviousWord("abc. def", sSeparators, 2)); + assertEquals(RichInputConnection.getNthPreviousWord("abc def", sSettings, 2), "abc"); + assertNull(RichInputConnection.getNthPreviousWord("abc", sSettings, 2)); + assertNull(RichInputConnection.getNthPreviousWord("abc. def", sSettings, 2)); // The following tests reflect the current behavior of the function // RichInputConnection#getNthPreviousWord. @@ -148,15 +150,15 @@ public class RichInputConnectionAndTextRangeTests extends AndroidTestCase { // this function if needed - especially since it does not seem very // logical. These tests are just there to catch any unintentional // changes in the behavior of the RichInputConnection#getPreviousWord method. - assertEquals(RichInputConnection.getNthPreviousWord("abc def ", sSeparators, 2), "abc"); - assertEquals(RichInputConnection.getNthPreviousWord("abc def.", sSeparators, 2), "abc"); - assertEquals(RichInputConnection.getNthPreviousWord("abc def .", sSeparators, 2), "def"); - assertNull(RichInputConnection.getNthPreviousWord("abc ", sSeparators, 2)); - - assertEquals(RichInputConnection.getNthPreviousWord("abc def", sSeparators, 1), "def"); - assertEquals(RichInputConnection.getNthPreviousWord("abc def ", sSeparators, 1), "def"); - assertNull(RichInputConnection.getNthPreviousWord("abc def.", sSeparators, 1)); - assertNull(RichInputConnection.getNthPreviousWord("abc def .", sSeparators, 1)); + assertEquals(RichInputConnection.getNthPreviousWord("abc def ", sSettings, 2), "abc"); + assertEquals(RichInputConnection.getNthPreviousWord("abc def.", sSettings, 2), "abc"); + assertEquals(RichInputConnection.getNthPreviousWord("abc def .", sSettings, 2), "def"); + assertNull(RichInputConnection.getNthPreviousWord("abc ", sSettings, 2)); + + assertEquals(RichInputConnection.getNthPreviousWord("abc def", sSettings, 1), "def"); + assertEquals(RichInputConnection.getNthPreviousWord("abc def ", sSettings, 1), "def"); + assertNull(RichInputConnection.getNthPreviousWord("abc def.", sSettings, 1)); + assertNull(RichInputConnection.getNthPreviousWord("abc def .", sSettings, 1)); } /** diff --git a/tests/src/com/android/inputmethod/latin/WordComposerTests.java b/tests/src/com/android/inputmethod/latin/WordComposerTests.java index 1434c6b63..a67f6a4ac 100644 --- a/tests/src/com/android/inputmethod/latin/WordComposerTests.java +++ b/tests/src/com/android/inputmethod/latin/WordComposerTests.java @@ -26,8 +26,15 @@ import android.test.suitebuilder.annotation.SmallTest; public class WordComposerTests extends AndroidTestCase { public void testMoveCursor() { final WordComposer wc = new WordComposer(); + // BMP is the Basic Multilingual Plane, as defined by Unicode. This includes + // most characters for most scripts, including all Roman alphabet languages, + // CJK, Arabic, Hebrew. Notable exceptions include some emoji and some + // very rare Chinese ideograms. BMP characters can be encoded on 2 bytes + // in UTF-16, whereas those outside the BMP need 4 bytes. + // http://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane final String STR_WITHIN_BMP = "abcdef"; - wc.setComposingWord(STR_WITHIN_BMP, null); + final String PREVWORD = "prevword"; + wc.setComposingWord(STR_WITHIN_BMP, PREVWORD, null /* keyboard */); assertEquals(wc.size(), STR_WITHIN_BMP.codePointCount(0, STR_WITHIN_BMP.length())); assertFalse(wc.isCursorFrontOrMiddleOfComposingWord()); @@ -43,13 +50,20 @@ public class WordComposerTests extends AndroidTestCase { // Move the cursor to after the 'f' assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(1)); assertFalse(wc.isCursorFrontOrMiddleOfComposingWord()); + // Check the previous word is still there + assertEquals(PREVWORD, wc.getPreviousWord()); // Move the cursor past the end of the word assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(1)); assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(15)); + // Do what LatinIME does when the cursor is moved outside of the word, + // and check the behavior is correct. + wc.reset(); + assertNull(wc.getPreviousWord()); // \uD861\uDED7 is 𨛗, a character outside the BMP final String STR_WITH_SUPPLEMENTARY_CHAR = "abcde\uD861\uDED7fgh"; - wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null); + wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null /* previousWord */, + null /* keyboard */); assertEquals(wc.size(), STR_WITH_SUPPLEMENTARY_CHAR.codePointCount(0, STR_WITH_SUPPLEMENTARY_CHAR.length())); assertFalse(wc.isCursorFrontOrMiddleOfComposingWord()); @@ -59,34 +73,46 @@ public class WordComposerTests extends AndroidTestCase { assertTrue(wc.isCursorFrontOrMiddleOfComposingWord()); assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(1)); assertFalse(wc.isCursorFrontOrMiddleOfComposingWord()); + assertNull(wc.getPreviousWord()); - wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null); + wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, STR_WITHIN_BMP, null /* keyboard */); wc.setCursorPositionWithinWord(3); assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(7)); + assertEquals(STR_WITHIN_BMP, wc.getPreviousWord()); - wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null); + wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, STR_WITH_SUPPLEMENTARY_CHAR, + null /* keyboard */); wc.setCursorPositionWithinWord(3); assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(7)); + assertEquals(STR_WITH_SUPPLEMENTARY_CHAR, wc.getPreviousWord()); - wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null); + wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, STR_WITHIN_BMP, null /* keyboard */); wc.setCursorPositionWithinWord(3); assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(-3)); assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(-1)); + assertEquals(STR_WITHIN_BMP, wc.getPreviousWord()); - wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null); + wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null /* previousWord */, + null /* keyboard */); wc.setCursorPositionWithinWord(3); assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(-9)); + assertNull(wc.getPreviousWord()); - wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null); + wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, STR_WITH_SUPPLEMENTARY_CHAR, + null /* keyboard */); assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(-10)); + assertEquals(STR_WITH_SUPPLEMENTARY_CHAR, wc.getPreviousWord()); - wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null); + wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null /* previousWord */, + null /* keyboard */); assertFalse(wc.moveCursorByAndReturnIfInsideComposingWord(-11)); - wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null); + wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null /* previousWord */, + null /* keyboard */); assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(0)); - wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null); + wc.setComposingWord(STR_WITH_SUPPLEMENTARY_CHAR, null /* previousWord */, + null /* keyboard */); wc.setCursorPositionWithinWord(2); assertTrue(wc.moveCursorByAndReturnIfInsideComposingWord(0)); } diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java index 32c07e106..e3ec2eca9 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictDecoderEncoderTests.java @@ -26,10 +26,10 @@ import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.CharEncodin import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer; import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader; import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions; -import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions; import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode; import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray; import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString; +import com.android.inputmethod.latin.makedict.UnsupportedFormatException; import com.android.inputmethod.latin.utils.ByteArrayDictBuffer; import com.android.inputmethod.latin.utils.CollectionUtils; @@ -52,18 +52,18 @@ import java.util.TreeMap; @LargeTest public class BinaryDictDecoderEncoderTests extends AndroidTestCase { private static final String TAG = BinaryDictDecoderEncoderTests.class.getSimpleName(); - private static final int DEFAULT_MAX_UNIGRAMS = 100; + private static final int DEFAULT_MAX_UNIGRAMS = 300; private static final int DEFAULT_CODE_POINT_SET_SIZE = 50; + private static final int LARGE_CODE_POINT_SET_SIZE = 300; private static final int UNIGRAM_FREQ = 10; private static final int BIGRAM_FREQ = 50; private static final int TOLERANCE_OF_BIGRAM_FREQ = 5; private static final int NUM_OF_NODES_HAVING_SHORTCUTS = 50; private static final int NUM_OF_SHORTCUTS = 5; - private static final int USE_BYTE_ARRAY = 1; - private static final int USE_BYTE_BUFFER = 2; - private static final ArrayList<String> sWords = CollectionUtils.newArrayList(); + private static final ArrayList<String> sWordsWithVariousCodePoints = + CollectionUtils.newArrayList(); private static final SparseArray<List<Integer>> sEmptyBigrams = CollectionUtils.newSparseArray(); private static final SparseArray<List<Integer>> sStarBigrams = CollectionUtils.newSparseArray(); @@ -71,21 +71,6 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { CollectionUtils.newSparseArray(); private static final HashMap<String, List<String>> sShortcuts = CollectionUtils.newHashMap(); - private static final FormatSpec.FormatOptions VERSION2 = new FormatSpec.FormatOptions(2); - private static final FormatSpec.FormatOptions VERSION3_WITHOUT_DYNAMIC_UPDATE = - new FormatSpec.FormatOptions(3, false /* supportsDynamicUpdate */); - private static final FormatSpec.FormatOptions VERSION3_WITH_DYNAMIC_UPDATE = - new FormatSpec.FormatOptions(3, true /* supportsDynamicUpdate */); - private static final FormatSpec.FormatOptions VERSION4_WITHOUT_DYNAMIC_UPDATE = - new FormatSpec.FormatOptions(4, false /* supportsDynamicUpdate */); - private static final FormatSpec.FormatOptions VERSION4_WITH_DYNAMIC_UPDATE = - new FormatSpec.FormatOptions(4, true /* supportsDynamicUpdate */); - private static final FormatSpec.FormatOptions VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP = - new FormatSpec.FormatOptions(4, true /* supportsDynamicUpdate */, - true /* hasTimestamp */); - - private static final String TEST_DICT_FILE_EXTENSION = ".testDict"; - public BinaryDictDecoderEncoderTests() { this(System.currentTimeMillis(), DEFAULT_MAX_UNIGRAMS); } @@ -95,9 +80,8 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { Log.e(TAG, "Testing dictionary: seed is " + seed); final Random random = new Random(seed); sWords.clear(); - final int[] codePointSet = CodePointUtils.generateCodePointSet(DEFAULT_CODE_POINT_SET_SIZE, - random); - generateWords(maxUnigrams, random, codePointSet); + sWordsWithVariousCodePoints.clear(); + generateWords(maxUnigrams, random); for (int i = 0; i < sWords.size(); ++i) { sChainBigrams.put(i, new ArrayList<Integer>()); @@ -124,23 +108,22 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { } } - private DictEncoder getDictEncoder(final File file, final FormatOptions formatOptions) { - if (formatOptions.mVersion == FormatSpec.VERSION4) { - return new Ver4DictEncoder(getContext().getCacheDir()); - } else if (formatOptions.mVersion == 3 || formatOptions.mVersion == 2) { - return new Ver3DictEncoder(file); - } else { - throw new RuntimeException("The format option has a wrong version : " - + formatOptions.mVersion); - } - } - - private void generateWords(final int number, final Random random, final int[] codePointSet) { + private void generateWords(final int number, final Random random) { + final int[] codePointSet = CodePointUtils.generateCodePointSet(DEFAULT_CODE_POINT_SET_SIZE, + random); final Set<String> wordSet = CollectionUtils.newHashSet(); while (wordSet.size() < number) { wordSet.add(CodePointUtils.generateWord(random, codePointSet)); } sWords.addAll(wordSet); + + final int[] largeCodePointSet = CodePointUtils.generateCodePointSet( + LARGE_CODE_POINT_SET_SIZE, random); + wordSet.clear(); + while (wordSet.size() < number) { + wordSet.add(CodePointUtils.generateWord(random, largeCodePointSet)); + } + sWordsWithVariousCodePoints.addAll(wordSet); } /** @@ -186,7 +169,8 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { long now = -1, diff = -1; try { - final DictEncoder dictEncoder = getDictEncoder(file, formatOptions); + final DictEncoder dictEncoder = BinaryDictUtils.getDictEncoder(file, formatOptions, + getContext().getCacheDir()); now = System.currentTimeMillis(); // If you need to dump the dict to a textual file, uncomment the line below and the @@ -241,54 +225,21 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { private String outputOptions(final int bufferType, final FormatSpec.FormatOptions formatOptions) { String result = " : buffer type = " - + ((bufferType == USE_BYTE_BUFFER) ? "byte buffer" : "byte array"); + + ((bufferType == BinaryDictUtils.USE_BYTE_BUFFER) ? "byte buffer" : "byte array"); result += " : version = " + formatOptions.mVersion; return result + ", supportsDynamicUpdate = " + formatOptions.mSupportsDynamicUpdate; } - private DictionaryOptions getDictionaryOptions(final String id, final String version) { - final DictionaryOptions options = new DictionaryOptions(new HashMap<String, String>(), - false, false); - options.mAttributes.put("version", version); - options.mAttributes.put("dictionary", id); - return options; - } - - private File setUpDictionaryFile(final String name, final String version) { - File file = null; - try { - file = new File(getContext().getCacheDir(), name + "." + version - + TEST_DICT_FILE_EXTENSION); - file.createNewFile(); - } catch (IOException e) { - // do nothing - } - assertTrue("Failed to create the dictionary file.", file.exists()); - return file; - } - - private DictDecoder getDictDecoder(final File file, final int bufferType, - final FormatOptions formatOptions, final DictionaryOptions dictOptions) { - if (formatOptions.mVersion == FormatSpec.VERSION4) { - final FileHeader header = new FileHeader(0, dictOptions, formatOptions); - return FormatSpec.getDictDecoder(new File(getContext().getCacheDir(), - header.getId() + "." + header.getVersion()), bufferType); - } else { - return FormatSpec.getDictDecoder(file, bufferType); - } - } // Tests for readDictionaryBinary and writeDictionaryBinary private long timeReadingAndCheckDict(final File file, final List<String> words, final SparseArray<List<Integer>> bigrams, - final HashMap<String, List<String>> shortcutMap, final int bufferType, - final FormatOptions formatOptions, final DictionaryOptions dictOptions) { + final HashMap<String, List<String>> shortcutMap, final int bufferType) { long now, diff = -1; FusionDictionary dict = null; try { - final DictDecoder dictDecoder = getDictDecoder(file, bufferType, formatOptions, - dictOptions); + final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, bufferType); now = System.currentTimeMillis(); dict = dictDecoder.readDictionaryBinary(null, false /* deleteDictIfBroken */); diff = System.currentTimeMillis() - now; @@ -310,17 +261,17 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { final String dictName = "runReadAndWrite"; final String dictVersion = Long.toString(System.currentTimeMillis()); - final File file = setUpDictionaryFile(dictName, dictVersion); + final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions, + getContext().getCacheDir()); final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - getDictionaryOptions(dictName, dictVersion)); + BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion)); addUnigrams(words.size(), dict, words, shortcuts); addBigrams(dict, words, bigrams); checkDictionary(dict, words, bigrams, shortcuts); final long write = timeWritingDictToFile(file, dict, formatOptions); - final long read = timeReadingAndCheckDict(file, words, bigrams, shortcuts, bufferType, - formatOptions, dict.mOptions); + final long read = timeReadingAndCheckDict(file, words, bigrams, shortcuts, bufferType); return "PROF: read=" + read + "ms, write=" + write + "ms :" + message + " : " + outputOptions(bufferType, formatOptions); @@ -340,6 +291,9 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { "chain with shortcuts")); results.add(runReadAndWrite(sWords, sStarBigrams, sShortcuts, bufferType, formatOptions, "star with shortcuts")); + results.add(runReadAndWrite(sWordsWithVariousCodePoints, sEmptyBigrams, + null /* shortcuts */, bufferType, formatOptions, + "unigram with various code points")); } // Unit test for CharEncoding.readString and CharEncoding.writeString. @@ -349,8 +303,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { final byte[] buffer = new byte[50 * 3]; final DictBuffer dictBuffer = new ByteArrayDictBuffer(buffer); for (final String word : sWords) { - Log.d("testReadAndWriteString", "write : " + word); - Arrays.fill(buffer, (byte)0); + Arrays.fill(buffer, (byte) 0); CharEncoding.writeString(buffer, 0, word); dictBuffer.position(0); final String str = CharEncoding.readString(dictBuffer); @@ -361,12 +314,18 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { public void testReadAndWriteWithByteBuffer() { final List<String> results = CollectionUtils.newArrayList(); - runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION2); - runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITHOUT_DYNAMIC_UPDATE); - runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITH_DYNAMIC_UPDATE); - runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION4_WITHOUT_DYNAMIC_UPDATE); - runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION4_WITH_DYNAMIC_UPDATE); - runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP); + runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION2); + runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION3_WITHOUT_DYNAMIC_UPDATE); + runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION3_WITH_DYNAMIC_UPDATE); + runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION4_WITHOUT_DYNAMIC_UPDATE); + runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE); + runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP); for (final String result : results) { Log.d(TAG, result); @@ -376,12 +335,18 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { public void testReadAndWriteWithByteArray() { final List<String> results = CollectionUtils.newArrayList(); - runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION2); - runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITHOUT_DYNAMIC_UPDATE); - runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITH_DYNAMIC_UPDATE); - runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION4_WITHOUT_DYNAMIC_UPDATE); - runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION4_WITH_DYNAMIC_UPDATE); - runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP); + runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION2); + runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION3_WITHOUT_DYNAMIC_UPDATE); + runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION3_WITH_DYNAMIC_UPDATE); + runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION4_WITHOUT_DYNAMIC_UPDATE); + runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE); + runReadAndWriteTests(results, BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP); for (final String result : results) { Log.d(TAG, result); @@ -437,8 +402,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { } private long timeAndCheckReadUnigramsAndBigramsBinary(final File file, final List<String> words, - final SparseArray<List<Integer>> bigrams, final int bufferType, - final FormatOptions formatOptions, final DictionaryOptions dictOptions) { + final SparseArray<List<Integer>> bigrams, final int bufferType) { FileInputStream inStream = null; final TreeMap<Integer, String> resultWords = CollectionUtils.newTreeMap(); @@ -448,8 +412,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { long now = -1, diff = -1; try { - final DictDecoder dictDecoder = getDictDecoder(file, bufferType, formatOptions, - dictOptions); + final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, bufferType); now = System.currentTimeMillis(); dictDecoder.readUnigramsAndBigramsBinary(resultWords, resultFreqs, resultBigrams); diff = System.currentTimeMillis() - now; @@ -476,20 +439,20 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { final FormatSpec.FormatOptions formatOptions, final String message) { final String dictName = "runReadUnigrams"; final String dictVersion = Long.toString(System.currentTimeMillis()); - final File file = setUpDictionaryFile(dictName, dictVersion); + final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions, + getContext().getCacheDir()); // making the dictionary from lists of words. final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - getDictionaryOptions(dictName, dictVersion)); + BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion)); addUnigrams(words.size(), dict, words, null /* shortcutMap */); addBigrams(dict, words, bigrams); timeWritingDictToFile(file, dict, formatOptions); - long wordMap = timeAndCheckReadUnigramsAndBigramsBinary(file, words, bigrams, bufferType, - formatOptions, dict.mOptions); + long wordMap = timeAndCheckReadUnigramsAndBigramsBinary(file, words, bigrams, bufferType); long fullReading = timeReadingAndCheckDict(file, words, bigrams, null /* shortcutMap */, - bufferType, formatOptions, dict.mOptions); + bufferType); return "readDictionaryBinary=" + fullReading + ", readUnigramsAndBigramsBinary=" + wordMap + " : " + message + " : " + outputOptions(bufferType, formatOptions); @@ -508,13 +471,18 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { public void testReadUnigramsAndBigramsBinaryWithByteBuffer() { final ArrayList<String> results = CollectionUtils.newArrayList(); - runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION2); - runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITHOUT_DYNAMIC_UPDATE); - runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITH_DYNAMIC_UPDATE); - runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION4_WITHOUT_DYNAMIC_UPDATE); - runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION4_WITH_DYNAMIC_UPDATE); - runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, - VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP); + runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION2); + runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION3_WITHOUT_DYNAMIC_UPDATE); + runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION3_WITH_DYNAMIC_UPDATE); + runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION4_WITHOUT_DYNAMIC_UPDATE); + runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE); + runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP); for (final String result : results) { Log.d(TAG, result); @@ -524,13 +492,18 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { public void testReadUnigramsAndBigramsBinaryWithByteArray() { final ArrayList<String> results = CollectionUtils.newArrayList(); - runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION2); - runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITHOUT_DYNAMIC_UPDATE); - runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITH_DYNAMIC_UPDATE); - runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION4_WITHOUT_DYNAMIC_UPDATE); - runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION4_WITH_DYNAMIC_UPDATE); - runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, - VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP); + runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION2); + runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION3_WITHOUT_DYNAMIC_UPDATE); + runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION3_WITH_DYNAMIC_UPDATE); + runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION4_WITHOUT_DYNAMIC_UPDATE); + runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE); + runReadUnigramsAndBigramsTests(results, BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP); for (final String result : results) { Log.d(TAG, result); @@ -550,7 +523,7 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { return null; } if (fileHeader == null) return null; - return BinaryDictDecoderUtils.getWordAtPosition(dictDecoder, fileHeader.mHeaderSize, + return BinaryDictDecoderUtils.getWordAtPosition(dictDecoder, fileHeader.mBodyOffset, address, fileHeader.mFormatOptions).mWord; } @@ -578,20 +551,21 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { final FormatOptions formatOptions, final String message) { final String dictName = "testGetTerminalPosition"; final String dictVersion = Long.toString(System.currentTimeMillis()); - final File file = setUpDictionaryFile(dictName, dictVersion); + final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions, + getContext().getCacheDir()); final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - getDictionaryOptions(dictName, dictVersion)); + BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion)); addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */); addBigrams(dict, words, bigrams); timeWritingDictToFile(file, dict, formatOptions); - final DictDecoder dictDecoder = getDictDecoder(file, DictDecoder.USE_BYTEARRAY, - formatOptions, dict.mOptions); + final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, DictDecoder.USE_BYTEARRAY); try { dictDecoder.openDictBuffer(); } catch (IOException e) { - // ignore + Log.e(TAG, "IOException while opening the buffer", e); + } catch (UnsupportedFormatException e) { Log.e(TAG, "IOException while opening the buffer", e); } assertTrue("Can't get the buffer", dictDecoder.isDictBufferOpen()); @@ -638,65 +612,63 @@ public class BinaryDictDecoderEncoderTests extends AndroidTestCase { public void testGetTerminalPosition() { final ArrayList<String> results = CollectionUtils.newArrayList(); - runGetTerminalPositionTests(USE_BYTE_ARRAY, VERSION2); - runGetTerminalPositionTests(USE_BYTE_ARRAY, VERSION3_WITHOUT_DYNAMIC_UPDATE); - runGetTerminalPositionTests(USE_BYTE_ARRAY, VERSION3_WITH_DYNAMIC_UPDATE); - runGetTerminalPositionTests(USE_BYTE_ARRAY, VERSION4_WITHOUT_DYNAMIC_UPDATE); - runGetTerminalPositionTests(USE_BYTE_ARRAY, VERSION4_WITH_DYNAMIC_UPDATE); - runGetTerminalPositionTests(USE_BYTE_ARRAY, VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP); - - runGetTerminalPositionTests(USE_BYTE_BUFFER, VERSION2); - runGetTerminalPositionTests(USE_BYTE_BUFFER, VERSION3_WITHOUT_DYNAMIC_UPDATE); - runGetTerminalPositionTests(USE_BYTE_BUFFER, VERSION3_WITH_DYNAMIC_UPDATE); - runGetTerminalPositionTests(USE_BYTE_BUFFER, VERSION4_WITHOUT_DYNAMIC_UPDATE); - runGetTerminalPositionTests(USE_BYTE_BUFFER, VERSION4_WITH_DYNAMIC_UPDATE); - runGetTerminalPositionTests(USE_BYTE_BUFFER, VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP); + runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_ARRAY, BinaryDictUtils.VERSION2); + runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION3_WITHOUT_DYNAMIC_UPDATE); + runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION3_WITH_DYNAMIC_UPDATE); + runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION4_WITHOUT_DYNAMIC_UPDATE); + runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE); + runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_ARRAY, + BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP); + + runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_BUFFER, BinaryDictUtils.VERSION2); + runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION3_WITHOUT_DYNAMIC_UPDATE); + runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION3_WITH_DYNAMIC_UPDATE); + runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION4_WITHOUT_DYNAMIC_UPDATE); + runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE); + runGetTerminalPositionTests(BinaryDictUtils.USE_BYTE_BUFFER, + BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP); for (final String result : results) { Log.d(TAG, result); } } - private void runTestDeleteWord(final FormatOptions formatOptions) { + private void runTestDeleteWord(final FormatOptions formatOptions) + throws IOException, UnsupportedFormatException { final String dictName = "testDeleteWord"; final String dictVersion = Long.toString(System.currentTimeMillis()); - final File file = setUpDictionaryFile(dictName, dictVersion); + final File file = BinaryDictUtils.getDictFile(dictName, dictVersion, formatOptions, + getContext().getCacheDir()); final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - new FusionDictionary.DictionaryOptions( - new HashMap<String, String>(), false, false)); + BinaryDictUtils.makeDictionaryOptions(dictName, dictVersion)); addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */); timeWritingDictToFile(file, dict, formatOptions); - final DictUpdater dictUpdater; - if (formatOptions.mVersion == 3) { - dictUpdater = new Ver3DictUpdater(file, DictDecoder.USE_WRITABLE_BYTEBUFFER); - } else if (formatOptions.mVersion == 4) { - dictUpdater = new Ver4DictUpdater(file, DictDecoder.USE_WRITABLE_BYTEBUFFER); - } else { - throw new RuntimeException("DictUpdater for version " + formatOptions.mVersion - + " doesn't exist."); - } - - try { - MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, - dictUpdater.getTerminalPosition(sWords.get(0))); - dictUpdater.deleteWord(sWords.get(0)); - assertEquals(FormatSpec.NOT_VALID_WORD, - dictUpdater.getTerminalPosition(sWords.get(0))); - - MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, - dictUpdater.getTerminalPosition(sWords.get(5))); - dictUpdater.deleteWord(sWords.get(5)); - assertEquals(FormatSpec.NOT_VALID_WORD, - dictUpdater.getTerminalPosition(sWords.get(5))); - } catch (IOException e) { - } catch (UnsupportedFormatException e) { - } + final DictUpdater dictUpdater = BinaryDictUtils.getDictUpdater(file, formatOptions); + MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, + dictUpdater.getTerminalPosition(sWords.get(0))); + dictUpdater.deleteWord(sWords.get(0)); + assertEquals(FormatSpec.NOT_VALID_WORD, + dictUpdater.getTerminalPosition(sWords.get(0))); + + MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, + dictUpdater.getTerminalPosition(sWords.get(5))); + dictUpdater.deleteWord(sWords.get(5)); + assertEquals(FormatSpec.NOT_VALID_WORD, + dictUpdater.getTerminalPosition(sWords.get(5))); } - public void testDeleteWord() { - runTestDeleteWord(VERSION3_WITH_DYNAMIC_UPDATE); - runTestDeleteWord(VERSION4_WITH_DYNAMIC_UPDATE); + public void testDeleteWord() throws IOException, UnsupportedFormatException { + runTestDeleteWord(BinaryDictUtils.VERSION3_WITH_DYNAMIC_UPDATE); + runTestDeleteWord(BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE); } } diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java index afe5adb73..308919499 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java @@ -23,6 +23,7 @@ import android.util.Log; import com.android.inputmethod.latin.makedict.BinaryDictDecoderUtils.DictBuffer; import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader; +import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions; import com.android.inputmethod.latin.makedict.FusionDictionary.PtNodeArray; import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString; import com.android.inputmethod.latin.utils.CollectionUtils; @@ -30,24 +31,16 @@ import com.android.inputmethod.latin.utils.CollectionUtils; import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; import java.util.Random; @LargeTest public class BinaryDictIOUtilsTests extends AndroidTestCase { private static final String TAG = BinaryDictIOUtilsTests.class.getSimpleName(); - private static final FormatSpec.FormatOptions FORMAT_OPTIONS = - new FormatSpec.FormatOptions(3, true); private static final ArrayList<String> sWords = CollectionUtils.newArrayList(); public static final int DEFAULT_MAX_UNIGRAMS = 1500; private final int mMaxUnigrams; - private static final String TEST_DICT_FILE_EXTENSION = ".testDict"; - - private static final int VERSION3 = 3; - private static final int VERSION4 = 4; - private static final String[] CHARACTERS = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", @@ -141,7 +134,7 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase { int position = FormatSpec.NOT_VALID_WORD; try { - final Ver3DictDecoder dictDecoder = new Ver3DictDecoder(file, + final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, DictDecoder.USE_READONLY_BYTEBUFFER); position = dictDecoder.getTerminalPosition(word); } catch (IOException e) { @@ -159,7 +152,7 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase { * @throws IOException * @throws UnsupportedFormatException */ - private static PtNodeInfo findWordByBinaryDictReader(final DictDecoder dictDecoder, + private static PtNodeInfo findWordByDictDecoder(final DictDecoder dictDecoder, final String word) throws IOException, UnsupportedFormatException { int position = dictDecoder.getTerminalPosition(word); if (position != FormatSpec.NOT_VALID_WORD) { @@ -176,7 +169,7 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase { PtNodeInfo info = null; try { dictDecoder.openDictBuffer(); - info = findWordByBinaryDictReader(dictDecoder, word); + info = findWordByDictDecoder(dictDecoder, word); } catch (IOException e) { } catch (UnsupportedFormatException e) { } @@ -186,16 +179,10 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase { // return amount of time to insert a word private long insertAndCheckWord(final File file, final String word, final int frequency, final boolean exist, final ArrayList<WeightedString> bigrams, - final ArrayList<WeightedString> shortcuts, final int formatVersion) { + final ArrayList<WeightedString> shortcuts, final FormatOptions formatOptions) { long amountOfTime = -1; try { - final DictUpdater dictUpdater; - if (formatVersion == VERSION3) { - dictUpdater = new Ver3DictUpdater(file, DictDecoder.USE_WRITABLE_BYTEBUFFER); - } else { - throw new RuntimeException("DictUpdater for version " + formatVersion + " doesn't" - + " exist."); - } + final DictUpdater dictUpdater = BinaryDictUtils.getDictUpdater(file, formatOptions); if (!exist) { assertEquals(FormatSpec.NOT_VALID_WORD, getWordPosition(file, word)); @@ -212,18 +199,14 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase { return amountOfTime; } - private void deleteWord(final File file, final String word, final int formatVersion) { + private void deleteWord(final File file, final String word, final FormatOptions formatOptions) { try { - final DictUpdater dictUpdater; - if (formatVersion == VERSION3) { - dictUpdater = new Ver3DictUpdater(file, DictDecoder.USE_WRITABLE_BYTEBUFFER); - } else { - throw new RuntimeException("DictUpdater for version " + formatVersion + " doesn't" - + " exist."); - } + final DictUpdater dictUpdater = BinaryDictUtils.getDictUpdater(file, formatOptions); dictUpdater.deleteWord(word); } catch (IOException e) { + Log.e(TAG, "Raised an IOException while deleting a word", e); } catch (UnsupportedFormatException e) { + Log.e(TAG, "Raised an UnsupportedFormatException while deleting a word", e); } } @@ -233,7 +216,7 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase { final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file); final FileHeader fileHeader = dictDecoder.readHeader(); assertEquals(word, - BinaryDictDecoderUtils.getWordAtPosition(dictDecoder, fileHeader.mHeaderSize, + BinaryDictDecoderUtils.getWordAtPosition(dictDecoder, fileHeader.mBodyOffset, position, fileHeader.mFormatOptions).mWord); } catch (IOException e) { Log.e(TAG, "Raised an IOException while looking up a word", e); @@ -242,23 +225,21 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase { } } - private void runTestInsertWord(final int formatVersion) { - File file = null; - try { - file = File.createTempFile("testInsertWord", TEST_DICT_FILE_EXTENSION, - getContext().getCacheDir()); - } catch (IOException e) { - fail("IOException while creating temporary file: " + e); - } + private void runTestInsertWord(final FormatOptions formatOptions) { + final String testName = "testInsertWord"; + final String version = Long.toString(System.currentTimeMillis()); + final File file = BinaryDictUtils.getDictFile(testName, version, formatOptions, + getContext().getCacheDir()); // set an initial dictionary. final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - new FusionDictionary.DictionaryOptions(new HashMap<String,String>(), false, false)); + BinaryDictUtils.makeDictionaryOptions(testName, version)); dict.add("abcd", 10, null, false); try { - final DictEncoder dictEncoder = new Ver3DictEncoder(file); - dictEncoder.writeDictionary(dict, FORMAT_OPTIONS); + final DictEncoder dictEncoder = BinaryDictUtils.getDictEncoder(file, formatOptions, + getContext().getCacheDir()); + dictEncoder.writeDictionary(dict, formatOptions); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } catch (UnsupportedFormatException e) { @@ -266,54 +247,68 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase { } MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, getWordPosition(file, "abcd")); - insertAndCheckWord(file, "abcde", 10, false, null, null, formatVersion); + insertAndCheckWord(file, "abcde", 10, false, null, null, formatOptions); + checkReverseLookup(file, "abcde", getWordPosition(file, "abcde")); - insertAndCheckWord(file, "abcdefghijklmn", 10, false, null, null, formatVersion); + insertAndCheckWord(file, "abcdefghijklmn", 10, false, null, null, formatOptions); checkReverseLookup(file, "abcdefghijklmn", getWordPosition(file, "abcdefghijklmn")); - insertAndCheckWord(file, "abcdabcd", 10, false, null, null, formatVersion); + insertAndCheckWord(file, "abcdabcd", 10, false, null, null, formatOptions); checkReverseLookup(file, "abcdabcd", getWordPosition(file, "abcdabcd")); // update the existing word. - insertAndCheckWord(file, "abcdabcd", 15, true, null, null, formatVersion); + insertAndCheckWord(file, "abcdabcd", 15, true, null, null, formatOptions); + checkReverseLookup(file, "abcdabcd", getWordPosition(file, "abcdabcd")); - // split 1 - insertAndCheckWord(file, "ab", 20, false, null, null, formatVersion); + // Testing splitOnly + insertAndCheckWord(file, "ab", 20, false, null, null, formatOptions); + checkReverseLookup(file, "ab", getWordPosition(file, "ab")); + checkReverseLookup(file, "abcdabcd", getWordPosition(file, "abcdabcd")); + checkReverseLookup(file, "abcde", getWordPosition(file, "abcde")); + checkReverseLookup(file, "abcdefghijklmn", getWordPosition(file, "abcdefghijklmn")); - // split 2 - insertAndCheckWord(file, "ami", 30, false, null, null, formatVersion); + // Testing splitAndBranch + insertAndCheckWord(file, "ami", 30, false, null, null, formatOptions); + checkReverseLookup(file, "ami", getWordPosition(file, "ami")); + checkReverseLookup(file, "ab", getWordPosition(file, "ab")); + checkReverseLookup(file, "abcdabcd", getWordPosition(file, "abcdabcd")); + checkReverseLookup(file, "abcde", getWordPosition(file, "abcde")); + checkReverseLookup(file, "abcdefghijklmn", getWordPosition(file, "abcdefghijklmn")); + checkReverseLookup(file, "ami", getWordPosition(file, "ami")); + + insertAndCheckWord(file, "abcdefzzzz", 40, false, null, null, formatOptions); + checkReverseLookup(file, "abcdefzzzz", getWordPosition(file, "abcdefzzzz")); - deleteWord(file, "ami", formatVersion); + deleteWord(file, "ami", formatOptions); assertEquals(FormatSpec.NOT_VALID_WORD, getWordPosition(file, "ami")); - insertAndCheckWord(file, "abcdabfg", 30, false, null, null, formatVersion); + insertAndCheckWord(file, "abcdabfg", 30, false, null, null, formatOptions); - deleteWord(file, "abcd", formatVersion); + deleteWord(file, "abcd", formatOptions); assertEquals(FormatSpec.NOT_VALID_WORD, getWordPosition(file, "abcd")); } public void testInsertWord() { - runTestInsertWord(VERSION3); + runTestInsertWord(BinaryDictUtils.VERSION3_WITH_DYNAMIC_UPDATE); + runTestInsertWord(BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE); } - private void runTestInsertWordWithBigrams(final int formatVersion) { - File file = null; - try { - file = File.createTempFile("testInsertWordWithBigrams", TEST_DICT_FILE_EXTENSION, - getContext().getCacheDir()); - } catch (IOException e) { - fail("IOException while creating temporary file: " + e); - } + private void runTestInsertWordWithBigrams(final FormatOptions formatOptions) { + final String testName = "testInsertWordWithBigrams"; + final String version = Long.toString(System.currentTimeMillis()); + File file = BinaryDictUtils.getDictFile(testName, version, formatOptions, + getContext().getCacheDir()); // set an initial dictionary. final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - new FusionDictionary.DictionaryOptions(new HashMap<String,String>(), false, false)); + BinaryDictUtils.makeDictionaryOptions(testName, version)); dict.add("abcd", 10, null, false); dict.add("efgh", 15, null, false); try { - final DictEncoder dictEncoder = new Ver3DictEncoder(file); - dictEncoder.writeDictionary(dict, FORMAT_OPTIONS); + final DictEncoder dictEncoder = BinaryDictUtils.getDictEncoder(file, formatOptions, + getContext().getCacheDir()); + dictEncoder.writeDictionary(dict, formatOptions); } catch (IOException e) { fail("IOException while writing an initial dictionary : " + e); } catch (UnsupportedFormatException e) { @@ -323,8 +318,8 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase { final ArrayList<WeightedString> banana = new ArrayList<WeightedString>(); banana.add(new WeightedString("banana", 10)); - insertAndCheckWord(file, "banana", 0, false, null, null, formatVersion); - insertAndCheckWord(file, "recursive", 60, true, banana, null, formatVersion); + insertAndCheckWord(file, "banana", 0, false, null, null, formatOptions); + insertAndCheckWord(file, "recursive", 60, true, banana, null, formatOptions); final PtNodeInfo info = findWordFromFile(file, "recursive"); int bananaPos = getWordPosition(file, "banana"); @@ -334,27 +329,25 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase { } public void testInsertWordWithBigrams() { - runTestInsertWordWithBigrams(VERSION3); + runTestInsertWordWithBigrams(BinaryDictUtils.VERSION3_WITH_DYNAMIC_UPDATE); + runTestInsertWordWithBigrams(BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE); } - private void runTestRandomWords(final int formatVersion) { - File file = null; - try { - file = File.createTempFile("testRandomWord", TEST_DICT_FILE_EXTENSION, - getContext().getCacheDir()); - } catch (IOException e) { - } - assertNotNull(file); + private void runTestRandomWords(final FormatOptions formatOptions) { + final String testName = "testRandomWord"; + final String version = Long.toString(System.currentTimeMillis()); + final File file = BinaryDictUtils.getDictFile(testName, version, formatOptions, + getContext().getCacheDir()); // set an initial dictionary. final FusionDictionary dict = new FusionDictionary(new PtNodeArray(), - new FusionDictionary.DictionaryOptions(new HashMap<String, String>(), false, - false)); + BinaryDictUtils.makeDictionaryOptions(testName, version)); dict.add("initial", 10, null, false); try { - final DictEncoder dictEncoder = new Ver3DictEncoder(file); - dictEncoder.writeDictionary(dict, FORMAT_OPTIONS); + final DictEncoder dictEncoder = BinaryDictUtils.getDictEncoder(file, formatOptions, + getContext().getCacheDir()); + dictEncoder.writeDictionary(dict, formatOptions); } catch (IOException e) { assertTrue(false); } catch (UnsupportedFormatException e) { @@ -366,7 +359,7 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase { int cnt = 0; for (final String word : sWords) { final long diff = insertAndCheckWord(file, word, - cnt % FormatSpec.MAX_TERMINAL_FREQUENCY, false, null, null, formatVersion); + cnt % FormatSpec.MAX_TERMINAL_FREQUENCY, false, null, null, formatOptions); maxTimeToInsert = Math.max(maxTimeToInsert, diff); minTimeToInsert = Math.min(minTimeToInsert, diff); sum += diff; @@ -377,13 +370,14 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase { MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, getWordPosition(file, word)); } - Log.d(TAG, "Test version " + formatVersion); + Log.d(TAG, "Test version " + formatOptions.mVersion); Log.d(TAG, "max = " + ((double)maxTimeToInsert/1000000) + " ms."); Log.d(TAG, "min = " + ((double)minTimeToInsert/1000000) + " ms."); Log.d(TAG, "avg = " + ((double)sum/mMaxUnigrams/1000000) + " ms."); } public void testRandomWords() { - runTestRandomWords(VERSION3); + runTestRandomWords(BinaryDictUtils.VERSION3_WITH_DYNAMIC_UPDATE); + runTestRandomWords(BinaryDictUtils.VERSION4_WITH_DYNAMIC_UPDATE); } } diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java new file mode 100644 index 000000000..ad17a7118 --- /dev/null +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictUtils.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.makedict; + +import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader; +import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions; +import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions; + +import java.io.File; +import java.util.HashMap; + +public class BinaryDictUtils { + public static final int USE_BYTE_ARRAY = 1; + public static final int USE_BYTE_BUFFER = 2; + + public static final String TEST_DICT_FILE_EXTENSION = ".testDict"; + + public static final FormatSpec.FormatOptions VERSION2 = + new FormatSpec.FormatOptions(FormatSpec.VERSION2); + public static final FormatSpec.FormatOptions VERSION3_WITHOUT_DYNAMIC_UPDATE = + new FormatSpec.FormatOptions(FormatSpec.VERSION3, false /* supportsDynamicUpdate */); + public static final FormatSpec.FormatOptions VERSION3_WITH_DYNAMIC_UPDATE = + new FormatSpec.FormatOptions(FormatSpec.VERSION3, true /* supportsDynamicUpdate */); + public static final FormatSpec.FormatOptions VERSION4_WITHOUT_DYNAMIC_UPDATE = + new FormatSpec.FormatOptions(FormatSpec.VERSION4, false /* supportsDynamicUpdate */); + public static final FormatSpec.FormatOptions VERSION4_WITH_DYNAMIC_UPDATE = + new FormatSpec.FormatOptions(FormatSpec.VERSION4, true /* supportsDynamicUpdate */); + public static final FormatSpec.FormatOptions VERSION4_WITH_DYNAMIC_UPDATE_AND_TIMESTAMP = + new FormatSpec.FormatOptions(FormatSpec.VERSION4, true /* supportsDynamicUpdate */, + true /* hasTimestamp */); + + public static DictionaryOptions makeDictionaryOptions(final String id, final String version) { + final DictionaryOptions options = new DictionaryOptions(new HashMap<String, String>(), + false /* germanUmlautProcessing */, false /* frenchLigatureProcessing */); + options.mAttributes.put(FileHeader.DICTIONARY_LOCALE_ATTRIBUTE, "en_US"); + options.mAttributes.put(FileHeader.DICTIONARY_ID_ATTRIBUTE, id); + options.mAttributes.put(FileHeader.DICTIONARY_VERSION_ATTRIBUTE, version); + return options; + } + + public static File getDictFile(final String name, final String version, + final FormatOptions formatOptions, final File directory) { + if (formatOptions.mVersion == FormatSpec.VERSION2 + || formatOptions.mVersion == FormatSpec.VERSION3) { + return new File(directory, name + "." + version + TEST_DICT_FILE_EXTENSION); + } else if (formatOptions.mVersion == FormatSpec.VERSION4) { + return new File(directory, name + "." + version); + } else { + throw new RuntimeException("the format option has a wrong version : " + + formatOptions.mVersion); + } + } + + public static DictEncoder getDictEncoder(final File file, final FormatOptions formatOptions, + final File cacheDir) { + if (formatOptions.mVersion == FormatSpec.VERSION4) { + return new Ver4DictEncoder(cacheDir); + } else if (formatOptions.mVersion == FormatSpec.VERSION3 + || formatOptions.mVersion == FormatSpec.VERSION2) { + return new Ver3DictEncoder(file); + } else { + throw new RuntimeException("The format option has a wrong version : " + + formatOptions.mVersion); + } + } + + public static DictUpdater getDictUpdater(final File file, final FormatOptions formatOptions) + throws UnsupportedFormatException { + if (formatOptions.mVersion == FormatSpec.VERSION4) { + return new Ver4DictUpdater(file, DictDecoder.USE_WRITABLE_BYTEBUFFER); + } else if (formatOptions.mVersion == FormatSpec.VERSION3) { + return new Ver3DictUpdater(file, DictDecoder.USE_WRITABLE_BYTEBUFFER); + } else { + throw new UnsupportedFormatException("The format option has a wrong version : " + + formatOptions.mVersion); + } + } +} diff --git a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java index 7c1decb71..17423a7ba 100644 --- a/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java +++ b/tests/src/com/android/inputmethod/latin/personalization/UserHistoryDictionaryTests.java @@ -16,8 +16,6 @@ package com.android.inputmethod.latin.personalization; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; @@ -28,6 +26,7 @@ import com.android.inputmethod.latin.utils.CollectionUtils; import java.io.File; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Random; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -38,21 +37,12 @@ import java.util.concurrent.TimeUnit; @LargeTest public class UserHistoryDictionaryTests extends AndroidTestCase { private static final String TAG = UserHistoryDictionaryTests.class.getSimpleName(); - private SharedPreferences mPrefs; private static final String[] CHARACTERS = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" }; - private static final int MIN_USER_HISTORY_DICTIONARY_FILE_SIZE = 1000; - private static final int WAIT_TERMINATING_IN_MILLISECONDS = 100; - - @Override - public void setUp() { - mPrefs = PreferenceManager.getDefaultSharedPreferences(getContext()); - } - /** * Generates a random word. */ @@ -78,7 +68,8 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { private void addToDict(final UserHistoryDictionary dict, final List<String> words) { String prevWord = null; for (String word : words) { - dict.addToDictionary(prevWord, word, true); + dict.addToDictionary(prevWord, word, true, + (int)TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())); prevWord = word; } } @@ -92,14 +83,11 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { final List<String> words = generateWords(numberOfWords, random); final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary(getContext(), - testFilenameSuffix /* locale */, mPrefs); + new Locale(testFilenameSuffix)); // Add random words to the user history dictionary. addToDict(dict, words); if (checkContents) { - try { - Thread.sleep(TimeUnit.MILLISECONDS.convert(5L, TimeUnit.SECONDS)); - } catch (InterruptedException e) { - } + dict.waitAllTasksForTests(); for (int i = 0; i < numberOfWords; ++i) { final String word = words.get(i); assertTrue(dict.isInDictionaryForTests(word)); @@ -116,7 +104,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { private void clearHistory(final String testFilenameSuffix) { final UserHistoryDictionary dict = PersonalizationHelper.getUserHistoryDictionary(getContext(), - testFilenameSuffix /* locale */, mPrefs); + new Locale(testFilenameSuffix)); dict.clearAndFlushDictionary(); dict.close(); } @@ -126,23 +114,16 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { * @param testFilenameSuffix file name suffix used for testing. */ private void waitForWriting(final String testFilenameSuffix) { - try { - final UserHistoryDictionary dict = - PersonalizationHelper.getUserHistoryDictionary(getContext(), - testFilenameSuffix, mPrefs); - dict.shutdownExecutorForTests(); - while (!dict.isTerminatedForTests()) { - Thread.sleep(WAIT_TERMINATING_IN_MILLISECONDS); - } - } catch (InterruptedException e) { - Log.d(TAG, "InterruptedException: ", e); - } + final UserHistoryDictionary dict = + PersonalizationHelper.getUserHistoryDictionary(getContext(), + new Locale(testFilenameSuffix)); + dict.waitAllTasksForTests(); } public void testRandomWords() { Log.d(TAG, "This test can be used for profiling."); Log.d(TAG, "Usage: please set UserHistoryDictionary.PROFILE_SAVE_RESTORE to true."); - final String testFilenameSuffix = "testRandomWords" + System.currentTimeMillis(); + final String testFilenameSuffix = "test_random_words" + System.currentTimeMillis(); final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffix + ExpandableBinaryDictionary.DICT_FILE_EXTENSION; @@ -159,7 +140,6 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { final File dictFile = new File(getContext().getFilesDir(), fileName); if (dictFile != null) { assertTrue(dictFile.exists()); - assertTrue(dictFile.length() >= MIN_USER_HISTORY_DICTIONARY_FILE_SIZE); dictFile.delete(); } } @@ -177,9 +157,9 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { // Create filename suffixes for this test. for (int i = 0; i < numberOfLanguages; i++) { - testFilenameSuffixes[i] = "testSwitchingLanguages" + i; - final String fileName = UserHistoryDictionary.NAME + "." + - testFilenameSuffixes[i] + ExpandableBinaryDictionary.DICT_FILE_EXTENSION; + testFilenameSuffixes[i] = "test_switching_languages" + i; + final String fileName = UserHistoryDictionary.NAME + "." + testFilenameSuffixes[i] + + ExpandableBinaryDictionary.DICT_FILE_EXTENSION; dictFiles[i] = new File(getContext().getFilesDir(), fileName); clearHistory(testFilenameSuffixes[i]); } @@ -205,7 +185,6 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { for (final File file : dictFiles) { if (file != null) { assertTrue(file.exists()); - assertTrue(file.length() >= MIN_USER_HISTORY_DICTIONARY_FILE_SIZE); file.delete(); } } @@ -213,10 +192,8 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { } public void testAddManyWords() { - final String testFilenameSuffix = "testRandomWords" + System.currentTimeMillis(); - final int numberOfWords = - ExpandableBinaryDictionary.ENABLE_BINARY_DICTIONARY_DYNAMIC_UPDATE ? - 10000 : 1000; + final String testFilenameSuffix = "test_random_words" + System.currentTimeMillis(); + final int numberOfWords = 10000; final Random random = new Random(123456); clearHistory(testFilenameSuffix); try { @@ -230,7 +207,6 @@ public class UserHistoryDictionaryTests extends AndroidTestCase { final File dictFile = new File(getContext().getFilesDir(), fileName); if (dictFile != null) { assertTrue(dictFile.exists()); - assertTrue(dictFile.length() >= MIN_USER_HISTORY_DICTIONARY_FILE_SIZE); dictFile.delete(); } } diff --git a/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/StringAndJsonUtilsTests.java index 4e396a1cf..2123e84e8 100644 --- a/tests/src/com/android/inputmethod/latin/utils/StringUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/StringAndJsonUtilsTests.java @@ -26,7 +26,7 @@ import java.util.List; import java.util.Locale; @SmallTest -public class StringUtilsTests extends AndroidTestCase { +public class StringAndJsonUtilsTests extends AndroidTestCase { public void testContainsInArray() { assertFalse("empty array", StringUtils.containsInArray("key", new String[0])); assertFalse("not in 1 element", StringUtils.containsInArray("key", new String[] { @@ -44,7 +44,7 @@ public class StringUtilsTests extends AndroidTestCase { })); } - public void testContainsInExtraValues() { + public void testContainsInCommaSplittableText() { assertFalse("null", StringUtils.containsInCommaSplittableText("key", null)); assertFalse("empty", StringUtils.containsInCommaSplittableText("key", "")); assertFalse("not in 1 element", @@ -56,7 +56,28 @@ public class StringUtilsTests extends AndroidTestCase { assertTrue("in 2 elements", StringUtils.containsInCommaSplittableText("key", "key1,key")); } - public void testAppendToExtraValuesIfNotExists() { + public void testJoinCommaSplittableText() { + assertEquals("2 nulls", "", + StringUtils.joinCommaSplittableText(null, null)); + assertEquals("null and empty", "", + StringUtils.joinCommaSplittableText(null, "")); + assertEquals("empty and null", "", + StringUtils.joinCommaSplittableText("", null)); + assertEquals("2 empties", "", + StringUtils.joinCommaSplittableText("", "")); + assertEquals("text and null", "text", + StringUtils.joinCommaSplittableText("text", null)); + assertEquals("text and empty", "text", + StringUtils.joinCommaSplittableText("text", "")); + assertEquals("null and text", "text", + StringUtils.joinCommaSplittableText(null, "text")); + assertEquals("empty and text", "text", + StringUtils.joinCommaSplittableText("", "text")); + assertEquals("2 texts", "text1,text2", + StringUtils.joinCommaSplittableText("text1", "text2")); + } + + public void testAppendToCommaSplittableTextIfNotExists() { assertEquals("null", "key", StringUtils.appendToCommaSplittableTextIfNotExists("key", null)); assertEquals("empty", "key", @@ -77,7 +98,7 @@ public class StringUtilsTests extends AndroidTestCase { StringUtils.appendToCommaSplittableTextIfNotExists("key", "key1,key,key3")); } - public void testRemoveFromExtraValuesIfExists() { + public void testRemoveFromCommaSplittableTextIfExists() { assertEquals("null", "", StringUtils.removeFromCommaSplittableTextIfExists("key", null)); assertEquals("empty", "", StringUtils.removeFromCommaSplittableTextIfExists("key", "")); @@ -271,11 +292,11 @@ public class StringUtilsTests extends AndroidTestCase { assertTrue(bytesStr.equals(bytesStr2)); } - public void testJsonStringUtils() { + public void testJsonUtils() { final Object[] objs = new Object[] { 1, "aaa", "bbb", 3 }; final List<Object> objArray = Arrays.asList(objs); - final String str = StringUtils.listToJsonStr(objArray); - final List<Object> newObjArray = StringUtils.jsonStrToList(str); + final String str = JsonUtils.listToJsonStr(objArray); + final List<Object> newObjArray = JsonUtils.jsonStrToList(str); for (int i = 0; i < objs.length; ++i) { assertEquals(objs[i], newObjArray.get(i)); } diff --git a/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java index 856b2dbda..ccdd56750 100644 --- a/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java @@ -41,7 +41,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { InputMethodSubtype ES_US; InputMethodSubtype FR; InputMethodSubtype FR_CA; + InputMethodSubtype FR_CH; InputMethodSubtype DE; + InputMethodSubtype DE_CH; InputMethodSubtype ZZ; InputMethodSubtype DE_QWERTY; InputMethodSubtype FR_QWERTZ; @@ -70,8 +72,12 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { Locale.FRENCH.toString(), "azerty"); FR_CA = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( Locale.CANADA_FRENCH.toString(), "qwerty"); + FR_CH = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + "fr_CH", "swiss"); DE = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( Locale.GERMAN.toString(), "qwertz"); + DE_CH = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( + "de_CH", "swiss"); ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( SubtypeLocaleUtils.NO_LANGUAGE, "qwerty"); DE_QWERTY = AdditionalSubtypeUtils.createAdditionalSubtype( @@ -112,7 +118,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { assertEquals("es_US", "spanish", SubtypeLocaleUtils.getKeyboardLayoutSetName(ES_US)); assertEquals("fr ", "azerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR)); assertEquals("fr_CA", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR_CA)); + assertEquals("fr_CH", "swiss", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR_CH)); assertEquals("de ", "qwertz", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE)); + assertEquals("de_CH", "swiss", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE_CH)); assertEquals("zz ", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(ZZ)); } @@ -125,7 +133,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { // es_US spanish F Spanish (US) exception // fr azerty F French // fr_CA qwerty F French (Canada) + // fr_CH swiss F French (Switzerland) // de qwertz F German + // de_CH swiss F German (Switzerland) // zz qwerty F Alphabet (QWERTY) // fr qwertz T French (QWERTZ) // de qwerty T German (QWERTY) @@ -148,8 +158,12 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR)); assertEquals("fr_CA", "French (Canada)", SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CA)); + assertEquals("fr_CH", "French (Switzerland)", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CH)); assertEquals("de ", "German", SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE)); + assertEquals("de_CH", "German (Switzerland)", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_CH)); assertEquals("zz ", "Alphabet (QWERTY)", SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ)); return null; @@ -189,7 +203,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { // es_US spanish F Espagnol (États-Unis) exception // fr azerty F Français // fr_CA qwerty F Français (Canada) + // fr_CH swiss F Français (Suisse) // de qwertz F Allemand + // de_CH swiss F Allemand (Suisse) // zz qwerty F Aucune langue (QWERTY) // fr qwertz T Français (QWERTZ) // de qwerty T Allemand (QWERTY) @@ -212,8 +228,12 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR)); assertEquals("fr_CA", "Français (Canada)", SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CA)); + assertEquals("fr_CH", "Français (Suisse)", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CH)); assertEquals("de ", "Allemand", SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE)); + assertEquals("de_CH", "Allemand (Suisse)", + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_CH)); assertEquals("zz ", "Alphabet latin (QWERTY)", SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ)); return null; @@ -300,7 +320,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { // es_US spanish F Es Español Español (EE.UU.) exception // fr azerty F Fr Français Français // fr_CA qwerty F Fr Français Français (Canada) + // fr_CH swiss F Fr Français Français (Suisse) // de qwertz F De Deutsch Deutsch + // de_CH swiss F De Deutsch Deutsch (Schweiz) // zz qwerty F QWERTY QWERTY // fr qwertz T Fr Français Français // de qwerty T De Deutsch Deutsch @@ -317,7 +339,11 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { assertEquals("fr ", "Français", SubtypeLocaleUtils.getFullDisplayName(FR)); assertEquals("fr_CA", "Français (Canada)", SubtypeLocaleUtils.getFullDisplayName(FR_CA)); + assertEquals("fr_CH", "Français (Suisse)", + SubtypeLocaleUtils.getFullDisplayName(FR_CH)); assertEquals("de ", "Deutsch", SubtypeLocaleUtils.getFullDisplayName(DE)); + assertEquals("de_CH", "Deutsch (Schweiz)", + SubtypeLocaleUtils.getFullDisplayName(DE_CH)); assertEquals("zz ", "QWERTY", SubtypeLocaleUtils.getFullDisplayName(ZZ)); assertEquals("en_US", "English", SubtypeLocaleUtils.getMiddleDisplayName(EN_US)); @@ -325,7 +351,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { assertEquals("es_US", "Español", SubtypeLocaleUtils.getMiddleDisplayName(ES_US)); assertEquals("fr ", "Français", SubtypeLocaleUtils.getMiddleDisplayName(FR)); assertEquals("fr_CA", "Français", SubtypeLocaleUtils.getMiddleDisplayName(FR_CA)); + assertEquals("fr_CH", "Français", SubtypeLocaleUtils.getMiddleDisplayName(FR_CH)); assertEquals("de ", "Deutsch", SubtypeLocaleUtils.getMiddleDisplayName(DE)); + assertEquals("de_CH", "Deutsch", SubtypeLocaleUtils.getMiddleDisplayName(DE_CH)); assertEquals("zz ", "QWERTY", SubtypeLocaleUtils.getMiddleDisplayName(ZZ)); assertEquals("en_US", "En", SubtypeLocaleUtils.getShortDisplayName(EN_US)); @@ -333,7 +361,9 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase { assertEquals("es_US", "Es", SubtypeLocaleUtils.getShortDisplayName(ES_US)); assertEquals("fr ", "Fr", SubtypeLocaleUtils.getShortDisplayName(FR)); assertEquals("fr_CA", "Fr", SubtypeLocaleUtils.getShortDisplayName(FR_CA)); + assertEquals("fr_CH", "Fr", SubtypeLocaleUtils.getShortDisplayName(FR_CH)); assertEquals("de ", "De", SubtypeLocaleUtils.getShortDisplayName(DE)); + assertEquals("de_CH", "De", SubtypeLocaleUtils.getShortDisplayName(DE_CH)); assertEquals("zz ", "", SubtypeLocaleUtils.getShortDisplayName(ZZ)); return null; } diff --git a/tests/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtilsTests.java index 1944fd332..fc921b4fd 100644 --- a/tests/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/UserHistoryDictIOUtilsTests.java @@ -24,8 +24,10 @@ import android.util.Log; import com.android.inputmethod.latin.makedict.DictDecoder; import com.android.inputmethod.latin.makedict.DictEncoder; import com.android.inputmethod.latin.makedict.FormatSpec; +import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader; import com.android.inputmethod.latin.makedict.FusionDictionary; import com.android.inputmethod.latin.makedict.FusionDictionary.PtNode; +import com.android.inputmethod.latin.makedict.UnsupportedFormatException; import com.android.inputmethod.latin.makedict.Ver3DictDecoder; import com.android.inputmethod.latin.makedict.Ver3DictEncoder; import com.android.inputmethod.latin.personalization.UserHistoryDictionaryBigramList; @@ -52,6 +54,12 @@ public class UserHistoryDictIOUtilsTests extends AndroidTestCase private static final ArrayList<String> NOT_HAVE_BIGRAM = new ArrayList<String>(); private static final FormatSpec.FormatOptions FORMAT_OPTIONS = new FormatSpec.FormatOptions(2); private static final String TEST_DICT_FILE_EXTENSION = ".testDict"; + private static final HashMap<String, String> HEADER_OPTIONS = new HashMap<String, String>(); + static { + HEADER_OPTIONS.put(FileHeader.DICTIONARY_LOCALE_ATTRIBUTE, "en_US"); + HEADER_OPTIONS.put(FileHeader.DICTIONARY_ID_ATTRIBUTE, "test"); + HEADER_OPTIONS.put(FileHeader.DICTIONARY_VERSION_ATTRIBUTE, "1000"); + } /** * Return same frequency for all words and bigrams @@ -139,18 +147,14 @@ public class UserHistoryDictIOUtilsTests extends AndroidTestCase private void writeDictToFile(final File file, final UserHistoryDictionaryBigramList bigramList) { final DictEncoder dictEncoder = new Ver3DictEncoder(file); - UserHistoryDictIOUtils.writeDictionary(dictEncoder, this, bigramList, FORMAT_OPTIONS); + UserHistoryDictIOUtils.writeDictionary(dictEncoder, this, bigramList, FORMAT_OPTIONS, + HEADER_OPTIONS); } - private void readDictFromFile(final File file, final OnAddWordListener listener) { + private void readDictFromFile(final File file, final OnAddWordListener listener) + throws IOException, FileNotFoundException, UnsupportedFormatException { final DictDecoder dictDecoder = FormatSpec.getDictDecoder(file, DictDecoder.USE_BYTEARRAY); - try { - dictDecoder.openDictBuffer(); - } catch (FileNotFoundException e) { - Log.e(TAG, "file not found", e); - } catch (IOException e) { - Log.e(TAG, "IOException", e); - } + dictDecoder.openDictBuffer(); UserHistoryDictIOUtils.readDictionaryBinary(dictDecoder, listener); } @@ -163,13 +167,14 @@ public class UserHistoryDictIOUtilsTests extends AndroidTestCase addBigramToBigramList("this", "was", addedWords, originalList); addBigramToBigramList("hello", "world", addedWords, originalList); - final FusionDictionary fusionDict = - UserHistoryDictIOUtils.constructFusionDictionary(this, originalList); + final FusionDictionary fusionDict = UserHistoryDictIOUtils.constructFusionDictionary( + this, originalList, HEADER_OPTIONS); checkWordsInFusionDict(fusionDict, addedWords); } - public void testReadAndWrite() { + public void testReadAndWrite() throws IOException, FileNotFoundException, + UnsupportedFormatException { final Context context = getContext(); File file = null; |