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.assertNotEquals;
     21 import static org.junit.Assert.assertNotNull;
     22 import static org.junit.Assert.assertNotSame;
     23 import static org.junit.Assert.assertSame;
     24 
     25 import android.support.test.filters.MediumTest;
     26 import android.support.test.runner.AndroidJUnit4;
     27 import android.text.InputType;
     28 import android.text.method.TimeKeyListener;
     29 import android.view.KeyCharacterMap;
     30 import android.view.KeyEvent;
     31 
     32 import com.android.compatibility.common.util.CtsKeyEventUtil;
     33 
     34 import org.junit.Test;
     35 import org.junit.runner.RunWith;
     36 
     37 import java.util.Locale;
     38 
     39 @MediumTest
     40 @RunWith(AndroidJUnit4.class)
     41 public class TimeKeyListenerTest extends KeyListenerTestCase {
     42     @Test
     43     public void testConstructor() {
     44         // deprecated empty constructor
     45         new TimeKeyListener();
     46 
     47         // newer constructor that takes locales
     48         new TimeKeyListener(null); // fallback to old behavior
     49         new TimeKeyListener(Locale.US);
     50         new TimeKeyListener(Locale.forLanguageTag("fa-IR"));
     51     }
     52 
     53     @Test
     54     public void testGetInstance() {
     55         final TimeKeyListener emptyListener1 = TimeKeyListener.getInstance();
     56         final TimeKeyListener emptyListener2 = TimeKeyListener.getInstance();
     57         final TimeKeyListener nullListener = TimeKeyListener.getInstance(null);
     58 
     59         assertNotNull(emptyListener1);
     60         assertNotNull(emptyListener2);
     61         assertNotNull(nullListener);
     62         assertSame(emptyListener1, emptyListener2);
     63         assertSame(emptyListener1, nullListener);
     64 
     65         final TimeKeyListener usListener1 = TimeKeyListener.getInstance(Locale.US);
     66         final TimeKeyListener usListener2 = TimeKeyListener.getInstance(new Locale("en", "US"));
     67         final TimeKeyListener irListener = TimeKeyListener.getInstance(
     68                 Locale.forLanguageTag("fa-IR"));
     69 
     70         assertNotNull(usListener1);
     71         assertNotNull(usListener2);
     72         assertNotNull(irListener);
     73         assertSame(usListener1, usListener2);
     74         assertNotSame(usListener1, irListener);
     75         assertNotSame(usListener1, nullListener);
     76     }
     77 
     78     @Test
     79     public void testGetAcceptedChars() {
     80         assertNotNull(TimeKeyListener.CHARACTERS);
     81 
     82         final MockTimeKeyListener mockTimeKeyListener = new MockTimeKeyListener();
     83         assertSame(TimeKeyListener.CHARACTERS, mockTimeKeyListener.getAcceptedChars());
     84 
     85         final MockTimeKeyListener usMockTimeKeyListener = new MockTimeKeyListener(Locale.US);
     86         assertNotSame(TimeKeyListener.CHARACTERS, usMockTimeKeyListener.getAcceptedChars());
     87 
     88         MockTimeKeyListener irMockTimeKeyListener = new MockTimeKeyListener(
     89                 Locale.forLanguageTag("fa-IR"));
     90         final String acceptedChars = new String(irMockTimeKeyListener.getAcceptedChars());
     91         // Make sure all these chararacters are accepted.
     92         final char[] expectedChars = {
     93             '\u06F0', '\u06F1', '\u06F2', '\u06F3', '\u06F4',
     94             '\u06F5', '\u06F6', '\u06F7', '\u06F8', '\u06F9',
     95             ':'
     96         };
     97         for (int i = 0; i < expectedChars.length; i++) {
     98             assertNotEquals(-1, acceptedChars.indexOf(expectedChars[i]));
     99         }
    100         // Make sure all these chararacters are not accepted.
    101         final char[] unexpectedChars = {
    102             '0', '1', '2', '3', '4',
    103             '5', '6', '7', '8', '9'
    104         };
    105         for (int i = 0; i < unexpectedChars.length; i++) {
    106             assertEquals(-1, acceptedChars.indexOf(unexpectedChars[i]));
    107         }
    108 
    109     }
    110 
    111     @Test
    112     public void testGetInputType() {
    113         // The "normal" input type that has been used consistently until Android O.
    114         final int dateTimeType = InputType.TYPE_CLASS_DATETIME
    115                 | InputType.TYPE_DATETIME_VARIATION_TIME;
    116         // Fallback for locales that need more characters.
    117         final int textType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL;
    118 
    119         // Deprecated constructor that needs to preserve pre-existing behavior.
    120         TimeKeyListener listener = TimeKeyListener.getInstance();
    121         assertEquals(dateTimeType, listener.getInputType());
    122 
    123         // TYPE_CLASS_DATETIME is fine for English locales.
    124         listener = TimeKeyListener.getInstance(Locale.US);
    125         assertEquals(dateTimeType, listener.getInputType());
    126         listener = TimeKeyListener.getInstance(Locale.UK);
    127         assertEquals(dateTimeType, listener.getInputType());
    128 
    129         // Persian needs more characters then typically provided by datetime inputs, so it falls
    130         // back on normal text.
    131         listener = TimeKeyListener.getInstance(Locale.forLanguageTag("fa-IR"));
    132         assertEquals(textType, listener.getInputType());
    133     }
    134 
    135     /*
    136      * Scenario description:
    137      * 1. Press '1' key and check if the content of TextView becomes "1"
    138      * 2. Press '2' key and check if the content of TextView becomes "12"
    139      * 3. Press 'a' key if it is producible
    140      * 4. Press 'p' key if it is producible
    141      * 5. Press 'm' key if it is producible
    142      * 6. Press an unaccepted key if it exists and this key could not be entered.
    143      * 7. Remove TimeKeyListener, '1' key will not be accepted.
    144      */
    145     @Test
    146     public void testTimeKeyListener() {
    147         final TimeKeyListener timeKeyListener = TimeKeyListener.getInstance();
    148         String expectedText = "";
    149 
    150         setKeyListenerSync(timeKeyListener);
    151         assertEquals(expectedText, mTextView.getText().toString());
    152 
    153         // press '1' key.
    154         CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "1");
    155         expectedText += "1";
    156         assertEquals(expectedText, mTextView.getText().toString());
    157 
    158         // press '2' key.
    159         CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "2");
    160         expectedText += "2";
    161         assertEquals("12", mTextView.getText().toString());
    162 
    163         // press 'a' key if producible
    164         KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
    165         if ('a' == kcm.getMatch(KeyEvent.KEYCODE_A, TimeKeyListener.CHARACTERS)) {
    166             expectedText += "a";
    167             CtsKeyEventUtil.sendKeyDownUp(mInstrumentation, mTextView, KeyEvent.KEYCODE_A);
    168             assertEquals(expectedText, mTextView.getText().toString());
    169         }
    170 
    171         // press 'p' key if producible
    172         if ('p' == kcm.getMatch(KeyEvent.KEYCODE_P, TimeKeyListener.CHARACTERS)) {
    173             expectedText += "p";
    174             CtsKeyEventUtil.sendKeyDownUp(mInstrumentation, mTextView, KeyEvent.KEYCODE_P);
    175             assertEquals(expectedText, mTextView.getText().toString());
    176         }
    177 
    178         // press 'm' key if producible
    179         if ('m' == kcm.getMatch(KeyEvent.KEYCODE_M, TimeKeyListener.CHARACTERS)) {
    180             expectedText += "m";
    181             CtsKeyEventUtil.sendKeyDownUp(mInstrumentation, mTextView, KeyEvent.KEYCODE_M);
    182             assertEquals(expectedText, mTextView.getText().toString());
    183         }
    184 
    185         // press an unaccepted key if it exists.
    186         int keyCode = TextMethodUtils.getUnacceptedKeyCode(TimeKeyListener.CHARACTERS);
    187         if (-1 != keyCode) {
    188             CtsKeyEventUtil.sendKeys(mInstrumentation, mTextView, keyCode);
    189             assertEquals(expectedText, mTextView.getText().toString());
    190         }
    191 
    192         setKeyListenerSync(null);
    193 
    194         // press '1' key.
    195         CtsKeyEventUtil.sendString(mInstrumentation, mTextView, "1");
    196         assertEquals(expectedText, mTextView.getText().toString());
    197     }
    198 
    199     /**
    200      * A mocked {@link android.text.method.TimeKeyListener} for testing purposes.
    201      *
    202      * Allows {@link TimeKeyListenerTest} to call
    203      * {@link android.text.method.TimeKeyListener#getAcceptedChars()}.
    204      */
    205     private class MockTimeKeyListener extends TimeKeyListener {
    206         MockTimeKeyListener() {
    207             super();
    208         }
    209 
    210         MockTimeKeyListener(Locale locale) {
    211             super(locale);
    212         }
    213 
    214         @Override
    215         protected char[] getAcceptedChars() {
    216             return super.getAcceptedChars();
    217         }
    218     }
    219 }
    220