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