blob: 1d6c10979c5973a91944a9fb7c27b10cfa0ace99 [file] [log] [blame]
/*
* Copyright (C) 2008 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 android.text.method.cts;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.ToBeFixed;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.text.Editable;
import android.text.Selection;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.method.ArrowKeyMovementMethod;
import android.text.method.MetaKeyKeyListener;
import android.text.method.MovementMethod;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import android.widget.TextView.BufferType;
/**
* Test {@link ArrowKeyMovementMethod}. The class is an implementation of interface
* {@link MovementMethod}. The typical usage of {@link MovementMethod} is tested in
* {@link android.widget.cts.TextViewTest} and this test case is only focused on the
* implementation of the methods.
*
* @see android.widget.cts.TextViewTest
*/
@TestTargetClass(ArrowKeyMovementMethod.class)
public class ArrowKeyMovementMethodTest extends ActivityInstrumentationTestCase2<StubActivity> {
private static final String THREE_LINES_TEXT = "first line\nsecond line\nlast line";
private static final int END_OF_ALL_TEXT = THREE_LINES_TEXT.length();
private static final int END_OF_1ST_LINE = THREE_LINES_TEXT.indexOf('\n');
private static final int START_OF_2ND_LINE = END_OF_1ST_LINE + 1;
private static final int END_OF_2ND_LINE = THREE_LINES_TEXT.indexOf('\n', START_OF_2ND_LINE);
private static final int START_OF_3RD_LINE = END_OF_2ND_LINE + 1;
private static final int SPACE_IN_2ND_LINE = THREE_LINES_TEXT.indexOf(' ', START_OF_2ND_LINE);
private TextView mTextView;
private ArrowKeyMovementMethod mArrowKeyMovementMethod;
private Editable mEditable;
private MyMetaKeyKeyListener mMetaListener;
public ArrowKeyMovementMethodTest() {
super("com.android.cts.stub", StubActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
mMetaListener = new MyMetaKeyKeyListener();
mArrowKeyMovementMethod = new ArrowKeyMovementMethod();
initTextViewWithNullLayout();
mEditable = (Editable) mTextView.getText();
getInstrumentation().runOnMainSync(new Runnable() {
public void run() {
getActivity().setContentView(mTextView);
mTextView.setFocusable(true);
mTextView.requestFocus();
}
});
getInstrumentation().waitForIdleSync();
assertNotNull(mTextView.getLayout());
assertTrue(mTextView.isFocused());
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test constructor ArrowKeyMovementMethod#ArrowKeyMovementMethod().",
method = "ArrowKeyMovementMethod",
args = {}
)
public void testConstructor() {
new ArrowKeyMovementMethod();
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#canSelectArbitrarily()}. "
+ "It always returns true.",
method = "canSelectArbitrarily",
args = {}
)
public void testCanSelectArbitrarily() {
assertTrue(new ArrowKeyMovementMethod().canSelectArbitrarily());
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#getInstance()}. "
+ "This is a method for creating singleton.",
method = "getInstance",
args = {}
)
public void testGetInstance() {
MovementMethod method0 = ArrowKeyMovementMethod.getInstance();
assertNotNull(method0);
MovementMethod method1 = ArrowKeyMovementMethod.getInstance();
assertNotNull(method1);
assertSame(method0, method1);
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onTakeFocus(TextView, Spannable, int)}. "
+ "Test the method after the widget get layouted.",
method = "onTakeFocus",
args = {TextView.class, Spannable.class, int.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. There is no "
+ "document about the behaviour of this method.")
public void testOnTakeFocus() throws Throwable {
/*
* The following assertions depend on whether the TextView has a layout.
* The text view will not get layout in setContent method but in other
* handler's function. Assertion which is following the setContent will
* not get the expecting result. It have to wait all the handlers'
* operations on the UiTread to finish. So all these cases are divided
* into several steps, setting the content at first, waiting the layout,
* and checking the assertion at last.
*/
assertSelection(-1);
runTestOnUiThread(new Runnable() {
public void run() {
Selection.removeSelection(mEditable);
mArrowKeyMovementMethod.onTakeFocus(mTextView, mEditable, View.FOCUS_UP);
}
});
getInstrumentation().waitForIdleSync();
assertSelection(END_OF_ALL_TEXT);
runTestOnUiThread(new Runnable() {
public void run() {
Selection.removeSelection(mEditable);
mArrowKeyMovementMethod.onTakeFocus(mTextView, mEditable, View.FOCUS_LEFT);
}
});
getInstrumentation().waitForIdleSync();
assertSelection(END_OF_ALL_TEXT);
runTestOnUiThread(new Runnable() {
public void run() {
mTextView.setSingleLine();
}
});
// wait until the textView gets layout
getInstrumentation().waitForIdleSync();
assertNotNull(mTextView.getLayout());
assertEquals(1, mTextView.getLayout().getLineCount());
runTestOnUiThread(new Runnable() {
public void run() {
Selection.removeSelection(mEditable);
mArrowKeyMovementMethod.onTakeFocus(mTextView, mEditable, View.FOCUS_UP);
}
});
assertSelection(END_OF_ALL_TEXT);
runTestOnUiThread(new Runnable() {
public void run() {
Selection.removeSelection(mEditable);
mArrowKeyMovementMethod.onTakeFocus(mTextView, mEditable, View.FOCUS_LEFT);
}
});
assertSelection(END_OF_ALL_TEXT);
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onTakeFocus(TextView, Spannable, int)}. "
+ "Test the method before the widget get layouted.",
method = "onTakeFocus",
args = {TextView.class, Spannable.class, int.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. There is no "
+ "document about the behaviour of this method.")
public void testOnTakeFoucusWithNullLayout() {
initTextViewWithNullLayout();
mEditable = (Editable) mTextView.getText();
assertSelectEndOfContent();
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onTakeFocus(TextView, Spannable, int)}. "
+ "Test the method with null parameters.",
method = "onTakeFocus",
args = {TextView.class, Spannable.class, int.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. @throws clause "
+ "should be added into javadoc of ArrowKeyMovementMethod#onTakeFocus(TextView, "
+ "Spannable, int)} when the params view or text is null")
public void testOnTakeFocusWithNullParameters() {
initTextViewWithNullLayout();
mEditable = (Editable) mTextView.getText();
try {
mArrowKeyMovementMethod.onTakeFocus(null, mEditable, View.FOCUS_DOWN);
fail("The method did not throw NullPointerException when param textView is null.");
} catch (NullPointerException e) {
// expected
}
try {
mArrowKeyMovementMethod.onTakeFocus(mTextView, null, View.FOCUS_DOWN);
fail("The method did not throw NullPointerException when param spannable is null.");
} catch (NullPointerException e) {
// expected
}
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onKeyDown(TextView, Spannable, int, "
+ "KeyEvent)}. KeyEvent parameter is never read.",
method = "onKeyDown",
args = {TextView.class, Spannable.class, int.class, KeyEvent.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. There is no "
+ "document about the behaviour of this method.")
@UiThreadTest
public void testOnKeyDownWithKeyCodeUp() {
// first line
// second |line
// last line
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
pressBothShiftAlt();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_UP, null));
// |first line
// second |line
// last line
assertSelection(SPACE_IN_2ND_LINE, 0);
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
pressShift();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_UP, null));
// first lin|e
// second |line
// last line
assertEquals(SPACE_IN_2ND_LINE, Selection.getSelectionStart(mEditable));
int correspondingIn1stLine = Selection.getSelectionEnd(mEditable);
assertTrue(correspondingIn1stLine >= 0);
assertTrue(correspondingIn1stLine <= END_OF_1ST_LINE);
pressShift();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_UP, null));
// |first line
// second |line
// last line
assertSelection(SPACE_IN_2ND_LINE, 0);
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
pressAlt();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_UP, null));
// |first line
// second line
// last line
assertSelection(0);
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
MetaKeyKeyListener.resetMetaState(mEditable);
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_UP, null));
// first lin|e
// second line
// last line
assertSelection(correspondingIn1stLine);
assertFalse(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_UP, null));
// first lin|e
// second line
// last line
assertSelection(correspondingIn1stLine);
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onKeyDown(TextView, Spannable, int, "
+ "KeyEvent)}. KeyEvent parameter is never read.",
method = "onKeyDown",
args = {TextView.class, Spannable.class, int.class, KeyEvent.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. There is no "
+ "document about the behaviour of this method.")
@UiThreadTest
public void testOnKeyDownWithKeyCodeDown() {
// first line
// second |line
// last line
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
pressBothShiftAlt();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_DOWN, null));
// first line
// second |line
// last line|
assertSelection(SPACE_IN_2ND_LINE, END_OF_ALL_TEXT);
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
pressShift();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_DOWN, null));
// first line
// second |line
// last lin|e
assertEquals(SPACE_IN_2ND_LINE, Selection.getSelectionStart(mEditable));
int correspondingIn3rdLine = Selection.getSelectionEnd(mEditable);
assertTrue(correspondingIn3rdLine >= START_OF_3RD_LINE);
assertTrue(correspondingIn3rdLine <= END_OF_ALL_TEXT);
pressShift();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_DOWN, null));
// first line
// second |line
// last line|
assertSelection(SPACE_IN_2ND_LINE, END_OF_ALL_TEXT);
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
pressAlt();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_DOWN, null));
// first line
// second line
// last line|
assertSelection(END_OF_ALL_TEXT);
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
MetaKeyKeyListener.resetMetaState(mEditable);
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_DOWN, null));
// first line
// second line
// last lin|e
assertSelection(correspondingIn3rdLine);
assertFalse(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_DOWN, null));
// first line
// second line
// last lin|e
assertSelection(correspondingIn3rdLine);
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onKeyDown(TextView, Spannable, int, "
+ "KeyEvent)}. KeyEvent parameter is never read.",
method = "onKeyDown",
args = {TextView.class, Spannable.class, int.class, KeyEvent.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. There is no "
+ "document about the behaviour of this method.")
@UiThreadTest
public void testOnKeyDownWithKeyCodeLeft() {
// first line
// second |line
// last line
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
pressBothShiftAlt();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_LEFT, null));
// first line
// |second |line
// last line
assertSelection(SPACE_IN_2ND_LINE, START_OF_2ND_LINE);
pressBothShiftAlt();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_LEFT, null));
// first line
// |second |line
// last line
assertSelection(SPACE_IN_2ND_LINE, START_OF_2ND_LINE);
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
pressShift();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_LEFT, null));
// first line
// second| |line
// last line
assertSelection(SPACE_IN_2ND_LINE, SPACE_IN_2ND_LINE - 1);
pressShift();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_LEFT, null));
// first line
// secon|d |line
// last line
assertSelection(SPACE_IN_2ND_LINE, SPACE_IN_2ND_LINE - 2);
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
pressAlt();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_LEFT, null));
// first line
// |second line
// last line
assertSelection(START_OF_2ND_LINE);
pressAlt();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_LEFT, null));
// first line
// |second line
// last line
assertSelection(START_OF_2ND_LINE);
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
MetaKeyKeyListener.resetMetaState(mEditable);
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_LEFT, null));
// first line
// second| line
// last line
assertSelection(SPACE_IN_2ND_LINE - 1);
Selection.setSelection(mEditable, START_OF_2ND_LINE);
// first line
// |second line
// last line
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_LEFT, null));
// first line|
// second line
// last line
assertSelection(END_OF_1ST_LINE);
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onKeyDown(TextView, Spannable, int, "
+ "KeyEvent)}. KeyEvent parameter is never read.",
method = "onKeyDown",
args = {TextView.class, Spannable.class, int.class, KeyEvent.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. There is no "
+ "document about the behaviour of this method.")
@UiThreadTest
public void testOnKeyDownWithKeyCodeRight() {
// first line
// second |line
// last line
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
pressBothShiftAlt();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_RIGHT, null));
// first line
// second |line|
// last line
assertSelection(SPACE_IN_2ND_LINE, END_OF_2ND_LINE);
pressBothShiftAlt();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_RIGHT, null));
// first line
// second |line|
// last line
assertSelection(SPACE_IN_2ND_LINE, END_OF_2ND_LINE);
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
pressShift();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_RIGHT, null));
// first line
// second |l|ine
// last line
assertSelection(SPACE_IN_2ND_LINE, SPACE_IN_2ND_LINE + 1);
pressShift();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_RIGHT, null));
// first line
// second |li|ne
// last line
assertSelection(SPACE_IN_2ND_LINE, SPACE_IN_2ND_LINE + 2);
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
pressAlt();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_RIGHT, null));
// first line
// second line|
// last line
assertSelection(END_OF_2ND_LINE);
pressAlt();
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_RIGHT, null));
// first line
// second line|
// last line
assertSelection(END_OF_2ND_LINE);
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
MetaKeyKeyListener.resetMetaState(mEditable);
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_RIGHT, null));
// first line
// second l|ine
// last line
assertSelection(SPACE_IN_2ND_LINE + 1);
Selection.setSelection(mEditable, END_OF_2ND_LINE);
// first line
// second line|
// last line
assertTrue(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_RIGHT, null));
// first line
// second line
// |last line
assertSelection(START_OF_3RD_LINE);
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onKeyDown(TextView, Spannable, int, "
+ "KeyEvent)}. Test the method before the widget get layouted.",
method = "onKeyDown",
args = {TextView.class, Spannable.class, int.class, KeyEvent.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. @throws clause "
+ "should be added into javadoc of ArrowKeyMovementMethod#onKeyDown(TextView, "
+ "Spannable, int, KeyEvent)} when the view does not get layout")
public void testOnKeyDownWithNullLayout() {
initTextViewWithNullLayout();
mEditable = (Editable) mTextView.getText();
try {
mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable, KeyEvent.KEYCODE_DPAD_RIGHT,
null);
fail("The method did not throw NullPointerException when layout of the view is null.");
} catch (NullPointerException e) {
// expected
}
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onKeyOther(TextView, Spannable, KeyEvent)}.",
method = "onKeyOther",
args = {TextView.class, Spannable.class, KeyEvent.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. There is no "
+ "document about the behaviour of this method.")
@UiThreadTest
public void testOnKeyOther() {
// first line
// second |line
// last line
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
assertFalse(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
new KeyEvent(0, 0, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_DPAD_CENTER, 2)));
assertFalse(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
new KeyEvent(0, 0, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_0, 2)));
assertFalse(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
new KeyEvent(0, 0, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_E, 2)));
assertFalse(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
new KeyEvent(0, 0, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_UNKNOWN, 2)));
assertFalse(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP, 0)));
assertFalse(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN, 0)));
assertFalse(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT, 0)));
assertFalse(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT, 0)));
// only repeat arrow key events get handled
assertTrue(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
new KeyEvent(0, 0, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_DPAD_UP, 2)));
assertTrue(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
new KeyEvent(0, 0, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_DPAD_DOWN, 2)));
assertTrue(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
new KeyEvent(0, 0, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_DPAD_LEFT, 2)));
assertTrue(mArrowKeyMovementMethod.onKeyOther(mTextView, mEditable,
new KeyEvent(0, 0, KeyEvent.ACTION_MULTIPLE, KeyEvent.KEYCODE_DPAD_RIGHT, 2)));
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onKeyDown(TextView, Spannable, int, "
+ "KeyEvent)}. Test the method with other key code except up, down, left ,right.",
method = "onKeyDown",
args = {TextView.class, Spannable.class, int.class, KeyEvent.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. There is no "
+ "document about the behaviour of this method.")
@UiThreadTest
public void testOnKeyDownWithOtherKeyCode() {
// first line
// second |line
// last line
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
assertFalse(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_DPAD_CENTER, null));
assertFalse(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_0, null));
assertFalse(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_E, null));
assertFalse(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
KeyEvent.KEYCODE_UNKNOWN, null));
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onKeyDown(TextView, Spannable, int, "
+ "KeyEvent)}. Test the method with null parameters.",
method = "onKeyDown",
args = {TextView.class, Spannable.class, int.class, KeyEvent.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. @throws clause "
+ "should be added into javadoc of ArrowKeyMovementMethod#onKeyDown(TextView, "
+ "Spannable, int, KeyEvent)} when the params view or buffer is null")
public void testOnKeyDownWithNullParameters() {
initTextViewWithNullLayout();
mEditable = (Editable) mTextView.getText();
try {
mArrowKeyMovementMethod.onKeyDown(null, mEditable, KeyEvent.KEYCODE_DPAD_RIGHT,
new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT));
fail("The method did not throw NullPointerException when param textView is null.");
} catch (NullPointerException e) {
// expected
}
try {
mArrowKeyMovementMethod.onKeyDown(mTextView, null, KeyEvent.KEYCODE_DPAD_RIGHT,
new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT));
fail("The method did not throw NullPointerException when param spannable is null.");
} catch (NullPointerException e) {
// expected
}
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onTouchEvent(TextView, Spannable,"
+ " MotionEvent)}. Test the method while the widget is focused.",
method = "onTouchEvent",
args = {TextView.class, Spannable.class, MotionEvent.class}
)
@UiThreadTest
@ToBeFixed(bug = "1400249", explanation = "There is a side effect that the "
+ "view scroll while dragging on the screen. Should be tested in functional test.")
public void testOnTouchEvent() throws Throwable {
long now = SystemClock.currentThreadTimeMillis();
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
assertFalse(mArrowKeyMovementMethod.onTouchEvent(mTextView, mEditable,
MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, 1, 1, 0)));
assertSelection(SPACE_IN_2ND_LINE);
assertFalse(mArrowKeyMovementMethod.onTouchEvent(mTextView, mEditable,
MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, 1, 1,
KeyEvent.META_SHIFT_ON)));
assertSelection(SPACE_IN_2ND_LINE);
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onTouchEvent(TextView, Spannable, "
+ "MotionEvent)}. Test the method before the widget get layouted.",
method = "onTouchEvent",
args = {TextView.class, Spannable.class, MotionEvent.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. @throws clause "
+ "should be added into javadoc of ArrowKeyMovementMethod#onTouchEvent(TextView, "
+ "Spannable, MotionEvent)} when the view does not get layout")
public void testOnTouchEventWithNullLayout() {
initTextViewWithNullLayout();
mEditable = (Editable) mTextView.getText();
mTextView.setFocusable(true);
mTextView.requestFocus();
assertTrue(mTextView.isFocused());
long now = SystemClock.currentThreadTimeMillis();
assertFalse(mArrowKeyMovementMethod.onTouchEvent(mTextView, mEditable,
MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, 1, 1, 0)));
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onTouchEvent(TextView, Spannable, "
+ "MotionEvent)}. Test the method while the widget is not focused.",
method = "onTouchEvent",
args = {TextView.class, Spannable.class, MotionEvent.class}
)
@UiThreadTest
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. There is no "
+ "document about the behaviour of this method.")
public void testOnTouchEventWithoutFocus() {
long now = SystemClock.currentThreadTimeMillis();
Selection.setSelection(mEditable, SPACE_IN_2ND_LINE);
assertFalse(mArrowKeyMovementMethod.onTouchEvent(mTextView, mEditable,
MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, 1, 1, 0)));
assertSelection(SPACE_IN_2ND_LINE);
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onTouchEvent(TextView, Spannable, "
+ "MotionEvent)}. Test the method with null parameters.",
method = "onTouchEvent",
args = {TextView.class, Spannable.class, MotionEvent.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. @throws clause "
+ "should be added into javadoc of ArrowKeyMovementMethod#onTouchEvent(TextView, "
+ "Spannable, MotionEvent)} when the params view, buffer or event is null")
public void testOnTouchEventWithNullParameters() {
initTextViewWithNullLayout();
mEditable = (Editable) mTextView.getText();
try {
mArrowKeyMovementMethod.onTouchEvent(null, mEditable,
MotionEvent.obtain(0, 0, 0, 1, 1, 0));
fail("The method did not throw NullPointerException when param textView is null.");
} catch (NullPointerException e) {
// expected
}
try {
mArrowKeyMovementMethod.onTouchEvent(mTextView, null,
MotionEvent.obtain(0, 0, 0, 1, 1, 0));
fail("The method did not throw NullPointerException when param spannable is null.");
} catch (NullPointerException e) {
// expected
}
try {
mArrowKeyMovementMethod.onTouchEvent(mTextView, mEditable, null);
fail("The method did not throw NullPointerException when param motionEvent is null.");
} catch (NullPointerException e) {
// expected
}
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#initialize(TextView, Spannable)}. "
+ "TextView parameter is never read.",
method = "initialize",
args = {TextView.class, Spannable.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. @throws clause "
+ "should be added into javadoc of ArrowKeyMovementMethod#initialize(TextView, "
+ "Spannable)} when the params text is null")
public void testInitialize() {
Spannable spannable = new SpannableString("test content");
ArrowKeyMovementMethod method = new ArrowKeyMovementMethod();
assertEquals(-1, Selection.getSelectionStart(spannable));
assertEquals(-1, Selection.getSelectionEnd(spannable));
method.initialize(null, spannable);
assertEquals(0, Selection.getSelectionStart(spannable));
assertEquals(0, Selection.getSelectionEnd(spannable));
Selection.setSelection(spannable, 2);
assertEquals(2, Selection.getSelectionStart(spannable));
assertEquals(2, Selection.getSelectionEnd(spannable));
method.initialize(null, spannable);
assertEquals(0, Selection.getSelectionStart(spannable));
assertEquals(0, Selection.getSelectionEnd(spannable));
try {
method.initialize(mTextView, null);
fail("The method did not throw NullPointerException when param spannable is null.");
} catch (NullPointerException e) {
// expected
}
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onTrackballEvent(TextView, Spannable, "
+ "MotionEvent)}. This method always returns false.",
method = "onTrackballEvent",
args = {TextView.class, Spannable.class, MotionEvent.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. "
+ "There is no document about behaviour of this method.")
public void testOnTrackballEven() {
assertFalse(mArrowKeyMovementMethod.onTrackballEvent(mTextView, mEditable,
MotionEvent.obtain(0, 0, 0, 1, 1, 0)));
initTextViewWithNullLayout();
mEditable = (Editable) mTextView.getText();
assertFalse(mArrowKeyMovementMethod.onTrackballEvent(mTextView, mEditable,
MotionEvent.obtain(0, 0, 0, 1, 1, 0)));
assertFalse(mArrowKeyMovementMethod.onTrackballEvent(mTextView, null,
MotionEvent.obtain(0, 0, 0, 1, 1, 0)));
assertFalse(mArrowKeyMovementMethod.onTrackballEvent(mTextView, mEditable, null));
}
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "Test {@link ArrowKeyMovementMethod#onKeyUp(TextView, Spannable, int, KeyEvent)}. "
+ "It always returns false.",
method = "onKeyUp",
args = {TextView.class, Spannable.class, int.class, KeyEvent.class}
)
@ToBeFixed(bug = "1695243", explanation = "Android API javadocs are incomplete. "
+ "There is no document about behaviour of this method.")
public void testOnKeyUp() {
ArrowKeyMovementMethod method = new ArrowKeyMovementMethod();
SpannableString spannable = new SpannableString("Test Content");
KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
TextView view = new TextView(getActivity());
assertFalse(method.onKeyUp(view, spannable, KeyEvent.KEYCODE_0, event));
assertFalse(method.onKeyUp(null, null, 0, null));
assertFalse(method.onKeyUp(null, spannable, KeyEvent.KEYCODE_0, event));
assertFalse(method.onKeyUp(view, null, KeyEvent.KEYCODE_0, event));
assertFalse(method.onKeyUp(view, spannable, 0, event));
assertFalse(method.onKeyUp(view, spannable, KeyEvent.KEYCODE_0, null));
}
private void initTextViewWithNullLayout() {
mTextView = new TextView(getActivity());
mTextView.setText(THREE_LINES_TEXT, BufferType.EDITABLE);
assertNull(mTextView.getLayout());
}
private void pressMetaKey(int metakey, int expectedState) {
mMetaListener.onKeyDown(null, mEditable, metakey, null);
assertEquals(1, MetaKeyKeyListener.getMetaState(mEditable, expectedState));
}
private void pressShift() {
MetaKeyKeyListener.resetMetaState(mEditable);
pressMetaKey(KeyEvent.KEYCODE_SHIFT_LEFT, MetaKeyKeyListener.META_SHIFT_ON);
}
private void pressAlt() {
MetaKeyKeyListener.resetMetaState(mEditable);
pressMetaKey(KeyEvent.KEYCODE_ALT_LEFT, MetaKeyKeyListener.META_ALT_ON);
}
private void pressBothShiftAlt() {
MetaKeyKeyListener.resetMetaState(mEditable);
pressMetaKey(KeyEvent.KEYCODE_SHIFT_LEFT, MetaKeyKeyListener.META_SHIFT_ON);
pressMetaKey(KeyEvent.KEYCODE_ALT_LEFT, MetaKeyKeyListener.META_ALT_ON);
}
private void assertSelection(int position) {
assertSelection(position, position);
}
private void assertSelection(int start, int end) {
assertEquals(start, Selection.getSelectionStart(mEditable));
assertEquals(end, Selection.getSelectionEnd(mEditable));
}
private void assertSelectEndOfContent() {
Selection.removeSelection(mEditable);
mArrowKeyMovementMethod.onTakeFocus(mTextView, mEditable, View.FOCUS_DOWN);
assertSelection(END_OF_ALL_TEXT);
Selection.removeSelection(mEditable);
mArrowKeyMovementMethod.onTakeFocus(mTextView, mEditable, View.FOCUS_RIGHT);
assertSelection(END_OF_ALL_TEXT);
assertSelectEndOfContentExceptFocusForward();
}
private void assertSelectEndOfContentExceptFocusForward() {
Selection.removeSelection(mEditable);
mArrowKeyMovementMethod.onTakeFocus(mTextView, mEditable, View.FOCUS_UP);
assertSelection(END_OF_ALL_TEXT);
Selection.removeSelection(mEditable);
mArrowKeyMovementMethod.onTakeFocus(mTextView, mEditable, View.FOCUS_LEFT);
assertSelection(END_OF_ALL_TEXT);
}
private static class MyMetaKeyKeyListener extends MetaKeyKeyListener {
}
}