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