diff options
Diffstat (limited to 'tests/src')
5 files changed, 286 insertions, 29 deletions
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/HermiteInterpolatorTests.java b/tests/src/com/android/inputmethod/keyboard/internal/HermiteInterpolatorTests.java new file mode 100644 index 000000000..3ff5aa485 --- /dev/null +++ b/tests/src/com/android/inputmethod/keyboard/internal/HermiteInterpolatorTests.java @@ -0,0 +1,203 @@ +/* + * 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.keyboard.internal; + +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; + +@SmallTest +public class HermiteInterpolatorTests extends AndroidTestCase { + private final HermiteInterpolator mInterpolator = new HermiteInterpolator(); + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + private static final float EPSLION = 0.0000005f; + + private static void assertFloatEquals(final String message, float expected, float actual) { + if (Math.abs(expected - actual) >= EPSLION) { + fail(String.format("%s expected:<%s> but was:<%s>", message, expected, actual)); + } + } + + // t=0 p0=(0,1) + // t=1 p1=(1,0) + // t=2 p2=(3,2) + // t=3 p3=(2,3) + // y + // | + // 3 + o p3 + // | + // 2 + o p2 + // | + // 1 o p0 + // | p1 + // 0 +---o---+---+-- x + // 0 1 2 3 + private final int[] mXCoords = { 0, 1, 3, 2 }; + private final int[] mYCoords = { 1, 0, 2, 3 }; + private static final int p0 = 0; + private static final int p1 = 1; + private static final int p2 = 2; + private static final int p3 = 3; + + public void testP0P1() { + // [(p0 p1) p2 p3] + mInterpolator.reset(mXCoords, mYCoords, p0, p3 + 1); + mInterpolator.setInterval(p0 - 1, p0, p1, p1 + 1); + assertEquals("p0x", mXCoords[p0], mInterpolator.mP1X); + assertEquals("p0y", mYCoords[p0], mInterpolator.mP1Y); + assertEquals("p1x", mXCoords[p1], mInterpolator.mP2X); + assertEquals("p1y", mYCoords[p1], mInterpolator.mP2Y); + // XY-slope at p0=3.0 (-0.75/-0.25) + assertFloatEquals("slope x p0", -0.25f, mInterpolator.mSlope1X); + assertFloatEquals("slope y p0", -0.75f, mInterpolator.mSlope1Y); + // XY-slope at p1=1/3.0 (0.50/1.50) + assertFloatEquals("slope x p1", 1.50f, mInterpolator.mSlope2X); + assertFloatEquals("slope y p1", 0.50f, mInterpolator.mSlope2Y); + // t=0.0 (p0) + mInterpolator.interpolate(0.0f); + assertFloatEquals("t=0.0 x", 0.0f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.0 y", 1.0f, mInterpolator.mInterpolatedY); + // t=0.2 + mInterpolator.interpolate(0.2f); + assertFloatEquals("t=0.2 x", 0.02400f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.2 y", 0.78400f, mInterpolator.mInterpolatedY); + // t=0.5 + mInterpolator.interpolate(0.5f); + assertFloatEquals("t=0.5 x", 0.28125f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.5 y", 0.34375f, mInterpolator.mInterpolatedY); + // t=0.8 + mInterpolator.interpolate(0.8f); + assertFloatEquals("t=0.8 x", 0.69600f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.8 y", 0.01600f, mInterpolator.mInterpolatedY); + // t=1.0 (p1) + mInterpolator.interpolate(1.0f); + assertFloatEquals("t=1.0 x", 1.0f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=1.0 y", 0.0f, mInterpolator.mInterpolatedY); + } + + public void testP1P2() { + // [p0 (p1 p2) p3] + mInterpolator.reset(mXCoords, mYCoords, p0, p3 + 1); + mInterpolator.setInterval(p1 - 1, p1, p2, p2 + 1); + assertEquals("p1x", mXCoords[p1], mInterpolator.mP1X); + assertEquals("p1y", mYCoords[p1], mInterpolator.mP1Y); + assertEquals("p2x", mXCoords[p2], mInterpolator.mP2X); + assertEquals("p2y", mYCoords[p2], mInterpolator.mP2Y); + // XY-slope at p1=1/3.0 (0.50/1.50) + assertFloatEquals("slope x p1", 1.50f, mInterpolator.mSlope1X); + assertFloatEquals("slope y p1", 0.50f, mInterpolator.mSlope1Y); + // XY-slope at p2=3.0 (1.50/0.50) + assertFloatEquals("slope x p2", 0.50f, mInterpolator.mSlope2X); + assertFloatEquals("slope y p2", 1.50f, mInterpolator.mSlope2Y); + // t=0.0 (p1) + mInterpolator.interpolate(0.0f); + assertFloatEquals("t=0.0 x", 1.0f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.0 y", 0.0f, mInterpolator.mInterpolatedY); + // t=0.2 + mInterpolator.interpolate(0.2f); + assertFloatEquals("t=0.2 x", 1.384f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.2 y", 0.224f, mInterpolator.mInterpolatedY); + // t=0.5 + mInterpolator.interpolate(0.5f); + assertFloatEquals("t=0.5 x", 2.125f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.5 y", 0.875f, mInterpolator.mInterpolatedY); + // t=0.8 + mInterpolator.interpolate(0.8f); + assertFloatEquals("t=0.8 x", 2.776f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.8 y", 1.616f, mInterpolator.mInterpolatedY); + // t=1.0 (p2) + mInterpolator.interpolate(1.0f); + assertFloatEquals("t=1.0 x", 3.0f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=1.0 y", 2.0f, mInterpolator.mInterpolatedY); + } + + public void testP2P3() { + // [p0 p1 (p2 p3)] + mInterpolator.reset(mXCoords, mYCoords, p0, p3 + 1); + mInterpolator.setInterval(p2 - 1, p2, p3, p3 + 1); + assertEquals("p2x", mXCoords[p2], mInterpolator.mP1X); + assertEquals("p2y", mYCoords[p2], mInterpolator.mP1Y); + assertEquals("p3x", mXCoords[p3], mInterpolator.mP2X); + assertEquals("p3y", mYCoords[p3], mInterpolator.mP2Y); + // XY-slope at p2=3.0 (1.50/0.50) + assertFloatEquals("slope x p2", 0.50f, mInterpolator.mSlope1X); + assertFloatEquals("slope y p2", 1.50f, mInterpolator.mSlope1Y); + // XY-slope at p3=1/3.0 (-0.25/-0.75) + assertFloatEquals("slope x p3", -0.75f, mInterpolator.mSlope2X); + assertFloatEquals("slope y p3", -0.25f, mInterpolator.mSlope2Y); + // t=0.0 (p2) + mInterpolator.interpolate(0.0f); + assertFloatEquals("t=0.0 x", 3.0f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.0 y", 2.0f, mInterpolator.mInterpolatedY); + // t=0.2 + mInterpolator.interpolate(0.2f); + assertFloatEquals("t=0.2 x", 2.98400f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.2 y", 2.30400f, mInterpolator.mInterpolatedY); + // t=0.5 + mInterpolator.interpolate(0.5f); + assertFloatEquals("t=0.5 x", 2.65625f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.5 y", 2.71875f, mInterpolator.mInterpolatedY); + // t=0.8 + mInterpolator.interpolate(0.8f); + assertFloatEquals("t=0.8 x", 2.21600f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.8 y", 2.97600f, mInterpolator.mInterpolatedY); + // t=1.0 (p3) + mInterpolator.interpolate(1.0f); + assertFloatEquals("t=1.0 x", 2.0f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=1.0 y", 3.0f, mInterpolator.mInterpolatedY); + } + + public void testJustP1P2() { + // [(p1 p2)] + mInterpolator.reset(mXCoords, mYCoords, p1, p2 + 1); + mInterpolator.setInterval(p1 - 1, p1, p2, p2 + 1); + assertEquals("p1x", mXCoords[p1], mInterpolator.mP1X); + assertEquals("p1y", mYCoords[p1], mInterpolator.mP1Y); + assertEquals("p2x", mXCoords[p2], mInterpolator.mP2X); + assertEquals("p2y", mYCoords[p2], mInterpolator.mP2Y); + // XY-slope at p1=1.0 (2.0/2.0) + assertFloatEquals("slope x p1", 2.00f, mInterpolator.mSlope1X); + assertFloatEquals("slope y p1", 2.00f, mInterpolator.mSlope1Y); + // XY-slope at p2=1.0 (2.0/2.0) + assertFloatEquals("slope x p2", 2.00f, mInterpolator.mSlope2X); + assertFloatEquals("slope y p2", 2.00f, mInterpolator.mSlope2Y); + // t=0.0 (p1) + mInterpolator.interpolate(0.0f); + assertFloatEquals("t=0.0 x", 1.0f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.0 y", 0.0f, mInterpolator.mInterpolatedY); + // t=0.2 + mInterpolator.interpolate(0.2f); + assertFloatEquals("t=0.2 x", 1.4f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.2 y", 0.4f, mInterpolator.mInterpolatedY); + // t=0.5 + mInterpolator.interpolate(0.5f); + assertFloatEquals("t=0.5 x", 2.0f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.5 y", 1.0f, mInterpolator.mInterpolatedY); + // t=0.8 + mInterpolator.interpolate(0.8f); + assertFloatEquals("t=0.8 x", 2.6f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=0.8 y", 1.6f, mInterpolator.mInterpolatedY); + // t=1.0 (p2) + mInterpolator.interpolate(1.0f); + assertFloatEquals("t=1.0 x", 3.0f, mInterpolator.mInterpolatedX); + assertFloatEquals("t=1.0 y", 2.0f, mInterpolator.mInterpolatedY); + } +} diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java index 05f39551b..d05aabf51 100644 --- a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java +++ b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserCsvTests.java @@ -56,7 +56,8 @@ public class KeySpecParserCsvTests extends InstrumentationTestCase { return names.toArray(new String[names.size()]); } - private static void assertArrayEquals(String message, Object[] expected, Object[] actual) { + private static void assertArrayEquals(final String message, final Object[] expected, + final Object[] actual) { if (expected == actual) { return; } @@ -74,14 +75,15 @@ public class KeySpecParserCsvTests extends InstrumentationTestCase { } } - private void assertTextArray(String message, String value, String ... expectedArray) { + private void assertTextArray(final String message, final String value, + final String ... expectedArray) { final String resolvedActual = KeySpecParser.resolveTextReference(value, mTextsSet); final String[] actual = StringUtils.parseCsvString(resolvedActual); final String[] expected = (expectedArray.length == 0) ? null : expectedArray; assertArrayEquals(message, expected, actual); } - private void assertError(String message, String value, String ... expected) { + private void assertError(final String message, final String value, final String ... expected) { try { assertTextArray(message, value, expected); fail(message); diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java index 4ccbf4857..4583eab2f 100644 --- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java +++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java @@ -36,6 +36,7 @@ import android.widget.TextView; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import java.util.Locale; @@ -130,7 +131,9 @@ public class InputTestsBase extends ServiceTestCase<LatinIME> { protected void setUp() throws Exception { super.setUp(); mTextView = new MyTextView(getContext()); - mTextView.setInputType(InputType.TYPE_CLASS_TEXT); + final int inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT + | InputType.TYPE_TEXT_FLAG_MULTI_LINE; + mTextView.setInputType(inputType); mTextView.setEnabled(true); setupService(); mLatinIME = getService(); @@ -138,9 +141,7 @@ public class InputTestsBase extends ServiceTestCase<LatinIME> { mLatinIME.onCreate(); setDebugMode(previousDebugSetting); final EditorInfo ei = new EditorInfo(); - ei.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT; final InputConnection ic = mTextView.onCreateInputConnection(ei); - ei.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT; final LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); final ViewGroup vg = new FrameLayout(getContext()); @@ -181,17 +182,21 @@ public class InputTestsBase extends ServiceTestCase<LatinIME> { // a message that calls it instead of calling it directly. Looper.loop(); - // Once #quit() has been called, the message queue has an "mQuiting" field that prevents - // any subsequent post in this queue. However the queue itself is still fully functional! - // If we have a way of resetting "queue.mQuiting" then we can continue using it as normal, - // coming back to this method to run the messages. + // Once #quit() has been called, the looper is not functional any more (it used to be, + // but now it SIGSEGV's if it's used again). + // It won't accept creating a new looper for this thread and switching to it... + // ...unless we can trick it into throwing out the old looper and believing it hasn't + // been initialized before. MessageQueue queue = Looper.myQueue(); try { - // However there is no way of doing it externally, and mQuiting is private. + // However there is no way of doing it externally, and the static ThreadLocal + // field into which it's stored is private. // So... get out the big guns. - java.lang.reflect.Field f = MessageQueue.class.getDeclaredField("mQuiting"); - f.setAccessible(true); // What do you mean "private"? - f.setBoolean(queue, false); + java.lang.reflect.Field f = Looper.class.getDeclaredField("sThreadLocal"); + f.setAccessible(true); // private lolwut + final ThreadLocal<Looper> a = (ThreadLocal<Looper>) f.get(looper); + a.set(null); + looper.prepare(); } catch (NoSuchFieldException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { @@ -251,7 +256,8 @@ public class InputTestsBase extends ServiceTestCase<LatinIME> { } protected void pickSuggestionManually(final int index, final String suggestion) { - mLatinIME.pickSuggestionManually(index, suggestion); + mLatinIME.pickSuggestionManually(index, new SuggestedWordInfo(suggestion, 1, + SuggestedWordInfo.KIND_CORRECTION, "main")); } // Helper to avoid writing the try{}catch block each time diff --git a/tests/src/com/android/inputmethod/latin/StringUtilsTests.java b/tests/src/com/android/inputmethod/latin/StringUtilsTests.java index 923ab2ecc..966919ed3 100644 --- a/tests/src/com/android/inputmethod/latin/StringUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/StringUtilsTests.java @@ -19,6 +19,8 @@ package com.android.inputmethod.latin; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; +import java.util.Locale; + @SmallTest public class StringUtilsTests extends AndroidTestCase { public void testContainsInArray() { @@ -90,4 +92,48 @@ public class StringUtilsTests extends AndroidTestCase { assertEquals("in 5 elements at position 2,4", "key1,key3,key5", StringUtils.removeFromCsvIfExists("key", "key1,key,key3,key,key5")); } + + public void testToTitleCase() { + assertEquals("SSaa", + StringUtils.toTitleCase("ßaa", Locale.GERMAN)); + assertEquals("Aßa", + StringUtils.toTitleCase("aßa", Locale.GERMAN)); + assertEquals("Iab", + StringUtils.toTitleCase("iab", Locale.ENGLISH)); + assertEquals("Camelcase", + StringUtils.toTitleCase("cAmElCaSe", Locale.ENGLISH)); + assertEquals("İab", + StringUtils.toTitleCase("iab", new Locale("tr"))); + assertEquals("Aib", + StringUtils.toTitleCase("AİB", new Locale("tr"))); + // For one character, toTitleCase returns the string as is. Not sure what the motivation + // is, but that's how it works now. + assertEquals("a", + StringUtils.toTitleCase("a", Locale.ENGLISH)); + assertEquals("A", + StringUtils.toTitleCase("A", Locale.ENGLISH)); + } + + public void testGetCapitalizationType() { + assertEquals(StringUtils.CAPITALIZE_NONE, + StringUtils.getCapitalizationType("capitalize")); + assertEquals(StringUtils.CAPITALIZE_NONE, + StringUtils.getCapitalizationType("cApITalize")); + assertEquals(StringUtils.CAPITALIZE_NONE, + StringUtils.getCapitalizationType("capitalizE")); + assertEquals(StringUtils.CAPITALIZE_NONE, + StringUtils.getCapitalizationType("__c a piu$@tali56ze")); + assertEquals(StringUtils.CAPITALIZE_FIRST, + StringUtils.getCapitalizationType("A__c a piu$@tali56ze")); + assertEquals(StringUtils.CAPITALIZE_FIRST, + StringUtils.getCapitalizationType("Capitalize")); + assertEquals(StringUtils.CAPITALIZE_FIRST, + StringUtils.getCapitalizationType(" Capitalize")); + assertEquals(StringUtils.CAPITALIZE_ALL, + StringUtils.getCapitalizationType("CAPITALIZE")); + assertEquals(StringUtils.CAPITALIZE_ALL, + StringUtils.getCapitalizationType(" PI26LIE")); + assertEquals(StringUtils.CAPITALIZE_NONE, + StringUtils.getCapitalizationType("")); + } } diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java index ade010981..bd8729203 100644 --- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java +++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java @@ -72,15 +72,12 @@ public class BinaryDictIOTests extends AndroidTestCase { private static final FormatSpec.FormatOptions VERSION3_WITH_DYNAMIC_UPDATE = new FormatSpec.FormatOptions(3, true /* supportsDynamicUpdate */); - 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" - }; - public BinaryDictIOTests() { super(); - final Random random = new Random(123456); + final long time = System.currentTimeMillis(); + Log.e(TAG, "Testing dictionary: seed is " + time); + final Random random = new Random(time); sWords.clear(); generateWords(MAX_UNIGRAMS, random); @@ -132,13 +129,16 @@ public class BinaryDictIOTests extends AndroidTestCase { /** * Generates a random word. */ - private String generateWord(final int value) { - final int lengthOfChars = CHARACTERS.length; + private String generateWord(final Random random) { StringBuilder builder = new StringBuilder("a"); - long lvalue = Math.abs((long)value); - while (lvalue > 0) { - builder.append(CHARACTERS[(int)(lvalue % lengthOfChars)]); - lvalue /= lengthOfChars; + int count = random.nextInt() % 30; // Arbitrarily 30 chars max + while (count > 0) { + final long r = Math.abs(random.nextInt()); + if (r < 0) continue; + // Don't insert 0~20, but insert any other code point. + // Code points are in the range 0~0x10FFFF. + builder.appendCodePoint((int)(20 + r % (0x10FFFF - 20))); + --count; } return builder.toString(); } @@ -146,7 +146,7 @@ public class BinaryDictIOTests extends AndroidTestCase { private void generateWords(final int number, final Random random) { final Set<String> wordSet = CollectionUtils.newHashSet(); while (wordSet.size() < number) { - wordSet.add(generateWord(random.nextInt())); + wordSet.add(generateWord(random)); } sWords.addAll(wordSet); } @@ -555,7 +555,7 @@ public class BinaryDictIOTests extends AndroidTestCase { // Test a word that isn't contained within the dictionary. final Random random = new Random((int)System.currentTimeMillis()); for (int i = 0; i < 1000; ++i) { - final String word = generateWord(random.nextInt()); + final String word = generateWord(random); if (sWords.indexOf(word) != -1) continue; runGetTerminalPosition(buffer, word, i, false); } |