182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir/* 282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Copyright (C) 2017 The Android Open Source Project 382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * 482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Licensed under the Apache License, Version 2.0 (the "License"); 582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * you may not use this file except in compliance with the License. 682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * You may obtain a copy of the License at 782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * 882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * http://www.apache.org/licenses/LICENSE-2.0 982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * 1082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Unless required by applicable law or agreed to in writing, software 1182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * distributed under the License is distributed on an "AS IS" BASIS, 1282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * See the License for the specific language governing permissions and 1482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * limitations under the License. 1582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 1682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirpackage android.support.text.emoji; 1782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 1882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport static android.support.text.emoji.util.EmojiMatcher.hasEmojiAt; 1982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport static android.support.text.emoji.util.EmojiMatcher.hasEmojiCount; 2082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 2182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport static junit.framework.TestCase.assertTrue; 2282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 2382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport static org.junit.Assert.assertThat; 2482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 259546df94e6393de504f7ef8dc1b12a1f550c47a8Siyamed Sinirimport android.annotation.TargetApi; 2682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport android.content.Context; 2782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport android.support.test.InstrumentationRegistry; 289546df94e6393de504f7ef8dc1b12a1f550c47a8Siyamed Sinirimport android.support.test.filters.SdkSuppress; 2982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport android.support.test.filters.SmallTest; 3082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport android.support.text.emoji.util.TestString; 3182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 3282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport org.junit.BeforeClass; 3382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport org.junit.Test; 3482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport org.junit.runner.RunWith; 3582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport org.junit.runners.Parameterized; 3682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 3782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport java.io.BufferedReader; 3882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport java.io.IOException; 3982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport java.io.InputStream; 4082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport java.io.InputStreamReader; 4182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport java.util.ArrayList; 4282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport java.util.Collection; 4382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 4482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir/** 4582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Reads raw/allemojis.txt which includes all the emojis known to human kind and tests that 4682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * EmojiCompat creates EmojiSpans for each one of them. 4782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 4882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir@SmallTest 4982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir@RunWith(Parameterized.class) 509546df94e6393de504f7ef8dc1b12a1f550c47a8Siyamed Sinir@SdkSuppress(minSdkVersion = 19) 519546df94e6393de504f7ef8dc1b12a1f550c47a8Siyamed Sinir@TargetApi(19) 5282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirpublic class AllEmojisTest { 5382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 5482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 5582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * String representation for a single emoji 5682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 5782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir private String mString; 5882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 5982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir /** 6082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir * Codepoints of emoji for better assert error message. 6182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir */ 6282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir private String mCodepoints; 6382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 6482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir @BeforeClass 6582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public static void setup() { 6682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir EmojiCompat.reset(TestConfigBuilder.config()); 6782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 6882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 6982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir @Parameterized.Parameters 70b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir public static Collection<Object[]> data() throws IOException { 7182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir final Context context = InstrumentationRegistry.getTargetContext(); 72176b7a517ad28a8cffc8cc3307b6ce2c42a36cc9Siyamed Sinir final InputStream inputStream = context.getAssets().open("emojis.txt"); 7382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir try { 74b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); 75b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir final Collection<Object[]> data = new ArrayList<>(); 76b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir final StringBuilder stringBuilder = new StringBuilder(); 77b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir final StringBuilder codePointsBuilder = new StringBuilder(); 78b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir 7982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir String s; 8082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir while ((s = reader.readLine()) != null) { 81b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir s = s.trim(); 82b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir // pass comments 83b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir if (s.isEmpty() || s.startsWith("#")) continue; 84b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir 8582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir stringBuilder.setLength(0); 8682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir codePointsBuilder.setLength(0); 8782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 8882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir // emoji codepoints are space separated: i.e. 0x1f1e6 0x1f1e8 8982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir final String[] split = s.split(" "); 9082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 9182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir for (int index = 0; index < split.length; index++) { 92b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir final String part = split[index].trim(); 93b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir codePointsBuilder.append(part); 9482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir codePointsBuilder.append(","); 95b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir stringBuilder.append(Character.toChars(Integer.parseInt(part, 16))); 9682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 9782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir data.add(new Object[]{stringBuilder.toString(), codePointsBuilder.toString()}); 9882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 99b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir 100b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir return data; 101b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir } finally { 102b7b27782ff7589608ed7de38634adc846665cecbSiyamed Sinir inputStream.close(); 10382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 10482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 10582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 10682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 10782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public AllEmojisTest(String string, String codepoints) { 10882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir mString = string; 10982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir mCodepoints = codepoints; 11082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 11182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 11282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir @Test 11382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public void testEmoji() { 11482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir assertTrue("EmojiCompat should have emoji: " + mCodepoints, 11582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir EmojiCompat.get().hasEmojiGlyph(mString)); 11682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir assertEmojiCompatAddsEmoji(mString); 11782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 11882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 11982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir private void assertEmojiCompatAddsEmoji(final String str) { 12082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir TestString string = new TestString(str); 12182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir CharSequence sequence = EmojiCompat.get().process(string.toString()); 12282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir assertThat(sequence, hasEmojiCount(1)); 12382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir assertThat(sequence, hasEmojiAt(string.emojiStartIndex(), string.emojiEndIndex())); 12482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 12582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir // case where Emoji is in the middle of string 12682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir string = new TestString(str).withPrefix().withSuffix(); 12782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir sequence = EmojiCompat.get().process(string.toString()); 12882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir assertThat(sequence, hasEmojiCount(1)); 12982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir assertThat(sequence, hasEmojiAt(string.emojiStartIndex(), string.emojiEndIndex())); 13082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 13182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir // case where Emoji is at the end of string 13282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir string = new TestString(str).withSuffix(); 13382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir sequence = EmojiCompat.get().process(string.toString()); 13482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir assertThat(sequence, hasEmojiCount(1)); 13582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir assertThat(sequence, hasEmojiAt(string.emojiStartIndex(), string.emojiEndIndex())); 13682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 13782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 13882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir} 139