1/* 2 * Copyright (C) 2017 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 17package androidx.emoji.widget; 18 19import static androidx.emoji.util.EmojiMatcher.sameCharSequence; 20 21import static org.junit.Assert.assertEquals; 22import static org.junit.Assert.assertFalse; 23import static org.junit.Assert.assertNotNull; 24import static org.junit.Assert.assertNull; 25import static org.junit.Assert.assertTrue; 26import static org.mockito.ArgumentMatchers.anyInt; 27import static org.mockito.ArgumentMatchers.eq; 28import static org.mockito.Mockito.mock; 29import static org.mockito.Mockito.times; 30import static org.mockito.Mockito.verify; 31import static org.mockito.Mockito.when; 32 33import android.content.Context; 34import android.inputmethodservice.InputMethodService; 35import android.support.test.InstrumentationRegistry; 36import android.support.test.annotation.UiThreadTest; 37import android.support.test.filters.SdkSuppress; 38import android.support.test.filters.SmallTest; 39import android.support.test.runner.AndroidJUnit4; 40import android.text.InputType; 41import android.view.LayoutInflater; 42import android.view.View; 43import android.view.ViewGroup; 44import android.view.inputmethod.EditorInfo; 45 46import androidx.emoji.R; 47import androidx.emoji.text.EmojiCompat; 48 49import org.junit.Before; 50import org.junit.BeforeClass; 51import org.junit.Test; 52import org.junit.runner.RunWith; 53 54@SmallTest 55@RunWith(AndroidJUnit4.class) 56public class EmojiExtractTextLayoutTest { 57 58 private InputMethodService mInputMethodService; 59 60 @BeforeClass 61 public static void setupEmojiCompat() { 62 EmojiCompat.reset(mock(EmojiCompat.class)); 63 } 64 65 @Before 66 public void setup() { 67 mInputMethodService = mock(InputMethodService.class); 68 } 69 70 @Test 71 @UiThreadTest 72 public void testInflate() { 73 final Context context = InstrumentationRegistry.getTargetContext(); 74 final EmojiExtractTextLayout layout = (EmojiExtractTextLayout) LayoutInflater.from(context) 75 .inflate(androidx.emoji.test.R.layout.extract_view, null); 76 77 final EmojiExtractEditText extractEditText = layout.findViewById( 78 android.R.id.inputExtractEditText); 79 assertNotNull(extractEditText); 80 81 final ViewGroup inputExtractAccessories = layout.findViewById( 82 R.id.inputExtractAccessories); 83 assertNotNull(inputExtractAccessories); 84 85 final ExtractButtonCompat extractButton = inputExtractAccessories.findViewById( 86 R.id.inputExtractAction); 87 assertNotNull(extractButton); 88 } 89 90 @Test 91 @UiThreadTest 92 public void testSetKeyListener_withNull() { 93 final Context context = InstrumentationRegistry.getTargetContext(); 94 final EmojiExtractTextLayout layout = (EmojiExtractTextLayout) LayoutInflater.from(context) 95 .inflate(androidx.emoji.test.R.layout.extract_view, null); 96 97 final EmojiExtractEditText extractEditText = layout.findViewById( 98 android.R.id.inputExtractEditText); 99 assertNotNull(extractEditText); 100 101 extractEditText.setKeyListener(null); 102 assertNull(extractEditText.getKeyListener()); 103 } 104 105 @Test 106 @UiThreadTest 107 public void testSetEmojiReplaceStrategy() { 108 final Context context = InstrumentationRegistry.getTargetContext(); 109 110 final EmojiExtractTextLayout layout = (EmojiExtractTextLayout) LayoutInflater.from(context) 111 .inflate(androidx.emoji.test.R.layout.extract_view_with_attrs, null); 112 113 assertEquals(EmojiCompat.REPLACE_STRATEGY_NON_EXISTENT, layout.getEmojiReplaceStrategy()); 114 115 final EmojiExtractEditText extractEditText = layout.findViewById( 116 android.R.id.inputExtractEditText); 117 assertNotNull(extractEditText); 118 assertEquals(EmojiCompat.REPLACE_STRATEGY_NON_EXISTENT, 119 extractEditText.getEmojiReplaceStrategy()); 120 121 layout.setEmojiReplaceStrategy(EmojiCompat.REPLACE_STRATEGY_ALL); 122 assertEquals(EmojiCompat.REPLACE_STRATEGY_ALL, layout.getEmojiReplaceStrategy()); 123 assertEquals(EmojiCompat.REPLACE_STRATEGY_ALL, extractEditText.getEmojiReplaceStrategy()); 124 } 125 126 @Test 127 @UiThreadTest 128 @SdkSuppress(minSdkVersion = 19) 129 public void testSetEmojiReplaceStrategyCallEmojiCompatWithCorrectStrategy() { 130 final Context context = InstrumentationRegistry.getTargetContext(); 131 132 final EmojiExtractTextLayout layout = (EmojiExtractTextLayout) LayoutInflater.from(context) 133 .inflate(androidx.emoji.test.R.layout.extract_view_with_attrs, null); 134 135 final EmojiExtractEditText extractEditText = layout.findViewById( 136 android.R.id.inputExtractEditText); 137 assertNotNull(layout); 138 assertNotNull(extractEditText); 139 assertEquals(EmojiCompat.REPLACE_STRATEGY_NON_EXISTENT, layout.getEmojiReplaceStrategy()); 140 141 final EmojiCompat emojiCompat = mock(EmojiCompat.class); 142 when(emojiCompat.getLoadState()).thenReturn(EmojiCompat.LOAD_STATE_SUCCEEDED); 143 EmojiCompat.reset(emojiCompat); 144 145 final String testString = "anytext"; 146 extractEditText.setText(testString); 147 148 verify(emojiCompat, times(1)).process(sameCharSequence(testString), anyInt(), anyInt(), 149 anyInt(), eq(EmojiCompat.REPLACE_STRATEGY_NON_EXISTENT)); 150 } 151 152 @Test 153 @UiThreadTest 154 public void testOnUpdateExtractingViews() { 155 final Context context = InstrumentationRegistry.getTargetContext(); 156 final EmojiExtractTextLayout layout = (EmojiExtractTextLayout) LayoutInflater.from(context) 157 .inflate(androidx.emoji.test.R.layout.extract_view, null); 158 159 final EditorInfo editorInfo = new EditorInfo(); 160 editorInfo.actionLabel = "My Action Label"; 161 editorInfo.imeOptions = EditorInfo.IME_ACTION_SEND; 162 editorInfo.inputType = InputType.TYPE_CLASS_TEXT; 163 164 when(mInputMethodService.isExtractViewShown()).thenReturn(true); 165 166 final ViewGroup inputExtractAccessories = layout.findViewById( 167 R.id.inputExtractAccessories); 168 inputExtractAccessories.setVisibility(View.GONE); 169 170 final ExtractButtonCompat extractButton = inputExtractAccessories.findViewById( 171 R.id.inputExtractAction); 172 173 layout.onUpdateExtractingViews(mInputMethodService, editorInfo); 174 175 assertEquals(View.VISIBLE, inputExtractAccessories.getVisibility()); 176 assertEquals(editorInfo.actionLabel, extractButton.getText()); 177 assertTrue(extractButton.hasOnClickListeners()); 178 } 179 180 @Test 181 @UiThreadTest 182 public void testOnUpdateExtractingViews_hidesAccessoriesIfNoAction() { 183 final Context context = InstrumentationRegistry.getTargetContext(); 184 final EmojiExtractTextLayout layout = (EmojiExtractTextLayout) LayoutInflater.from(context) 185 .inflate(androidx.emoji.test.R.layout.extract_view, null); 186 187 final EditorInfo editorInfo = new EditorInfo(); 188 editorInfo.imeOptions = EditorInfo.IME_ACTION_NONE; 189 when(mInputMethodService.isExtractViewShown()).thenReturn(true); 190 191 final ViewGroup inputExtractAccessories = layout.findViewById( 192 R.id.inputExtractAccessories); 193 final ExtractButtonCompat extractButton = inputExtractAccessories.findViewById( 194 R.id.inputExtractAction); 195 196 layout.onUpdateExtractingViews(mInputMethodService, editorInfo); 197 198 assertEquals(View.GONE, inputExtractAccessories.getVisibility()); 199 assertFalse(extractButton.hasOnClickListeners()); 200 } 201} 202