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 */
16package android.support.text.emoji;
17
18import static android.support.text.emoji.util.EmojiMatcher.hasEmojiAt;
19import static android.support.text.emoji.util.EmojiMatcher.hasEmojiCount;
20
21import static junit.framework.TestCase.assertTrue;
22
23import static org.junit.Assert.assertThat;
24
25import android.annotation.TargetApi;
26import android.content.Context;
27import android.support.test.InstrumentationRegistry;
28import android.support.test.filters.SdkSuppress;
29import android.support.test.filters.SmallTest;
30import android.support.text.emoji.util.TestString;
31
32import org.junit.BeforeClass;
33import org.junit.Test;
34import org.junit.runner.RunWith;
35import org.junit.runners.Parameterized;
36
37import java.io.BufferedReader;
38import java.io.IOException;
39import java.io.InputStream;
40import java.io.InputStreamReader;
41import java.util.ArrayList;
42import java.util.Collection;
43
44/**
45 * Reads raw/allemojis.txt which includes all the emojis known to human kind and tests that
46 * EmojiCompat creates EmojiSpans for each one of them.
47 */
48@SmallTest
49@RunWith(Parameterized.class)
50@SdkSuppress(minSdkVersion = 19)
51@TargetApi(19)
52public class AllEmojisTest {
53
54    /**
55     * String representation for a single emoji
56     */
57    private String mString;
58
59    /**
60     * Codepoints of emoji for better assert error message.
61     */
62    private String mCodepoints;
63
64    @BeforeClass
65    public static void setup() {
66        EmojiCompat.reset(TestConfigBuilder.config());
67    }
68
69    @Parameterized.Parameters
70    public static Collection<Object[]> data() throws IOException {
71        final Context context = InstrumentationRegistry.getTargetContext();
72        final InputStream inputStream = context.getAssets().open("emojis.txt");
73        try {
74            final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
75            final Collection<Object[]> data = new ArrayList<>();
76            final StringBuilder stringBuilder = new StringBuilder();
77            final StringBuilder codePointsBuilder = new StringBuilder();
78
79            String s;
80            while ((s = reader.readLine()) != null) {
81                s = s.trim();
82                // pass comments
83                if (s.isEmpty() || s.startsWith("#")) continue;
84
85                stringBuilder.setLength(0);
86                codePointsBuilder.setLength(0);
87
88                // emoji codepoints are space separated: i.e. 0x1f1e6 0x1f1e8
89                final String[] split = s.split(" ");
90
91                for (int index = 0; index < split.length; index++) {
92                    final String part = split[index].trim();
93                    codePointsBuilder.append(part);
94                    codePointsBuilder.append(",");
95                    stringBuilder.append(Character.toChars(Integer.parseInt(part, 16)));
96                }
97                data.add(new Object[]{stringBuilder.toString(), codePointsBuilder.toString()});
98            }
99
100            return data;
101        } finally {
102            inputStream.close();
103        }
104
105    }
106
107    public AllEmojisTest(String string, String codepoints) {
108        mString = string;
109        mCodepoints = codepoints;
110    }
111
112    @Test
113    public void testEmoji() {
114        assertTrue("EmojiCompat should have emoji: " + mCodepoints,
115                EmojiCompat.get().hasEmojiGlyph(mString));
116        assertEmojiCompatAddsEmoji(mString);
117    }
118
119    private void assertEmojiCompatAddsEmoji(final String str) {
120        TestString string = new TestString(str);
121        CharSequence sequence = EmojiCompat.get().process(string.toString());
122        assertThat(sequence, hasEmojiCount(1));
123        assertThat(sequence, hasEmojiAt(string.emojiStartIndex(), string.emojiEndIndex()));
124
125        // case where Emoji is in the middle of string
126        string = new TestString(str).withPrefix().withSuffix();
127        sequence = EmojiCompat.get().process(string.toString());
128        assertThat(sequence, hasEmojiCount(1));
129        assertThat(sequence, hasEmojiAt(string.emojiStartIndex(), string.emojiEndIndex()));
130
131        // case where Emoji is at the end of string
132        string = new TestString(str).withSuffix();
133        sequence = EmojiCompat.get().process(string.toString());
134        assertThat(sequence, hasEmojiCount(1));
135        assertThat(sequence, hasEmojiAt(string.emojiStartIndex(), string.emojiEndIndex()));
136    }
137
138}
139