Home | History | Annotate | Download | only in widget
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.widget;
     18 
     19 import android.test.ActivityInstrumentationTestCase2;
     20 import android.test.suitebuilder.annotation.SmallTest;
     21 import android.view.Choreographer;
     22 import android.view.ViewGroup;
     23 
     24 import java.util.concurrent.CountDownLatch;
     25 import java.util.concurrent.TimeUnit;
     26 
     27 import static android.support.test.espresso.Espresso.onView;
     28 import static android.support.test.espresso.action.ViewActions.click;
     29 import static android.widget.espresso.TextViewAssertions.hasInsertionPointerOnLeft;
     30 import static android.widget.espresso.TextViewAssertions.hasInsertionPointerOnRight;
     31 import static org.hamcrest.MatcherAssert.assertThat;
     32 import static org.hamcrest.Matchers.equalTo;
     33 import static org.hamcrest.Matchers.isEmptyString;
     34 import static org.hamcrest.Matchers.nullValue;
     35 import static org.hamcrest.Matchers.sameInstance;
     36 
     37 public class EditorCursorTest extends ActivityInstrumentationTestCase2<TextViewActivity> {
     38 
     39 
     40     private final static String LTR_STRING = "aaaaaaaaaaaaaaaaaaaaaa";
     41     private final static String LTR_HINT = "hint";
     42     private final static String RTL_STRING = "     ";
     43     private final static String RTL_HINT = "";
     44     private final static int CURSOR_BLINK_MS = 500;
     45 
     46     private EditText mEditText;
     47 
     48     public EditorCursorTest() {
     49         super(TextViewActivity.class);
     50     }
     51 
     52     @Override
     53     protected void setUp() throws Exception {
     54         super.setUp();
     55         mEditText = new EditText(getActivity());
     56         mEditText.setTextSize(30);
     57         mEditText.setSingleLine(true);
     58         mEditText.setLines(1);
     59         mEditText.setPadding(15, 15, 15, 15);
     60         ViewGroup.LayoutParams editTextLayoutParams = new ViewGroup.LayoutParams(200,
     61                 ViewGroup.LayoutParams.WRAP_CONTENT);
     62 
     63         mEditText.setLayoutParams(editTextLayoutParams);
     64 
     65         final FrameLayout layout = new FrameLayout(getActivity());
     66         ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
     67                 ViewGroup.LayoutParams.MATCH_PARENT,
     68                 ViewGroup.LayoutParams.MATCH_PARENT);
     69         layout.setLayoutParams(layoutParams);
     70         layout.addView(mEditText);
     71 
     72         getActivity().runOnUiThread(new Runnable() {
     73             @Override
     74             public void run() {
     75                 getActivity().setContentView(layout);
     76             }
     77         });
     78         getInstrumentation().waitForIdleSync();
     79         onView(sameInstance(mEditText)).perform(click());
     80     }
     81 
     82     @SmallTest
     83     public void testCursorIsInViewBoundariesWhenOnRightForLtr() {
     84         // Asserts that when an EditText has LTR text, and cursor is at the end (right),
     85         // cursor is drawn to the right edge of the view
     86         setEditTextText(LTR_STRING, LTR_STRING.length());
     87 
     88         onView(sameInstance(mEditText)).check(hasInsertionPointerOnRight());
     89     }
     90 
     91     @SmallTest
     92     public void testCursorIsInViewBoundariesWhenOnLeftForLtr() {
     93         // Asserts that when an EditText has LTR text, and cursor is at the beginning,
     94         // cursor is drawn to the left edge of the view
     95         setEditTextText(LTR_STRING, 0);
     96 
     97         onView(sameInstance(mEditText)).check(hasInsertionPointerOnLeft());
     98     }
     99 
    100     @SmallTest
    101     public void testCursorIsInViewBoundariesWhenOnRightForRtl() {
    102         // Asserts that when an EditText has RTL text, and cursor is at the end,
    103         // cursor is drawn to the left edge of the view
    104         setEditTextText(RTL_STRING, 0);
    105 
    106         onView(sameInstance(mEditText)).check(hasInsertionPointerOnRight());
    107     }
    108 
    109     @SmallTest
    110     public void testCursorIsInViewBoundariesWhenOnLeftForRtl() {
    111         // Asserts that when an EditText has RTL text, and cursor is at the beginning,
    112         // cursor is drawn to the right edge of the view
    113         setEditTextText(RTL_STRING, RTL_STRING.length());
    114 
    115         onView(sameInstance(mEditText)).check(hasInsertionPointerOnLeft());
    116     }
    117 
    118     /* Tests for cursor positioning with hint */
    119     @SmallTest
    120     public void testCursorIsOnLeft_withFirstStrongLtrAlgorithm() {
    121         setEditTextHint(null, TextView.TEXT_DIRECTION_FIRST_STRONG_LTR, 0);
    122         assertThat(mEditText.getText().toString(), isEmptyString());
    123         assertThat(mEditText.getHint(), nullValue());
    124 
    125         onView(sameInstance(mEditText)).check(hasInsertionPointerOnLeft());
    126 
    127         setEditTextHint(RTL_HINT, TextView.TEXT_DIRECTION_FIRST_STRONG_LTR, 0);
    128         assertThat(mEditText.getText().toString(), isEmptyString());
    129 
    130         onView(sameInstance(mEditText)).check(hasInsertionPointerOnLeft());
    131 
    132         setEditTextHint(LTR_HINT, TextView.TEXT_DIRECTION_FIRST_STRONG_LTR, 0);
    133         assertThat(mEditText.getText().toString(), isEmptyString());
    134 
    135         onView(sameInstance(mEditText)).check(hasInsertionPointerOnLeft());
    136     }
    137 
    138     @SmallTest
    139     public void testCursorIsOnRight_withFirstStrongRtlAlgorithm() {
    140         setEditTextHint(null, TextView.TEXT_DIRECTION_FIRST_STRONG_RTL, 0);
    141         assertThat(mEditText.getText().toString(), isEmptyString());
    142         assertThat(mEditText.getHint(), nullValue());
    143 
    144         onView(sameInstance(mEditText)).check(hasInsertionPointerOnRight());
    145 
    146         setEditTextHint(LTR_HINT, TextView.TEXT_DIRECTION_FIRST_STRONG_RTL, 0);
    147         assertThat(mEditText.getText().toString(), isEmptyString());
    148 
    149         onView(sameInstance(mEditText)).check(hasInsertionPointerOnRight());
    150 
    151         setEditTextHint(RTL_HINT, TextView.TEXT_DIRECTION_FIRST_STRONG_RTL, 0);
    152         assertThat(mEditText.getText().toString(), isEmptyString());
    153 
    154         onView(sameInstance(mEditText)).check(hasInsertionPointerOnRight());
    155     }
    156 
    157     @SmallTest
    158     public void testCursorIsOnLeft_withLtrAlgorithm() {
    159         setEditTextHint(null, TextView.TEXT_DIRECTION_LTR, 0);
    160         assertThat(mEditText.getText().toString(), isEmptyString());
    161         assertThat(mEditText.getHint(), nullValue());
    162 
    163         onView(sameInstance(mEditText)).check(hasInsertionPointerOnLeft());
    164 
    165         setEditTextHint(RTL_HINT, TextView.TEXT_DIRECTION_LTR, 0);
    166         assertThat(mEditText.getText().toString(), isEmptyString());
    167 
    168         onView(sameInstance(mEditText)).check(hasInsertionPointerOnLeft());
    169 
    170         setEditTextHint(LTR_HINT, TextView.TEXT_DIRECTION_LTR, 0);
    171         assertThat(mEditText.getText().toString(), isEmptyString());
    172 
    173         onView(sameInstance(mEditText)).check(hasInsertionPointerOnLeft());
    174     }
    175 
    176     @SmallTest
    177     public void testCursorIsOnRight_withRtlAlgorithm() {
    178         setEditTextHint(null, TextView.TEXT_DIRECTION_RTL, 0);
    179         assertThat(mEditText.getText().toString(), isEmptyString());
    180         assertThat(mEditText.getHint(), nullValue());
    181 
    182         onView(sameInstance(mEditText)).check(hasInsertionPointerOnRight());
    183 
    184         setEditTextHint(LTR_HINT, TextView.TEXT_DIRECTION_RTL, 0);
    185         assertThat(mEditText.getText().toString(), isEmptyString());
    186 
    187         onView(sameInstance(mEditText)).check(hasInsertionPointerOnRight());
    188 
    189         setEditTextHint(RTL_HINT, TextView.TEXT_DIRECTION_RTL, 0);
    190         assertThat(mEditText.getText().toString(), isEmptyString());
    191 
    192         onView(sameInstance(mEditText)).check(hasInsertionPointerOnRight());
    193     }
    194 
    195     private void setEditTextProperties(final String text, final String hint,
    196             final Integer textDirection, final Integer selection) {
    197         getActivity().runOnUiThread(new Runnable() {
    198             @Override
    199             public void run() {
    200                 if (textDirection != null) mEditText.setTextDirection(textDirection);
    201                 if (text != null) mEditText.setText(text);
    202                 if (hint != null) mEditText.setHint(hint);
    203                 if (selection != null) mEditText.setSelection(selection);
    204             }
    205         });
    206         getInstrumentation().waitForIdleSync();
    207 
    208         // wait for cursor to be drawn. updateCursorPositions function is called during draw() and
    209         // only when cursor is visible during blink.
    210         final CountDownLatch latch = new CountDownLatch(1);
    211         mEditText.postOnAnimationDelayed(new Runnable() {
    212             @Override
    213             public void run() {
    214                 latch.countDown();
    215             }
    216         }, CURSOR_BLINK_MS);
    217         try {
    218             assertThat("Problem while waiting for the cursor to blink",
    219                     latch.await(10, TimeUnit.SECONDS), equalTo(true));
    220         } catch (Exception e) {
    221             fail("Problem while waiting for the cursor to blink");
    222         }
    223     }
    224 
    225     private void setEditTextHint(final String hint, final int textDirection, final int selection) {
    226         setEditTextProperties(null, hint, textDirection, selection);
    227     }
    228 
    229     private void setEditTextText(final String text, final Integer selection) {
    230         setEditTextProperties(text, null, null, selection);
    231     }
    232 }
    233