Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2008 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.text.method.cts;
     18 
     19 import static org.junit.Assert.assertEquals;
     20 import static org.junit.Assert.assertFalse;
     21 import static org.junit.Assert.assertNull;
     22 import static org.junit.Assert.assertTrue;
     23 import static org.junit.Assert.fail;
     24 
     25 import android.support.test.filters.MediumTest;
     26 import android.support.test.runner.AndroidJUnit4;
     27 import android.text.Selection;
     28 import android.text.Spannable;
     29 import android.text.SpannableString;
     30 import android.text.Spanned;
     31 import android.text.method.NumberKeyListener;
     32 import android.view.KeyEvent;
     33 import android.widget.TextView.BufferType;
     34 
     35 import com.android.compatibility.common.util.CtsKeyEventUtil;
     36 
     37 import org.junit.Test;
     38 import org.junit.runner.RunWith;
     39 
     40 @MediumTest
     41 @RunWith(AndroidJUnit4.class)
     42 public class NumberKeyListenerTest extends KeyListenerTestCase {
     43     private MockNumberKeyListener mMockNumberKeyListener;
     44 
     45     /**
     46      * Check point:
     47      * 1. Filter "Android test", return "".
     48      * 2. Filter "12345", return null.
     49      * 3. Filter "", return null.
     50      * 4. Filter "12345 Android", return "12345".
     51      * 5. Filter Spanned("12345 Android"), return Spanned("12345") and copy spans.
     52      */
     53     @Test
     54     public void testFilter() {
     55         mMockNumberKeyListener = new MockNumberKeyListener(MockNumberKeyListener.DIGITS);
     56         String source = "Android test";
     57         SpannableString dest = new SpannableString("012345");
     58         assertEquals("", mMockNumberKeyListener.filter(source, 0, source.length(),
     59                 dest, 0, dest.length()).toString());
     60 
     61         source = "12345";
     62         dest = new SpannableString("012345");
     63         assertNull(mMockNumberKeyListener.filter(source, 0, source.length(), dest, 0,
     64                 dest.length()));
     65 
     66         source = "";
     67         dest = new SpannableString("012345");
     68         assertNull(mMockNumberKeyListener.filter(source, 0, source.length(), dest, 0,
     69                 dest.length()));
     70 
     71         source = "12345 Android";
     72         dest = new SpannableString("012345 Android-test");
     73         assertEquals("12345", mMockNumberKeyListener.filter(source, 0, source.length(),
     74                 dest, 0, dest.length()).toString());
     75 
     76         Object what = new Object();
     77         Spannable spannableSource = new SpannableString("12345 Android");
     78         spannableSource.setSpan(what, 0, spannableSource.length(), Spanned.SPAN_POINT_POINT);
     79         Spanned filtered = (Spanned) mMockNumberKeyListener.filter(spannableSource,
     80                 0, spannableSource.length(), dest, 0, dest.length());
     81         assertEquals("12345", filtered.toString());
     82         assertEquals(Spanned.SPAN_POINT_POINT, filtered.getSpanFlags(what));
     83         assertEquals(0, filtered.getSpanStart(what));
     84         assertEquals("12345".length(), filtered.getSpanEnd(what));
     85 
     86         try {
     87             mMockNumberKeyListener.filter(null, 0, 1, dest, 0, dest.length());
     88             fail("should throw NullPointerException.");
     89         } catch (NullPointerException e) {
     90         }
     91     }
     92 
     93     /**
     94      * Check point:
     95      * If one of the chars in the getAcceptedChars() can be generated by the keyCode of this
     96      * key event, return the char; otherwise return '\0'.
     97      */
     98     @Test
     99     public void testLookup() {
    100         mMockNumberKeyListener = new MockNumberKeyListener(MockNumberKeyListener.DIGITS);
    101         KeyEvent event1 = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
    102         SpannableString str = new SpannableString("012345");
    103         assertEquals('0', mMockNumberKeyListener.lookup(event1, str));
    104 
    105         mMockNumberKeyListener = new MockNumberKeyListener(MockNumberKeyListener.NOTHING);
    106         KeyEvent event2 = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A);
    107         str = new SpannableString("ABCD");
    108         assertEquals('\0', mMockNumberKeyListener.lookup(event2, str));
    109 
    110         try {
    111             mMockNumberKeyListener.lookup(null, str);
    112             fail("should throw NullPointerException.");
    113         } catch (NullPointerException e) {
    114             // expected.
    115         }
    116     }
    117 
    118     @Test
    119     public void testOk() {
    120         mMockNumberKeyListener = new MockNumberKeyListener(MockNumberKeyListener.DIGITS);
    121 
    122         assertTrue(mMockNumberKeyListener.callOk(mMockNumberKeyListener.getAcceptedChars(), '3'));
    123         assertFalse(mMockNumberKeyListener.callOk(mMockNumberKeyListener.getAcceptedChars(), 'e'));
    124 
    125         try {
    126             mMockNumberKeyListener.callOk(null, 'm');
    127             fail("should throw NullPointerException.");
    128         } catch (NullPointerException e) {
    129         }
    130     }
    131 
    132     /**
    133      * Check point:
    134      * 1. Press '0' key, '0' will be added to the text.
    135      * 2. Press an unaccepted key if it exists, it will not be added.
    136      * 3. remove NumberKeyListener and press '0' key, '0' will not be added.
    137      */
    138     @Test
    139     public void testPressKey() {
    140         final CharSequence text = "123456";
    141         final MockNumberKeyListener mockNumberKeyListener =
    142             new MockNumberKeyListener(MockNumberKeyListener.DIGITS);
    143 
    144         mActivity.runOnUiThread(() -> {
    145             mTextView.setText(text, BufferType.EDITABLE);
    146             mTextView.setKeyListener(mockNumberKeyListener);
    147             mTextView.requestFocus();
    148             Selection.setSelection(mTextView.getText(), 0, 0);
    149         });
    150         mInstrumentation.waitForIdleSync();
    151         assertEquals("123456", mTextView.getText().toString());
    152         // press '0' key.
    153         CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, KeyEvent.KEYCODE_0);
    154         assertEquals("0123456", mTextView.getText().toString());
    155 
    156         // an unaccepted key if it exists.
    157         int keyCode = TextMethodUtils.getUnacceptedKeyCode(MockNumberKeyListener.DIGITS);
    158         if (-1 != keyCode) {
    159             CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, keyCode);
    160             // text of TextView will not be changed.
    161             assertEquals("0123456", mTextView.getText().toString());
    162         }
    163 
    164         mActivity.runOnUiThread(() -> {
    165             mTextView.setKeyListener(null);
    166             mTextView.requestFocus();
    167         });
    168         mInstrumentation.waitForIdleSync();
    169         // press '0' key.
    170         CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, KeyEvent.KEYCODE_0);
    171         assertEquals("0123456", mTextView.getText().toString());
    172     }
    173 
    174     /**
    175      * A mocked {@link android.text.method.NumberKeyListener} for testing purposes.
    176      *
    177      * Allows {@link NumberKeyListenerTest} to call
    178      * {@link android.text.method.NumberKeyListener#getAcceptedChars()},
    179      * {@link android.text.method.NumberKeyListener#lookup(KeyEvent, Spannable)}, and
    180      * {@link android.text.method.NumberKeyListener@ok(char[], char)}.
    181      */
    182     private static class MockNumberKeyListener extends NumberKeyListener {
    183         static final char[] DIGITS =
    184                 new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
    185 
    186         static final char[] NOTHING = new char[0];
    187 
    188         private final char[] mAcceptedChars;
    189 
    190         MockNumberKeyListener(char[] acceptedChars) {
    191             this.mAcceptedChars = acceptedChars;
    192         }
    193 
    194         @Override
    195         protected char[] getAcceptedChars() {
    196             return mAcceptedChars;
    197         }
    198 
    199         @Override
    200         protected int lookup(KeyEvent event, Spannable content) {
    201             return super.lookup(event, content);
    202         }
    203 
    204         public boolean callOk(char[] accept, char c) {
    205             return NumberKeyListener.ok(accept, c);
    206         }
    207 
    208         public int getInputType() {
    209             return 0;
    210         }
    211     }
    212 }
    213