TypefaceCompatTest.java revision c357691d3aae8bb2913941267188e12594d5ca80
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 */ 16 17package android.support.v4.graphics; 18 19import static android.content.res.AssetManager.ACCESS_BUFFER; 20 21import static org.junit.Assert.assertEquals; 22import static org.junit.Assert.assertNotNull; 23import static org.junit.Assert.assertTrue; 24import static org.mockito.Mockito.mock; 25import static org.mockito.Mockito.verify; 26 27import android.graphics.Typeface; 28import android.os.Build; 29import android.os.Bundle; 30import android.os.ParcelFileDescriptor; 31import android.support.test.filters.SmallTest; 32import android.support.test.runner.AndroidJUnit4; 33import android.support.v4.BaseInstrumentationTestCase; 34import android.support.v4.app.TestSupportActivity; 35import android.support.v4.graphics.TypefaceCompat.FontRequestCallback; 36import android.support.v4.graphics.fonts.FontRequest; 37import android.support.v4.graphics.fonts.FontResult; 38import android.support.v4.provider.FontsContractCompat; 39import android.util.Base64; 40 41import org.junit.Before; 42import org.junit.Test; 43import org.junit.runner.RunWith; 44 45import java.io.File; 46import java.io.FileOutputStream; 47import java.io.IOException; 48import java.io.InputStream; 49import java.util.ArrayList; 50import java.util.Arrays; 51import java.util.List; 52 53/** 54 * Tests for {@link TypefaceCompatBaseImpl}. 55 */ 56@SmallTest 57@RunWith(AndroidJUnit4.class) 58public class TypefaceCompatTest extends BaseInstrumentationTestCase<TestSupportActivity> { 59 private static final String TEST_FONT_FILE = "fonts/samplefont1.ttf"; 60 private static final String CACHE_FILE = "cachedfont.ttf"; 61 private static final String PROVIDER = "com.test.fontprovider.authority"; 62 private static final String QUERY_CACHED = "query_cached"; 63 private static final String QUERY = "query"; 64 private static final String PACKAGE = "com.test.fontprovider.package"; 65 private static final byte[] BYTE_ARRAY = 66 Base64.decode("e04fd020ea3a6910a2d808002b30", Base64.DEFAULT); 67 private static final List<List<byte[]>> CERTS = Arrays.asList(Arrays.asList(BYTE_ARRAY)); 68 69 private TypefaceCompatBaseImpl mCompat; 70 71 public TypefaceCompatTest() { 72 super(TestSupportActivity.class); 73 } 74 75 @Before 76 public void setup() { 77 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 78 mCompat = new TypefaceCompatApi24Impl(mActivityTestRule.getActivity()); 79 } else { 80 mCompat = new TypefaceCompatBaseImpl(mActivityTestRule.getActivity()); 81 } 82 TypefaceCompatBaseImpl.putInCache(PROVIDER, QUERY_CACHED, Typeface.MONOSPACE); 83 } 84 85 @Test 86 public void testReceiveResult_cachedResult() { 87 FontRequestCallback callback = mock(FontRequestCallback.class); 88 89 mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY_CACHED, CERTS), 90 callback, 0, null); 91 92 verify(callback).onTypefaceRetrieved(Typeface.MONOSPACE); 93 } 94 95 @Test 96 public void testReceiveResult_resultCodeProviderNotFound() { 97 FontRequestCallback callback = mock(FontRequestCallback.class); 98 99 mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY, CERTS), callback, 100 FontsContractCompat.RESULT_CODE_PROVIDER_NOT_FOUND, null); 101 102 verify(callback).onTypefaceRequestFailed( 103 FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND); 104 } 105 106 @Test 107 public void testReceiveResult_resultCodeFontNotFound() { 108 FontRequestCallback callback = mock(FontRequestCallback.class); 109 110 mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY, CERTS), callback, 111 FontsContractCompat.Columns.RESULT_CODE_FONT_NOT_FOUND, null); 112 113 verify(callback).onTypefaceRequestFailed( 114 FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND); 115 } 116 117 @Test 118 public void testReceiveResult_nullBundle() { 119 FontRequestCallback callback = mock(FontRequestCallback.class); 120 121 mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY, CERTS), callback, 122 FontsContractCompat.Columns.RESULT_CODE_OK, null); 123 124 verify(callback).onTypefaceRequestFailed( 125 FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND); 126 } 127 128 @Test 129 public void testReceiveResult_nullResult() { 130 FontRequestCallback callback = mock(FontRequestCallback.class); 131 132 mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY, CERTS), callback, 133 FontsContractCompat.Columns.RESULT_CODE_OK, new Bundle()); 134 135 verify(callback).onTypefaceRequestFailed( 136 FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND); 137 } 138 139 @Test 140 public void testReceiveResult_emptyResult() { 141 FontRequestCallback callback = mock(FontRequestCallback.class); 142 Bundle bundle = new Bundle(); 143 bundle.putParcelableArrayList( 144 FontsContractCompat.PARCEL_FONT_RESULTS, new ArrayList<FontResult>()); 145 146 mCompat.receiveResult(new FontRequest(PROVIDER, PACKAGE, QUERY, CERTS), callback, 147 FontsContractCompat.Columns.RESULT_CODE_OK, bundle); 148 149 verify(callback).onTypefaceRequestFailed( 150 FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND); 151 } 152 153 @Test 154 public void testTypefaceRequestFailureConstantsAreInSync() { 155 // Error codes from the provider are positive numbers and are in sync 156 assertEquals(FontsContractCompat.Columns.RESULT_CODE_FONT_NOT_FOUND, 157 TypefaceCompat.FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND); 158 assertEquals(FontsContractCompat.Columns.RESULT_CODE_FONT_UNAVAILABLE, 159 TypefaceCompat.FontRequestCallback.FAIL_REASON_FONT_UNAVAILABLE); 160 assertEquals(FontsContractCompat.Columns.RESULT_CODE_MALFORMED_QUERY, 161 TypefaceCompat.FontRequestCallback.FAIL_REASON_MALFORMED_QUERY); 162 163 // Internal errors are negative 164 assertTrue(0 > TypefaceCompat.FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND); 165 assertTrue(0 > TypefaceCompat.FontRequestCallback.FAIL_REASON_WRONG_CERTIFICATES); 166 assertTrue(0 > TypefaceCompat.FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR); 167 } 168 169 private File loadFont() { 170 File cacheFile = new File(mActivityTestRule.getActivity().getCacheDir(), CACHE_FILE); 171 try { 172 copyToCacheFile(TEST_FONT_FILE, cacheFile); 173 return cacheFile; 174 } catch (IOException e) { 175 e.printStackTrace(); 176 } 177 return null; 178 } 179 180 private void copyToCacheFile(final String assetPath, final File cacheFile) 181 throws IOException { 182 InputStream is = null; 183 FileOutputStream fos = null; 184 try { 185 is = mActivityTestRule.getActivity().getAssets().open(assetPath, ACCESS_BUFFER); 186 fos = new FileOutputStream(cacheFile, false); 187 byte[] buffer = new byte[1024]; 188 int readLen; 189 while ((readLen = is.read(buffer)) != -1) { 190 fos.write(buffer, 0, readLen); 191 } 192 } finally { 193 if (is != null) { 194 is.close(); 195 } 196 if (fos != null) { 197 fos.close(); 198 } 199 } 200 } 201 202 @Test 203 public void testCreateTypeface() throws IOException, InterruptedException { 204 File file = loadFont(); 205 ParcelFileDescriptor pfd = 206 ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); 207 try { 208 FontResult result = new FontResult(pfd, 0, null, 400, false /* italic */); 209 Typeface typeface = mCompat.createTypeface(Arrays.asList(result)); 210 211 assertNotNull(typeface); 212 } finally { 213 if (file != null) { 214 file.delete(); 215 } 216 if (pfd != null) { 217 pfd.close(); 218 } 219 } 220 } 221} 222