EmojiSpanInstrumentationTest.java revision 372c6556a754d4e7cdbeb883ab0ea5719285a68c
1372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir/* 2372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir * Copyright (C) 2017 The Android Open Source Project 3372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir * 4372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir * Licensed under the Apache License, Version 2.0 (the "License"); 5372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir * you may not use this file except in compliance with the License. 6372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir * You may obtain a copy of the License at 7372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir * 8372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir * http://www.apache.org/licenses/LICENSE-2.0 9372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir * 10372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir * Unless required by applicable law or agreed to in writing, software 11372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir * distributed under the License is distributed on an "AS IS" BASIS, 12372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir * See the License for the specific language governing permissions and 14372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir * limitations under the License. 15372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir */ 16372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 17372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirpackage android.support.text.emoji; 18372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 19372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport static android.support.text.emoji.util.Emoji.EMOJI_SINGLE_CODEPOINT; 20372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport static android.support.text.emoji.util.EmojiMatcher.hasEmojiCount; 21372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 22372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport static junit.framework.Assert.assertEquals; 23372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport static junit.framework.Assert.assertNotNull; 24372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 25372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport static org.junit.Assert.assertThat; 26372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 27372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.app.Instrumentation; 28372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.support.test.InstrumentationRegistry; 29372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.support.test.filters.LargeTest; 30372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.support.test.rule.ActivityTestRule; 31372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.support.test.runner.AndroidJUnit4; 32372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.support.text.emoji.util.TestString; 33372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.text.Spannable; 34372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.text.Spanned; 35372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.text.style.RelativeSizeSpan; 36372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.util.TypedValue; 37372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.widget.TextView; 38372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 39372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport org.junit.Before; 40372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport org.junit.BeforeClass; 41372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport org.junit.Rule; 42372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport org.junit.Test; 43372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport org.junit.runner.RunWith; 44372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 45372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir@LargeTest 46372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir@RunWith(AndroidJUnit4.class) 47372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirpublic class EmojiSpanInstrumentationTest { 48372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 49372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir @Rule 50372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir public ActivityTestRule<TestActivity> mActivityRule = new ActivityTestRule<>( 51372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir TestActivity.class); 52372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir private Instrumentation mInstrumentation; 53372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 54372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir @BeforeClass 55372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir public static void setupEmojiCompat() { 56372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir EmojiCompat.reset(TestConfigBuilder.config()); 57372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir } 58372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 59372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir @Before 60372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir public void setup() { 61372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir mInstrumentation = InstrumentationRegistry.getInstrumentation(); 62372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir } 63372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 64372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir @Test 65372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir public void testGetSize_withRelativeSizeSpan() throws Exception { 66372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir final TestActivity activity = mActivityRule.getActivity(); 67372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir final TextView textView = (TextView) activity.findViewById( 68372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir android.support.text.emoji.test.R.id.text); 69372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 70372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir // create a string with single codepoint emoji 71372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir final TestString string = new TestString(EMOJI_SINGLE_CODEPOINT).withPrefix().withSuffix(); 72372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir final CharSequence charSequence = EmojiCompat.get().process(string.toString()); 73372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir assertNotNull(charSequence); 74372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir assertThat(charSequence, hasEmojiCount(1)); 75372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 76372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir final Spannable spanned = (Spannable) charSequence; 77372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir final EmojiSpan[] spans = spanned.getSpans(0, charSequence.length(), EmojiSpan.class); 78372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir final EmojiSpan span = spans[0]; 79372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 80372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir // set text to the charSequence with the EmojiSpan 81372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir mInstrumentation.runOnMainSync(new Runnable() { 82372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir @Override 83372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir public void run() { 84372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir textView.setText(charSequence); 85372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir } 86372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir }); 87372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir mInstrumentation.waitForIdleSync(); 88372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 89372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir // record height of the default span 90372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir final int defaultHeight = span.getHeight(); 91372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 92372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir // cover the charsequence with RelativeSizeSpan which will triple the size of the 93372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir // characters. 94372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir final float multiplier = 3.0f; 95372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir final RelativeSizeSpan sizeSpan = new RelativeSizeSpan(multiplier); 96372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir spanned.setSpan(sizeSpan, 0, charSequence.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 97372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir // set the new text 98372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir mInstrumentation.runOnMainSync(new Runnable() { 99372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir @Override 100372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir public void run() { 101372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir textView.setText(charSequence); 102372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir } 103372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir }); 104372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir mInstrumentation.waitForIdleSync(); 105372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 106372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir // record the height measured after RelativeSizeSpan 107372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir final int heightWithRelativeSpan = span.getHeight(); 108372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir 109372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir // accept 1sp error rate. 110372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir final float delta = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 1, 111372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir mInstrumentation.getTargetContext().getResources().getDisplayMetrics()); 112372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir assertEquals(defaultHeight * 3, heightWithRelativeSpan, delta); 113372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir } 114372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir} 115