1/* 2 * Copyright (C) 2011 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 com.android.volley.toolbox; 18 19import android.graphics.Bitmap; 20import android.graphics.Bitmap.Config; 21import android.widget.ImageView; 22import android.widget.ImageView.ScaleType; 23import com.android.volley.NetworkResponse; 24import com.android.volley.Response; 25import org.junit.Test; 26import org.junit.runner.RunWith; 27import org.robolectric.RobolectricTestRunner; 28import org.robolectric.shadows.ShadowBitmapFactory; 29 30import java.io.ByteArrayOutputStream; 31import java.io.IOException; 32import java.io.InputStream; 33 34import static org.junit.Assert.*; 35 36@RunWith(RobolectricTestRunner.class) 37public class ImageRequestTest { 38 39 @Test public void parseNetworkResponse_resizing() throws Exception { 40 // This is a horrible hack but Robolectric doesn't have a way to provide 41 // width and height hints for decodeByteArray. It works because the byte array 42 // "file:fake" is ASCII encodable and thus the name in Robolectric's fake 43 // bitmap creator survives as-is, and provideWidthAndHeightHints puts 44 // "file:" + name in its lookaside map. I write all this because it will 45 // probably break mysteriously at some point and I feel terrible about your 46 // having to debug it. 47 byte[] jpegBytes = "file:fake".getBytes(); 48 ShadowBitmapFactory.provideWidthAndHeightHints("fake", 1024, 500); 49 NetworkResponse jpeg = new NetworkResponse(jpegBytes); 50 51 // Scale the image uniformly (maintain the image's aspect ratio) so that 52 // both dimensions (width and height) of the image will be equal to or 53 // less than the corresponding dimension of the view. 54 ScaleType scalteType = ScaleType.CENTER_INSIDE; 55 56 // Exact sizes 57 verifyResize(jpeg, 512, 250, scalteType, 512, 250); // exactly half 58 verifyResize(jpeg, 511, 249, scalteType, 509, 249); // just under half 59 verifyResize(jpeg, 1080, 500, scalteType, 1024, 500); // larger 60 verifyResize(jpeg, 500, 500, scalteType, 500, 244); // keep same ratio 61 62 // Specify only width, preserve aspect ratio 63 verifyResize(jpeg, 512, 0, scalteType, 512, 250); 64 verifyResize(jpeg, 800, 0, scalteType, 800, 390); 65 verifyResize(jpeg, 1024, 0, scalteType, 1024, 500); 66 67 // Specify only height, preserve aspect ratio 68 verifyResize(jpeg, 0, 250, scalteType, 512, 250); 69 verifyResize(jpeg, 0, 391, scalteType, 800, 391); 70 verifyResize(jpeg, 0, 500, scalteType, 1024, 500); 71 72 // No resize 73 verifyResize(jpeg, 0, 0, scalteType, 1024, 500); 74 75 76 // Scale the image uniformly (maintain the image's aspect ratio) so that 77 // both dimensions (width and height) of the image will be equal to or 78 // larger than the corresponding dimension of the view. 79 scalteType = ScaleType.CENTER_CROP; 80 81 // Exact sizes 82 verifyResize(jpeg, 512, 250, scalteType, 512, 250); 83 verifyResize(jpeg, 511, 249, scalteType, 511, 249); 84 verifyResize(jpeg, 1080, 500, scalteType, 1024, 500); 85 verifyResize(jpeg, 500, 500, scalteType, 1024, 500); 86 87 // Specify only width 88 verifyResize(jpeg, 512, 0, scalteType, 512, 250); 89 verifyResize(jpeg, 800, 0, scalteType, 800, 390); 90 verifyResize(jpeg, 1024, 0, scalteType, 1024, 500); 91 92 // Specify only height 93 verifyResize(jpeg, 0, 250, scalteType, 512, 250); 94 verifyResize(jpeg, 0, 391, scalteType, 800, 391); 95 verifyResize(jpeg, 0, 500, scalteType, 1024, 500); 96 97 // No resize 98 verifyResize(jpeg, 0, 0, scalteType, 1024, 500); 99 100 101 // Scale in X and Y independently, so that src matches dst exactly. This 102 // may change the aspect ratio of the src. 103 scalteType = ScaleType.FIT_XY; 104 105 // Exact sizes 106 verifyResize(jpeg, 512, 250, scalteType, 512, 250); 107 verifyResize(jpeg, 511, 249, scalteType, 511, 249); 108 verifyResize(jpeg, 1080, 500, scalteType, 1024, 500); 109 verifyResize(jpeg, 500, 500, scalteType, 500, 500); 110 111 // Specify only width 112 verifyResize(jpeg, 512, 0, scalteType, 512, 500); 113 verifyResize(jpeg, 800, 0, scalteType, 800, 500); 114 verifyResize(jpeg, 1024, 0, scalteType, 1024, 500); 115 116 // Specify only height 117 verifyResize(jpeg, 0, 250, scalteType, 1024, 250); 118 verifyResize(jpeg, 0, 391, scalteType, 1024, 391); 119 verifyResize(jpeg, 0, 500, scalteType, 1024, 500); 120 121 // No resize 122 verifyResize(jpeg, 0, 0, scalteType, 1024, 500); 123 } 124 125 private void verifyResize(NetworkResponse networkResponse, int maxWidth, int maxHeight, 126 ScaleType scaleType, int expectedWidth, int expectedHeight) { 127 ImageRequest request = new ImageRequest("", null, maxWidth, maxHeight, scaleType, 128 Config.RGB_565, null); 129 Response<Bitmap> response = request.parseNetworkResponse(networkResponse); 130 assertNotNull(response); 131 assertTrue(response.isSuccess()); 132 Bitmap bitmap = response.result; 133 assertNotNull(bitmap); 134 assertEquals(expectedWidth, bitmap.getWidth()); 135 assertEquals(expectedHeight, bitmap.getHeight()); 136 } 137 138 @Test public void findBestSampleSize() { 139 // desired == actual == 1 140 assertEquals(1, ImageRequest.findBestSampleSize(100, 150, 100, 150)); 141 142 // exactly half == 2 143 assertEquals(2, ImageRequest.findBestSampleSize(280, 160, 140, 80)); 144 145 // just over half == 1 146 assertEquals(1, ImageRequest.findBestSampleSize(1000, 800, 501, 401)); 147 148 // just under 1/4 == 4 149 assertEquals(4, ImageRequest.findBestSampleSize(100, 200, 24, 50)); 150 } 151 152 private static byte[] readInputStream(InputStream in) throws IOException { 153 ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 154 byte[] buffer = new byte[1024]; 155 int count; 156 while ((count = in.read(buffer)) != -1) { 157 bytes.write(buffer, 0, count); 158 } 159 in.close(); 160 return bytes.toByteArray(); 161 } 162 163 @Test 164 public void publicMethods() throws Exception { 165 // Catch-all test to find API-breaking changes. 166 assertNotNull(ImageRequest.class.getConstructor(String.class, Response.Listener.class, 167 int.class, int.class, Bitmap.Config.class, Response.ErrorListener.class)); 168 assertNotNull(ImageRequest.class.getConstructor(String.class, Response.Listener.class, 169 int.class, int.class, ImageView.ScaleType.class, Bitmap.Config.class, 170 Response.ErrorListener.class)); 171 } 172} 173