Merge "Remove a high surrogate after a delete if any" into jb-dev
diff --git a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
index 81f744d..a9947c1 100644
--- a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
+++ b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
@@ -18,6 +18,9 @@
 
 import com.android.inputmethod.keyboard.Keyboard;
 
+import android.text.style.SuggestionSpan;
+import android.text.style.UnderlineSpan;
+
 public class BlueUnderlineTests extends InputTestsBase {
 
     public void testBlueUnderline() {
@@ -27,7 +30,7 @@
         type(STRING_TO_TYPE);
         sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
         runMessages();
-        final Span span = new Span(mTextView.getText());
+        final SpanGetter span = new SpanGetter(mTextView.getText(), SuggestionSpan.class);
         assertEquals("show blue underline, span start", EXPECTED_SPAN_START, span.mStart);
         assertEquals("show blue underline, span end", EXPECTED_SPAN_END, span.mEnd);
         assertEquals("show blue underline, span color", true, span.isAutoCorrectionIndicator());
@@ -44,7 +47,7 @@
         type(STRING_2_TO_TYPE);
         // We haven't have time to look into the dictionary yet, so the line should still be
         // blue to avoid any flicker.
-        final Span spanBefore = new Span(mTextView.getText());
+        final SpanGetter spanBefore = new SpanGetter(mTextView.getText(), SuggestionSpan.class);
         assertEquals("extend blue underline, span start", EXPECTED_SPAN_START, spanBefore.mStart);
         assertEquals("extend blue underline, span end", EXPECTED_SPAN_END, spanBefore.mEnd);
         assertEquals("extend blue underline, span color", true,
@@ -52,14 +55,15 @@
         sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
         runMessages();
         // Now we have been able to re-evaluate the word, there shouldn't be an auto-correction span
-        final Span spanAfter = new Span(mTextView.getText());
+        final SpanGetter spanAfter = new SpanGetter(mTextView.getText(), SuggestionSpan.class);
         assertNull("hide blue underline", spanAfter.mSpan);
     }
 
     public void testBlueUnderlineOnBackspace() {
         final String STRING_TO_TYPE = "tgis";
-        final int EXPECTED_SPAN_START = 0;
-        final int EXPECTED_SPAN_END = 4;
+        final int EXPECTED_SUGGESTION_SPAN_START = -1;
+        final int EXPECTED_UNDERLINE_SPAN_START = 0;
+        final int EXPECTED_UNDERLINE_SPAN_END = 4;
         type(STRING_TO_TYPE);
         sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
         runMessages();
@@ -72,13 +76,14 @@
         type(Keyboard.CODE_DELETE);
         sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
         runMessages();
-        final Span span = new Span(mTextView.getText());
-        assertEquals("show blue underline after backspace, span start",
-                EXPECTED_SPAN_START, span.mStart);
-        assertEquals("show blue underline after backspace, span end",
-                EXPECTED_SPAN_END, span.mEnd);
-        assertEquals("show blue underline after backspace, span color", true,
-                span.isAutoCorrectionIndicator());
+        final SpanGetter suggestionSpan = new SpanGetter(mTextView.getText(), SuggestionSpan.class);
+        assertEquals("show no blue underline after backspace, span start should be -1",
+                EXPECTED_SUGGESTION_SPAN_START, suggestionSpan.mStart);
+        final SpanGetter underlineSpan = new SpanGetter(mTextView.getText(), UnderlineSpan.class);
+        assertEquals("should be composing, so should have an underline span",
+                EXPECTED_UNDERLINE_SPAN_START, underlineSpan.mStart);
+        assertEquals("should be composing, so should have an underline span",
+                EXPECTED_UNDERLINE_SPAN_END, underlineSpan.mEnd);
     }
 
     public void testBlueUnderlineDisappearsWhenCursorMoved() {
@@ -96,7 +101,7 @@
         mLatinIME.onUpdateSelection(0, 0, NEW_CURSOR_POSITION, NEW_CURSOR_POSITION, -1, -1);
         sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
         runMessages();
-        final Span span = new Span(mTextView.getText());
+        final SpanGetter span = new SpanGetter(mTextView.getText(), SuggestionSpan.class);
         assertNull("blue underline removed when cursor is moved", span.mSpan);
     }
 }
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTests.java b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
index 6c3cb16..f1ccfdd 100644
--- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java
+++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
@@ -28,7 +28,7 @@
 
     public void testPickSuggestionThenBackspace() {
         final String WORD_TO_TYPE = "this";
-        final String EXPECTED_RESULT = "this";
+        final String EXPECTED_RESULT = "thi";
         type(WORD_TO_TYPE);
         pickSuggestionManually(0, WORD_TO_TYPE);
         mLatinIME.onUpdateSelection(0, 0, WORD_TO_TYPE.length(), WORD_TO_TYPE.length(), -1, -1);
@@ -40,7 +40,7 @@
     public void testPickAutoCorrectionThenBackspace() {
         final String WORD_TO_TYPE = "tgis";
         final String WORD_TO_PICK = "this";
-        final String EXPECTED_RESULT = "tgis";
+        final String EXPECTED_RESULT = "thi";
         type(WORD_TO_TYPE);
         // Choose the auto-correction, which is always in position 0. For "tgis", the
         // auto-correction should be "this".
@@ -55,7 +55,7 @@
 
     public void testPickTypedWordOverAutoCorrectionThenBackspace() {
         final String WORD_TO_TYPE = "tgis";
-        final String EXPECTED_RESULT = "tgis";
+        final String EXPECTED_RESULT = "tgi";
         type(WORD_TO_TYPE);
         // Choose the typed word, which should be in position 1 (because position 0 should
         // be occupied by the "this" auto-correction, as checked by testAutoCorrect())
@@ -71,7 +71,7 @@
     public void testPickDifferentSuggestionThenBackspace() {
         final String WORD_TO_TYPE = "tgis";
         final String WORD_TO_PICK = "thus";
-        final String EXPECTED_RESULT = "tgis";
+        final String EXPECTED_RESULT = "thu";
         type(WORD_TO_TYPE);
         // Choose the second suggestion, which should be in position 2 and should be "thus"
         // when "tgis is typed.
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
index c73a931..eb47fd5 100644
--- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -24,6 +24,7 @@
 import android.test.ServiceTestCase;
 import android.text.InputType;
 import android.text.SpannableStringBuilder;
+import android.text.style.CharacterStyle;
 import android.text.style.SuggestionSpan;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -57,18 +58,19 @@
             new HashMap<String, InputMethodSubtype>();
 
     // A helper class to ease span tests
-    public static class Span {
+    public static class SpanGetter {
         final SpannableStringBuilder mInputText;
-        final SuggestionSpan mSpan;
+        final CharacterStyle mSpan;
         final int mStart;
         final int mEnd;
         // The supplied CharSequence should be an instance of SpannableStringBuilder,
-        // and it should contain exactly zero or one SuggestionSpan. Otherwise, an exception
+        // and it should contain exactly zero or one span. Otherwise, an exception
         // is thrown.
-        public Span(final CharSequence inputText) {
+        public SpanGetter(final CharSequence inputText,
+                final Class<? extends CharacterStyle> spanType) {
             mInputText = (SpannableStringBuilder)inputText;
-            final SuggestionSpan[] spans =
-                    mInputText.getSpans(0, mInputText.length(), SuggestionSpan.class);
+            final CharacterStyle[] spans =
+                    mInputText.getSpans(0, mInputText.length(), spanType);
             if (0 == spans.length) {
                 mSpan = null;
                 mStart = -1;
@@ -78,11 +80,12 @@
                 mStart = mInputText.getSpanStart(mSpan);
                 mEnd = mInputText.getSpanEnd(mSpan);
             } else {
-                throw new RuntimeException("Expected one SuggestionSpan, found " + spans.length);
+                throw new RuntimeException("Expected one span, found " + spans.length);
             }
         }
         public boolean isAutoCorrectionIndicator() {
-            return 0 != (SuggestionSpan.FLAG_AUTO_CORRECTION & mSpan.getFlags());
+            return (mSpan instanceof SuggestionSpan) &&
+                    0 != (SuggestionSpan.FLAG_AUTO_CORRECTION & ((SuggestionSpan)mSpan).getFlags());
         }
     }