From 9ddbee8570af667b5b325ae4136853aaea85c5b9 Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Wed, 15 Oct 2014 18:14:59 +0900 Subject: [PATCH] Add the first gesture unit tests. At last I found a simple way to do it ! Bug: 8845843 Change-Id: I4dd3bf987b58e29a44cf0d7389d294657a33abe1 --- .../inputmethod/latin/BlueUnderlineTests.java | 20 ++++---- .../inputmethod/latin/InputLogicTests.java | 47 ++++++++++++----- .../InputLogicTestsLanguageWithoutSpaces.java | 4 +- .../latin/InputLogicTestsNonEnglish.java | 4 +- .../inputmethod/latin/InputTestsBase.java | 51 +++++++++++++++++-- .../inputmethod/latin/PunctuationTests.java | 2 +- .../inputmethod/latin/ShiftModeTests.java | 2 +- 7 files changed, 98 insertions(+), 32 deletions(-) diff --git a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java index 30b088137..ae5cc5c73 100644 --- a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java +++ b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java @@ -28,7 +28,7 @@ public class BlueUnderlineTests extends InputTestsBase { final int EXPECTED_SPAN_START = 0; final int EXPECTED_SPAN_END = 4; type(STRING_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); final SpanGetter span = new SpanGetter(mEditText.getText(), SuggestionSpan.class); assertEquals("show blue underline, span start", EXPECTED_SPAN_START, span.mStart); @@ -42,7 +42,7 @@ public class BlueUnderlineTests extends InputTestsBase { final int EXPECTED_SPAN_START = 0; final int EXPECTED_SPAN_END = 5; type(STRING_1_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); type(STRING_2_TO_TYPE); // We haven't have time to look into the dictionary yet, so the line should still be @@ -51,7 +51,7 @@ public class BlueUnderlineTests extends InputTestsBase { assertEquals("extend blue underline, span start", EXPECTED_SPAN_START, spanBefore.mStart); assertEquals("extend blue underline, span end", EXPECTED_SPAN_END, spanBefore.mEnd); assertTrue("extend blue underline, span color", spanBefore.isAutoCorrectionIndicator()); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); // Now we have been able to re-evaluate the word, there shouldn't be an auto-correction span final SpanGetter spanAfter = new SpanGetter(mEditText.getText(), SuggestionSpan.class); @@ -65,18 +65,18 @@ public class BlueUnderlineTests extends InputTestsBase { final int EXPECTED_UNDERLINE_SPAN_START = 0; final int EXPECTED_UNDERLINE_SPAN_END = 3; type(STRING_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); type(Constants.CODE_SPACE); // typedLength + 1 because we also typed a space mLatinIME.onUpdateSelection(0, 0, typedLength + 1, typedLength + 1, -1, -1); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); type(Constants.CODE_DELETE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); type(Constants.CODE_DELETE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); final SpanGetter suggestionSpan = new SpanGetter(mEditText.getText(), SuggestionSpan.class); assertFalse("show no blue underline after backspace, span should not be the auto-" @@ -93,7 +93,7 @@ public class BlueUnderlineTests extends InputTestsBase { final int typedLength = STRING_TO_TYPE.length(); final int NEW_CURSOR_POSITION = 0; type(STRING_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); // Simulate the onUpdateSelection() event mLatinIME.onUpdateSelection(0, 0, typedLength, typedLength, -1, -1); runMessages(); @@ -103,7 +103,7 @@ public class BlueUnderlineTests extends InputTestsBase { mInputConnection.setSelection(NEW_CURSOR_POSITION, NEW_CURSOR_POSITION); mLatinIME.onUpdateSelection(typedLength, typedLength, NEW_CURSOR_POSITION, NEW_CURSOR_POSITION, -1, -1); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); final SpanGetter span = new SpanGetter(mEditText.getText(), SuggestionSpan.class); assertFalse("blue underline removed when cursor is moved", @@ -113,7 +113,7 @@ public class BlueUnderlineTests extends InputTestsBase { public void testComposingStopsOnSpace() { final String STRING_TO_TYPE = "this "; type(STRING_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); // Simulate the onUpdateSelection() event mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1); runMessages(); diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTests.java b/tests/src/com/android/inputmethod/latin/InputLogicTests.java index ec249dab3..99dc9a204 100644 --- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java +++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java @@ -16,6 +16,7 @@ package com.android.inputmethod.latin; +import android.test.MoreAsserts; import android.test.suitebuilder.annotation.LargeTest; import android.text.TextUtils; import android.view.inputmethod.BaseInputConnection; @@ -487,7 +488,7 @@ public class InputLogicTests extends InputTestsBase { public void testPredictionsAfterSpace() { final String WORD_TO_TYPE = "Barack "; type(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); // Test the first prediction is displayed final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); @@ -499,17 +500,17 @@ public class InputLogicTests extends InputTestsBase { mLatinIME.clearPersonalizedDictionariesForTest(); final String WORD_TO_TYPE = "Barack "; type(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); // No need to test here, testPredictionsAfterSpace is testing it already type(" "); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); // Test the predictions have been cleared SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); assertEquals("predictions cleared after double-space-to-period", suggestedWords.size(), 0); type(Constants.CODE_DELETE); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); // Test the first prediction is displayed suggestedWords = mLatinIME.getSuggestedWordsForTest(); @@ -522,7 +523,7 @@ public class InputLogicTests extends InputTestsBase { type(WORD_TO_TYPE); // Choose the auto-correction. For "Barack", the auto-correction should be "Barack". pickSuggestionManually(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); // Test the first prediction is displayed final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); @@ -534,13 +535,13 @@ public class InputLogicTests extends InputTestsBase { mLatinIME.clearPersonalizedDictionariesForTest(); final String WORD_TO_TYPE = "Barack. "; type(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); assertEquals("No prediction after period after inputting once.", 0, suggestedWords.size()); type(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); suggestedWords = mLatinIME.getSuggestedWordsForTest(); assertEquals("Beginning-of-Sentence prediction after inputting 2 times.", "Barack", @@ -565,18 +566,18 @@ public class InputLogicTests extends InputTestsBase { type(" "); mLatinIME.onUpdateSelection(endOfSuggestion, endOfSuggestion, endOfSuggestion + 1, endOfSuggestion + 1, -1, -1); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); // Simulate a manual cursor move mInputConnection.setSelection(indexForManualCursor, indexForManualCursor); mLatinIME.onUpdateSelection(endOfSuggestion + 1, endOfSuggestion + 1, indexForManualCursor, indexForManualCursor, -1, -1); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); pickSuggestionManually(WORD_TO_TYPE); mLatinIME.onUpdateSelection(indexForManualCursor, indexForManualCursor, endOfWord, endOfWord, -1, -1); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); // Test the first prediction is displayed final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); @@ -624,7 +625,7 @@ public class InputLogicTests extends InputTestsBase { for (int i = 0; i < WORD_TO_TYPE.length(); ++i) { type(WORD_TO_TYPE.substring(i, i+1)); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); } assertEquals("type many trailing single quotes one by one", EXPECTED_RESULT, @@ -636,7 +637,7 @@ public class InputLogicTests extends InputTestsBase { final String EXPECTED_RESULT = WORD_TO_TYPE; for (int i = 0; i < WORD_TO_TYPE.length(); ++i) { type(WORD_TO_TYPE.substring(i, i+1)); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); } assertEquals("type words letter by letter", EXPECTED_RESULT, @@ -652,10 +653,30 @@ public class InputLogicTests extends InputTestsBase { changeLanguage("fr"); runMessages(); type(WORD_TO_TYPE_SECOND_PART); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); assertEquals("Suggestions updated after switching languages", EXPECTED_RESULT, suggestedWords.size() > 0 ? suggestedWords.getWord(1) : null); } + + public void testBasicGesture() { + gesture("this"); + assertEquals("gesture \"this\"", "this", mEditText.getText().toString()); + } + + public void testGestureGesture() { + gesture("this"); + gesture("is"); + assertEquals("gesture \"this is\"", "this is", mEditText.getText().toString()); + } + + public void testGestureBackspaceGestureAgain() { + gesture("this"); + type(Constants.CODE_DELETE); + assertEquals("gesture then backspace", "", mEditText.getText().toString()); + gesture("this"); + MoreAsserts.assertNotEqual("gesture twice the same thing", "this", + mEditText.getText().toString()); + } } diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTestsLanguageWithoutSpaces.java b/tests/src/com/android/inputmethod/latin/InputLogicTestsLanguageWithoutSpaces.java index 2560407dc..c16372ab5 100644 --- a/tests/src/com/android/inputmethod/latin/InputLogicTestsLanguageWithoutSpaces.java +++ b/tests/src/com/android/inputmethod/latin/InputLogicTestsLanguageWithoutSpaces.java @@ -74,7 +74,7 @@ public class InputLogicTestsLanguageWithoutSpaces extends InputTestsBase { mInputConnection.setSelection(CURSOR_POS, CURSOR_POS); mLatinIME.onUpdateSelection(typedLength, typedLength, CURSOR_POS, CURSOR_POS, -1, -1); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); assertEquals("start composing inside text", -1, BaseInputConnection.getComposingSpanStart(mEditText.getText())); @@ -91,7 +91,7 @@ public class InputLogicTestsLanguageWithoutSpaces extends InputTestsBase { final String WORD_TO_TYPE = "Barack "; changeKeyboardLocaleAndDictLocale("th", "en_US"); type(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); // Make sure there is no space assertEquals("predictions in lang without spaces", "Barack", diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTestsNonEnglish.java b/tests/src/com/android/inputmethod/latin/InputLogicTestsNonEnglish.java index 715d449a0..842b54fe1 100644 --- a/tests/src/com/android/inputmethod/latin/InputLogicTestsNonEnglish.java +++ b/tests/src/com/android/inputmethod/latin/InputLogicTestsNonEnglish.java @@ -70,7 +70,7 @@ public class InputLogicTestsNonEnglish extends InputTestsBase { try { changeLanguage("fr"); type(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); assertTrue("type word then type space should display punctuation strip", mLatinIME.getSuggestedWordsForTest().isPunctuationSuggestions()); @@ -95,7 +95,7 @@ public class InputLogicTestsNonEnglish extends InputTestsBase { try { changeLanguage("fr"); type(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest(); assertEquals("type word then type space yields predictions for French", diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java index ee7942450..dd900a22c 100644 --- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java +++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java @@ -18,6 +18,7 @@ package com.android.inputmethod.latin; import android.content.Context; import android.content.SharedPreferences; +import android.graphics.Point; import android.os.Looper; import android.preference.PreferenceManager; import android.test.ServiceTestCase; @@ -45,6 +46,7 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.settings.DebugSettings; import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.utils.LocaleUtils; +import com.android.inputmethod.latin.utils.StringUtils; import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import java.util.Locale; @@ -58,9 +60,11 @@ public class InputTestsBase extends ServiceTestCase { private static final String DEFAULT_AUTO_CORRECTION_THRESHOLD = "1"; // The message that sets the underline is posted with a 500 ms delay - protected static final int DELAY_TO_WAIT_FOR_UNDERLINE = 500; + protected static final int DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS = 500; // The message that sets predictions is posted with a 200 ms delay - protected static final int DELAY_TO_WAIT_FOR_PREDICTIONS = 200; + protected static final int DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS = 200; + // We wait for gesture computation for this delay + protected static final int DELAY_TO_WAIT_FOR_GESTURE_MILLIS = 200; private final int TIMEOUT_TO_WAIT_FOR_LOADING_MAIN_DICTIONARY_IN_SECONDS = 60; // Type for a test phony dictionary @@ -217,7 +221,7 @@ public class InputTestsBase extends ServiceTestCase { // Run messages to avoid the messages enqueued by startInputView() and its friends // to run on a later call and ruin things. We need to wait first because some of them // can be posted with a delay (notably, MSG_RESUME_SUGGESTIONS) - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); } @@ -301,6 +305,47 @@ public class InputTestsBase extends ServiceTestCase { } } + protected Point getXY(final int codePoint) { + final Key key = mKeyboard.getKey(codePoint); + if (key == null) { + throw new RuntimeException("Code point not on the keyboard"); + } else { + return new Point(key.getX() + key.getWidth() / 2, key.getY() + key.getHeight() / 2); + } + } + + protected void gesture(final String stringToGesture) { + if (StringUtils.codePointCount(stringToGesture) < 2) { + throw new RuntimeException("Can't gesture strings less than 2 chars long"); + } + + mLatinIME.onStartBatchInput(); + final int startCodePoint = stringToGesture.codePointAt(0); + Point oldPoint = getXY(startCodePoint); + int timestamp = 0; // In milliseconds since the start of the gesture + final InputPointers pointers = new InputPointers(Constants.DEFAULT_GESTURE_POINTS_CAPACITY); + pointers.addPointer(oldPoint.x, oldPoint.y, 0 /* pointerId */, timestamp); + + for (int i = Character.charCount(startCodePoint); i < stringToGesture.length(); + i = stringToGesture.offsetByCodePoints(i, 1)) { + final Point newPoint = getXY(stringToGesture.codePointAt(i)); + // Arbitrarily 0.5s between letters and 0.1 between events. Refine this later if needed. + final int STEPS = 5; + for (int j = 0; j < STEPS; ++j) { + timestamp += 100; + pointers.addPointer(oldPoint.x + ((newPoint.x - oldPoint.x) * j) / STEPS, + oldPoint.y + ((newPoint.y - oldPoint.y) * j) / STEPS, + 0 /* pointerId */, timestamp); + } + oldPoint.x = newPoint.x; + oldPoint.y = newPoint.y; + mLatinIME.onUpdateBatchInput(pointers); + } + mLatinIME.onEndBatchInput(pointers); + sleep(DELAY_TO_WAIT_FOR_GESTURE_MILLIS); + runMessages(); + } + protected void waitForDictionariesToBeLoaded() { try { mLatinIME.waitForLoadingDictionaries( diff --git a/tests/src/com/android/inputmethod/latin/PunctuationTests.java b/tests/src/com/android/inputmethod/latin/PunctuationTests.java index 64750fbda..3537918de 100644 --- a/tests/src/com/android/inputmethod/latin/PunctuationTests.java +++ b/tests/src/com/android/inputmethod/latin/PunctuationTests.java @@ -38,7 +38,7 @@ public class PunctuationTests extends InputTestsBase { try { mLatinIME.loadSettings(); type(WORD_TO_TYPE); - sleep(DELAY_TO_WAIT_FOR_UNDERLINE); + sleep(DELAY_TO_WAIT_FOR_UNDERLINE_MILLIS); runMessages(); assertTrue("type word then type space should display punctuation strip", mLatinIME.getSuggestedWordsForTest().isPunctuationSuggestions()); diff --git a/tests/src/com/android/inputmethod/latin/ShiftModeTests.java b/tests/src/com/android/inputmethod/latin/ShiftModeTests.java index db3c9baa9..8ba0174b5 100644 --- a/tests/src/com/android/inputmethod/latin/ShiftModeTests.java +++ b/tests/src/com/android/inputmethod/latin/ShiftModeTests.java @@ -75,7 +75,7 @@ public class ShiftModeTests extends InputTestsBase { repeatKey(Constants.CODE_DELETE); } assertFalse("Caps immediately after repeating Backspace a lot", isCapsModeAutoShifted()); - sleep(DELAY_TO_WAIT_FOR_PREDICTIONS); + sleep(DELAY_TO_WAIT_FOR_PREDICTIONS_MILLIS); runMessages(); assertTrue("Caps after a while after repeating Backspace a lot", isCapsModeAutoShifted()); }