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
279546df94e6393de504f7ef8dc1b12a1f550c47a8Siyamed Sinirimport android.annotation.TargetApi;
28372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.app.Instrumentation;
29372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.support.test.InstrumentationRegistry;
30372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.support.test.filters.LargeTest;
319546df94e6393de504f7ef8dc1b12a1f550c47a8Siyamed Sinirimport android.support.test.filters.SdkSuppress;
32372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.support.test.rule.ActivityTestRule;
33372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.support.test.runner.AndroidJUnit4;
34372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.support.text.emoji.util.TestString;
35372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.text.Spannable;
36372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.text.Spanned;
37372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.text.style.RelativeSizeSpan;
38372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.util.TypedValue;
39372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport android.widget.TextView;
40372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir
41372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport org.junit.Before;
42372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport org.junit.BeforeClass;
43372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport org.junit.Rule;
44372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport org.junit.Test;
45372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirimport org.junit.runner.RunWith;
46372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir
47372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir@LargeTest
48372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir@RunWith(AndroidJUnit4.class)
499546df94e6393de504f7ef8dc1b12a1f550c47a8Siyamed Sinir@SdkSuppress(minSdkVersion = 19)
509546df94e6393de504f7ef8dc1b12a1f550c47a8Siyamed Sinir@TargetApi(19)
51372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinirpublic class EmojiSpanInstrumentationTest {
52372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir
53372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir    @Rule
54372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir    public ActivityTestRule<TestActivity> mActivityRule = new ActivityTestRule<>(
55372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir            TestActivity.class);
56372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir    private Instrumentation mInstrumentation;
57372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir
58372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir    @BeforeClass
59372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir    public static void setupEmojiCompat() {
60372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        EmojiCompat.reset(TestConfigBuilder.config());
61372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir    }
62372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir
63372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir    @Before
64372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir    public void setup() {
65372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        mInstrumentation = InstrumentationRegistry.getInstrumentation();
66372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir    }
67372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir
68372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir    @Test
699546df94e6393de504f7ef8dc1b12a1f550c47a8Siyamed Sinir    public void testGetSize_withRelativeSizeSpan() {
70372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        final TestActivity activity = mActivityRule.getActivity();
71372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        final TextView textView = (TextView) activity.findViewById(
72372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir                android.support.text.emoji.test.R.id.text);
73372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir
74372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        // create a string with single codepoint emoji
75372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        final TestString string = new TestString(EMOJI_SINGLE_CODEPOINT).withPrefix().withSuffix();
76372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        final CharSequence charSequence = EmojiCompat.get().process(string.toString());
77372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        assertNotNull(charSequence);
78372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        assertThat(charSequence, hasEmojiCount(1));
79372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir
80372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        final Spannable spanned = (Spannable) charSequence;
81372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        final EmojiSpan[] spans = spanned.getSpans(0, charSequence.length(), EmojiSpan.class);
82372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        final EmojiSpan span = spans[0];
83372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir
84372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        // set text to the charSequence with the EmojiSpan
85372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        mInstrumentation.runOnMainSync(new Runnable() {
86372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir            @Override
87372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir            public void run() {
88372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir                textView.setText(charSequence);
89372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir            }
90372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        });
91372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        mInstrumentation.waitForIdleSync();
92372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir
93372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        // record height of the default span
94372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        final int defaultHeight = span.getHeight();
95372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir
96372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        // cover the charsequence with RelativeSizeSpan which will triple the size of the
97372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        // characters.
98372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        final float multiplier = 3.0f;
99372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        final RelativeSizeSpan sizeSpan = new RelativeSizeSpan(multiplier);
100372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        spanned.setSpan(sizeSpan, 0, charSequence.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
101372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        // set the new text
102372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        mInstrumentation.runOnMainSync(new Runnable() {
103372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir            @Override
104372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir            public void run() {
105372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir                textView.setText(charSequence);
106372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir            }
107372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        });
108372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        mInstrumentation.waitForIdleSync();
109372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir
110372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        // record the height measured after RelativeSizeSpan
111372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        final int heightWithRelativeSpan = span.getHeight();
112372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir
113372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        // accept 1sp error rate.
114372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        final float delta = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 1,
115372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir                mInstrumentation.getTargetContext().getResources().getDisplayMetrics());
116372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir        assertEquals(defaultHeight * 3, heightWithRelativeSpan, delta);
117372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir    }
118372c6556a754d4e7cdbeb883ab0ea5719285a68cSiyamed Sinir}
119