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