Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1137)

Unified Diff: content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionTest.java

Issue 1278593004: Introduce ThreadedInputConnection behind a switch (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: removed ImeTest#testDoesNotHang_rendererCrashes which does not test anything Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionTest.java
diff --git a/content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionTest.java b/content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8e7890913b9d78193209aa1526d10d52d3f9f90
--- /dev/null
+++ b/content/public/android/junit/src/org/chromium/content/browser/input/ThreadedInputConnectionTest.java
@@ -0,0 +1,162 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.input;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.when;
+
+import android.os.Handler;
+
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.Feature;
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+/**
+ * Unit tests for {@ThreadedInputConnection}.
+ */
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class ThreadedInputConnectionTest {
+ @Mock ImeAdapter mImeAdapter;
+
+ ThreadedInputConnection mConnection;
+ InOrder mInOrder;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ mImeAdapter = Mockito.mock(ImeAdapter.class);
+ mInOrder = inOrder(mImeAdapter);
+ // Let's create Handler for test thread and pretend that it is running on IME thread.
+ mConnection = new ThreadedInputConnection(mImeAdapter, new Handler());
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ public void testComposeGetTextFinishGetText() {
+ // IME app calls setComposingText().
+ mConnection.setComposingText("hello", 1);
+ mInOrder.verify(mImeAdapter).sendCompositionToNative("hello", 1, false);
+
+ // Renderer updates states asynchronously.
+ mConnection.updateStateOnUiThread("hello", 5, 5, 0, 5, true, true);
+ mInOrder.verify(mImeAdapter).updateSelection(5, 5, 0, 5);
+ assertEquals(0, mConnection.getQueueForTest().size());
+
+ // Prepare to call requestTextInputStateUpdate.
+ mConnection.updateStateOnUiThread("hello", 5, 5, 0, 5, true, false);
+ assertEquals(1, mConnection.getQueueForTest().size());
+ when(mImeAdapter.requestTextInputStateUpdate()).thenReturn(true);
+
+ // IME app calls getTextBeforeCursor().
+ assertEquals("hello", mConnection.getTextBeforeCursor(20, 0));
+
+ // IME app calls finishComposingText().
+ mConnection.finishComposingText();
+ mInOrder.verify(mImeAdapter).finishComposingText();
+ mConnection.updateStateOnUiThread("hello", 5, 5, -1, -1, true, true);
+ mInOrder.verify(mImeAdapter).updateSelection(5, 5, -1, -1);
+
+ // Prepare to call requestTextInputStateUpdate.
+ mConnection.updateStateOnUiThread("hello", 5, 5, -1, -1, true, false);
+ assertEquals(1, mConnection.getQueueForTest().size());
+ when(mImeAdapter.requestTextInputStateUpdate()).thenReturn(true);
+
+ // IME app calls getTextBeforeCursor().
+ assertEquals("hello", mConnection.getTextBeforeCursor(20, 0));
+
+ assertEquals(0, mConnection.getQueueForTest().size());
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ public void testRenderChangeUpdatesSelection() {
+ // User moves the cursor.
+ mConnection.updateStateOnUiThread("hello", 4, 4, -1, -1, true, true);
+ mInOrder.verify(mImeAdapter).updateSelection(4, 4, -1, -1);
+ assertEquals(0, mConnection.getQueueForTest().size());
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ public void testBatchEdit() {
+ // IME app calls beginBatchEdit().
+ assertTrue(mConnection.beginBatchEdit());
+ // Type hello real fast.
+ mConnection.commitText("hello", 1);
+ mInOrder.verify(mImeAdapter).sendCompositionToNative("hello", 1, true);
+
+ // Renderer updates states asynchronously.
+ mConnection.updateStateOnUiThread("hello", 5, 5, -1, -1, true, true);
+ mInOrder.verify(mImeAdapter, never()).updateSelection(5, 5, -1, -1);
+ assertEquals(0, mConnection.getQueueForTest().size());
+
+ {
+ // Nest another batch edit.
+ assertTrue(mConnection.beginBatchEdit());
+ // Move the cursor to the left.
+ mConnection.setSelection(4, 4);
+ assertTrue(mConnection.endBatchEdit());
+ }
+ // We still have one outer batch edit, so should not update selection yet.
+ mInOrder.verify(mImeAdapter, never()).updateSelection(4, 4, -1, -1);
+
+ // Prepare to call requestTextInputStateUpdate.
+ mConnection.updateStateOnUiThread("hello", 4, 4, -1, -1, true, false);
+ assertEquals(1, mConnection.getQueueForTest().size());
+ when(mImeAdapter.requestTextInputStateUpdate()).thenReturn(true);
+
+ // IME app calls endBatchEdit().
+ assertFalse(mConnection.endBatchEdit());
+ // Batch edit is finished, now update selection.
+ mInOrder.verify(mImeAdapter).updateSelection(4, 4, -1, -1);
+ assertEquals(0, mConnection.getQueueForTest().size());
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ public void testFailToRequestToRenderer() {
+ when(mImeAdapter.requestTextInputStateUpdate()).thenReturn(false);
+ // Should not hang here. Return null to indicate failure.
+ assertNull(null, mConnection.getTextBeforeCursor(10, 0));
+ }
+
+ @Test
+ @Feature({"TextInput"})
+ public void testRendererCannotUpdateState() {
+ when(mImeAdapter.requestTextInputStateUpdate()).thenReturn(true);
+ // We found that renderer cannot update state, e.g., due to a crash.
+ ThreadUtils.postOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ // TODO(changwan): find a way to avoid this.
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ fail();
+ }
+ mConnection.unblockOnUiThread();
+ }
+ });
+ // Should not hang here. Return null to indicate failure.
+ assertEquals(null, mConnection.getTextBeforeCursor(10, 0));
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698