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