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 junit.framework.Assert.assertEquals; 1982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 2082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport static org.mockito.Matchers.any; 213dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinirimport static org.mockito.Matchers.eq; 2282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport static org.mockito.Mockito.mock; 233dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinirimport static org.mockito.Mockito.reset; 243dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinirimport static org.mockito.Mockito.times; 253dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinirimport static org.mockito.Mockito.verify; 2682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport static org.mockito.Mockito.when; 2782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 289546df94e6393de504f7ef8dc1b12a1f550c47a8Siyamed Sinirimport android.annotation.TargetApi; 293dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinirimport android.graphics.Canvas; 303dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinirimport android.graphics.Paint; 3182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport android.graphics.Paint.FontMetricsInt; 329546df94e6393de504f7ef8dc1b12a1f550c47a8Siyamed Sinirimport android.support.test.filters.SdkSuppress; 3382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport android.support.test.filters.SmallTest; 3482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport android.support.test.runner.AndroidJUnit4; 3582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport android.text.TextPaint; 3682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 3782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport org.junit.Before; 3882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport org.junit.Test; 3982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport org.junit.runner.RunWith; 4082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport org.mockito.invocation.InvocationOnMock; 4182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirimport org.mockito.stubbing.Answer; 4282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 4382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir@SmallTest 4482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir@RunWith(AndroidJUnit4.class) 459546df94e6393de504f7ef8dc1b12a1f550c47a8Siyamed Sinir@SdkSuppress(minSdkVersion = 19) 469546df94e6393de504f7ef8dc1b12a1f550c47a8Siyamed Sinir@TargetApi(19) 4782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinirpublic class EmojiSpanTest { 4882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 4982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir @Before 5082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public void setup() { 5182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir EmojiCompat.reset(TestConfigBuilder.config()); 5282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 5382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 5482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir @Test 559546df94e6393de504f7ef8dc1b12a1f550c47a8Siyamed Sinir public void testGetSize() { 5682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir final short dimensionX = 18; 5782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir final short dimensionY = 20; 5882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir final int fontHeight = 10; 5982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir final float expectedRatio = fontHeight * 1.0f / dimensionY; 6082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir final TextPaint paint = mock(TextPaint.class); 6182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 6282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir // mock TextPaint to return test font metrics 6382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir when(paint.getFontMetricsInt(any(FontMetricsInt.class))).thenAnswer(new Answer<Object>() { 6482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir @Override 6582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir public Object answer(InvocationOnMock invocation) throws Throwable { 6682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir final FontMetricsInt fontMetrics = (FontMetricsInt) invocation.getArguments()[0]; 6782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir fontMetrics.ascent = 0; 6882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir fontMetrics.descent = -fontHeight; 6982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir return null; 7082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 7182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir }); 7282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 7382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir final EmojiMetadata metadata = mock(EmojiMetadata.class); 7482d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir when(metadata.getWidth()).thenReturn(dimensionX); 7582d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir when(metadata.getHeight()).thenReturn(dimensionY); 7682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir final EmojiSpan span = new TypefaceEmojiSpan(metadata); 7782d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir 7882d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir final int resultSize = span.getSize(paint, "", 0, 0, null); 7982d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir assertEquals((int) (dimensionX * expectedRatio), resultSize); 8082d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir assertEquals(expectedRatio, span.getRatio()); 8182d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir assertEquals((int) (dimensionX * expectedRatio), span.getWidth()); 8282d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir assertEquals((int) (dimensionY * expectedRatio), span.getHeight()); 8382d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir } 843dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir 853dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir @Test 863dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir public void testBackgroundIndicator() { 873dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir // control the size of the emoji span 883dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir final EmojiMetadata metadata = mock(EmojiMetadata.class); 893dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir when(metadata.getWidth()).thenReturn((short) 10); 903dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir when(metadata.getHeight()).thenReturn((short) 10); 913dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir 923dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir final EmojiSpan span = new TypefaceEmojiSpan(metadata); 933dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir final int spanWidth = span.getSize(mock(Paint.class), "", 0, 0, null); 943dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir // prepare parameters for draw() call 953dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir final Canvas canvas = mock(Canvas.class); 963dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir final float x = 10; 973dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir final int top = 15; 983dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir final int y = 20; 993dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir final int bottom = 30; 1003dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir 1013dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir // verify the case where indicators are disabled 1023dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir EmojiCompat.reset(TestConfigBuilder.config().setEmojiSpanIndicatorEnabled(false)); 1033dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir span.draw(canvas, "a", 0 /*start*/, 1 /*end*/, x, top, y, bottom, mock(Paint.class)); 1043dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir 1053dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir verify(canvas, times(0)).drawRect(eq(x), eq((float) top), eq(x + spanWidth), 1063dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir eq((float) bottom), any(Paint.class)); 1073dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir 1083dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir // verify the case where indicators are enabled 1093dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir EmojiCompat.reset(TestConfigBuilder.config().setEmojiSpanIndicatorEnabled(true)); 1103dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir reset(canvas); 1113dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir span.draw(canvas, "a", 0 /*start*/, 1 /*end*/, x, top, y, bottom, mock(Paint.class)); 1123dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir 1133dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir verify(canvas, times(1)).drawRect(eq(x), eq((float) top), eq(x + spanWidth), 1143dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir eq((float) bottom), any(Paint.class)); 1153dc8b512ac3a1a8fb0b7b2618246d50fd2f3367bSiyamed Sinir } 11682d2cc1cf0c2bfdd5121e6d6913dfe9fcaacf439Siyamed Sinir} 117