diff options
Diffstat (limited to 'src/test/java/com/android/volley/toolbox')
9 files changed, 1041 insertions, 0 deletions
diff --git a/src/test/java/com/android/volley/toolbox/BasicNetworkTest.java b/src/test/java/com/android/volley/toolbox/BasicNetworkTest.java new file mode 100644 index 0000000..89718b1 --- /dev/null +++ b/src/test/java/com/android/volley/toolbox/BasicNetworkTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.volley.toolbox; + +import com.android.volley.NetworkResponse; +import com.android.volley.Request; +import com.android.volley.Response; +import com.android.volley.mock.MockHttpStack; + +import org.apache.http.ProtocolVersion; +import org.apache.http.entity.StringEntity; +import org.apache.http.message.BasicHttpResponse; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +import static org.junit.Assert.*; + +import java.util.HashMap; +import java.util.Map; + +@RunWith(RobolectricTestRunner.class) +public class BasicNetworkTest { + + @Test public void headersAndPostParams() throws Exception { + MockHttpStack mockHttpStack = new MockHttpStack(); + BasicHttpResponse fakeResponse = new BasicHttpResponse(new ProtocolVersion("HTTP", 1, 1), + 200, "OK"); + fakeResponse.setEntity(new StringEntity("foobar")); + mockHttpStack.setResponseToReturn(fakeResponse); + BasicNetwork httpNetwork = new BasicNetwork(mockHttpStack); + Request<String> request = new Request<String>(Request.Method.GET, "http://foo", null) { + + @Override + protected Response<String> parseNetworkResponse(NetworkResponse response) { + return null; + } + + @Override + protected void deliverResponse(String response) { + } + + @Override + public Map<String, String> getHeaders() { + Map<String, String> result = new HashMap<String, String>(); + result.put("requestheader", "foo"); + return result; + } + + @Override + public Map<String, String> getParams() { + Map<String, String> result = new HashMap<String, String>(); + result.put("requestpost", "foo"); + return result; + } + }; + httpNetwork.performRequest(request); + assertEquals("foo", mockHttpStack.getLastHeaders().get("requestheader")); + assertEquals("requestpost=foo&", new String(mockHttpStack.getLastPostBody())); + } +} diff --git a/src/test/java/com/android/volley/toolbox/ByteArrayPoolTest.java b/src/test/java/com/android/volley/toolbox/ByteArrayPoolTest.java new file mode 100644 index 0000000..661e994 --- /dev/null +++ b/src/test/java/com/android/volley/toolbox/ByteArrayPoolTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.volley.toolbox; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +public class ByteArrayPoolTest { + @Test public void reusesBuffer() { + ByteArrayPool pool = new ByteArrayPool(32); + + byte[] buf1 = pool.getBuf(16); + byte[] buf2 = pool.getBuf(16); + + pool.returnBuf(buf1); + pool.returnBuf(buf2); + + byte[] buf3 = pool.getBuf(16); + byte[] buf4 = pool.getBuf(16); + assertTrue(buf3 == buf1 || buf3 == buf2); + assertTrue(buf4 == buf1 || buf4 == buf2); + assertTrue(buf3 != buf4); + } + + @Test public void obeysSizeLimit() { + ByteArrayPool pool = new ByteArrayPool(32); + + byte[] buf1 = pool.getBuf(16); + byte[] buf2 = pool.getBuf(16); + byte[] buf3 = pool.getBuf(16); + + pool.returnBuf(buf1); + pool.returnBuf(buf2); + pool.returnBuf(buf3); + + byte[] buf4 = pool.getBuf(16); + byte[] buf5 = pool.getBuf(16); + byte[] buf6 = pool.getBuf(16); + + assertTrue(buf4 == buf2 || buf4 == buf3); + assertTrue(buf5 == buf2 || buf5 == buf3); + assertTrue(buf4 != buf5); + assertTrue(buf6 != buf1 && buf6 != buf2 && buf6 != buf3); + } + + @Test public void returnsBufferWithRightSize() { + ByteArrayPool pool = new ByteArrayPool(32); + + byte[] buf1 = pool.getBuf(16); + pool.returnBuf(buf1); + + byte[] buf2 = pool.getBuf(17); + assertNotSame(buf2, buf1); + + byte[] buf3 = pool.getBuf(15); + assertSame(buf3, buf1); + } +} diff --git a/src/test/java/com/android/volley/toolbox/DiskBasedCacheTest.java b/src/test/java/com/android/volley/toolbox/DiskBasedCacheTest.java new file mode 100644 index 0000000..4b2955d --- /dev/null +++ b/src/test/java/com/android/volley/toolbox/DiskBasedCacheTest.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.volley.toolbox; + +import com.android.volley.Cache; +import com.android.volley.toolbox.DiskBasedCache.CacheHeader; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; + +public class DiskBasedCacheTest { + + // Simple end-to-end serialize/deserialize test. + @Test public void cacheHeaderSerialization() throws Exception { + Cache.Entry e = new Cache.Entry(); + e.data = new byte[8]; + e.serverDate = 1234567L; + e.ttl = 9876543L; + e.softTtl = 8765432L; + e.etag = "etag"; + e.responseHeaders = new HashMap<String, String>(); + e.responseHeaders.put("fruit", "banana"); + + CacheHeader first = new CacheHeader("my-magical-key", e); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + first.writeHeader(baos); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + CacheHeader second = CacheHeader.readHeader(bais); + + assertEquals(first.key, second.key); + assertEquals(first.serverDate, second.serverDate); + assertEquals(first.ttl, second.ttl); + assertEquals(first.softTtl, second.softTtl); + assertEquals(first.etag, second.etag); + assertEquals(first.responseHeaders, second.responseHeaders); + } + + @Test public void serializeInt() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DiskBasedCache.writeInt(baos, 0); + DiskBasedCache.writeInt(baos, 19791214); + DiskBasedCache.writeInt(baos, -20050711); + DiskBasedCache.writeInt(baos, Integer.MIN_VALUE); + DiskBasedCache.writeInt(baos, Integer.MAX_VALUE); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + assertEquals(DiskBasedCache.readInt(bais), 0); + assertEquals(DiskBasedCache.readInt(bais), 19791214); + assertEquals(DiskBasedCache.readInt(bais), -20050711); + assertEquals(DiskBasedCache.readInt(bais), Integer.MIN_VALUE); + assertEquals(DiskBasedCache.readInt(bais), Integer.MAX_VALUE); + } + + @Test public void serializeLong() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DiskBasedCache.writeLong(baos, 0); + DiskBasedCache.writeLong(baos, 31337); + DiskBasedCache.writeLong(baos, -4160); + DiskBasedCache.writeLong(baos, 4295032832L); + DiskBasedCache.writeLong(baos, -4314824046L); + DiskBasedCache.writeLong(baos, Long.MIN_VALUE); + DiskBasedCache.writeLong(baos, Long.MAX_VALUE); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + assertEquals(DiskBasedCache.readLong(bais), 0); + assertEquals(DiskBasedCache.readLong(bais), 31337); + assertEquals(DiskBasedCache.readLong(bais), -4160); + assertEquals(DiskBasedCache.readLong(bais), 4295032832L); + assertEquals(DiskBasedCache.readLong(bais), -4314824046L); + assertEquals(DiskBasedCache.readLong(bais), Long.MIN_VALUE); + assertEquals(DiskBasedCache.readLong(bais), Long.MAX_VALUE); + } + + @Test public void serializeString() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DiskBasedCache.writeString(baos, ""); + DiskBasedCache.writeString(baos, "This is a string."); + DiskBasedCache.writeString(baos, "ファイカス"); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + assertEquals(DiskBasedCache.readString(bais), ""); + assertEquals(DiskBasedCache.readString(bais), "This is a string."); + assertEquals(DiskBasedCache.readString(bais), "ファイカス"); + } + + @Test public void serializeMap() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + Map<String, String> empty = new HashMap<String, String>(); + DiskBasedCache.writeStringStringMap(empty, baos); + DiskBasedCache.writeStringStringMap(null, baos); + Map<String, String> twoThings = new HashMap<String, String>(); + twoThings.put("first", "thing"); + twoThings.put("second", "item"); + DiskBasedCache.writeStringStringMap(twoThings, baos); + Map<String, String> emptyKey = new HashMap<String, String>(); + emptyKey.put("", "value"); + DiskBasedCache.writeStringStringMap(emptyKey, baos); + Map<String, String> emptyValue = new HashMap<String, String>(); + emptyValue.put("key", ""); + DiskBasedCache.writeStringStringMap(emptyValue, baos); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + assertEquals(DiskBasedCache.readStringStringMap(bais), empty); + assertEquals(DiskBasedCache.readStringStringMap(bais), empty); // null reads back empty + assertEquals(DiskBasedCache.readStringStringMap(bais), twoThings); + assertEquals(DiskBasedCache.readStringStringMap(bais), emptyKey); + assertEquals(DiskBasedCache.readStringStringMap(bais), emptyValue); + } +} diff --git a/src/test/java/com/android/volley/toolbox/HttpClientStackTest.java b/src/test/java/com/android/volley/toolbox/HttpClientStackTest.java new file mode 100644 index 0000000..0c417d4 --- /dev/null +++ b/src/test/java/com/android/volley/toolbox/HttpClientStackTest.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.volley.toolbox; + +import com.android.volley.Request.Method; +import com.android.volley.mock.TestRequest; +import com.android.volley.toolbox.HttpClientStack.HttpPatch; + +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpHead; +import org.apache.http.client.methods.HttpOptions; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpTrace; +import org.apache.http.client.methods.HttpUriRequest; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +import static org.junit.Assert.*; + +@RunWith(RobolectricTestRunner.class) +public class HttpClientStackTest { + + @Test public void createDeprecatedGetRequest() throws Exception { + TestRequest.DeprecatedGet request = new TestRequest.DeprecatedGet(); + assertEquals(request.getMethod(), Method.DEPRECATED_GET_OR_POST); + + HttpUriRequest httpRequest = HttpClientStack.createHttpRequest(request, null); + assertTrue(httpRequest instanceof HttpGet); + } + + @Test public void createDeprecatedPostRequest() throws Exception { + TestRequest.DeprecatedPost request = new TestRequest.DeprecatedPost(); + assertEquals(request.getMethod(), Method.DEPRECATED_GET_OR_POST); + + HttpUriRequest httpRequest = HttpClientStack.createHttpRequest(request, null); + assertTrue(httpRequest instanceof HttpPost); + } + + @Test public void createGetRequest() throws Exception { + TestRequest.Get request = new TestRequest.Get(); + assertEquals(request.getMethod(), Method.GET); + + HttpUriRequest httpRequest = HttpClientStack.createHttpRequest(request, null); + assertTrue(httpRequest instanceof HttpGet); + } + + @Test public void createPostRequest() throws Exception { + TestRequest.Post request = new TestRequest.Post(); + assertEquals(request.getMethod(), Method.POST); + + HttpUriRequest httpRequest = HttpClientStack.createHttpRequest(request, null); + assertTrue(httpRequest instanceof HttpPost); + } + + @Test public void createPostRequestWithBody() throws Exception { + TestRequest.PostWithBody request = new TestRequest.PostWithBody(); + assertEquals(request.getMethod(), Method.POST); + + HttpUriRequest httpRequest = HttpClientStack.createHttpRequest(request, null); + assertTrue(httpRequest instanceof HttpPost); + } + + @Test public void createPutRequest() throws Exception { + TestRequest.Put request = new TestRequest.Put(); + assertEquals(request.getMethod(), Method.PUT); + + HttpUriRequest httpRequest = HttpClientStack.createHttpRequest(request, null); + assertTrue(httpRequest instanceof HttpPut); + } + + @Test public void createPutRequestWithBody() throws Exception { + TestRequest.PutWithBody request = new TestRequest.PutWithBody(); + assertEquals(request.getMethod(), Method.PUT); + + HttpUriRequest httpRequest = HttpClientStack.createHttpRequest(request, null); + assertTrue(httpRequest instanceof HttpPut); + } + + @Test public void createDeleteRequest() throws Exception { + TestRequest.Delete request = new TestRequest.Delete(); + assertEquals(request.getMethod(), Method.DELETE); + + HttpUriRequest httpRequest = HttpClientStack.createHttpRequest(request, null); + assertTrue(httpRequest instanceof HttpDelete); + } + + @Test public void createHeadRequest() throws Exception { + TestRequest.Head request = new TestRequest.Head(); + assertEquals(request.getMethod(), Method.HEAD); + + HttpUriRequest httpRequest = HttpClientStack.createHttpRequest(request, null); + assertTrue(httpRequest instanceof HttpHead); + } + + @Test public void createOptionsRequest() throws Exception { + TestRequest.Options request = new TestRequest.Options(); + assertEquals(request.getMethod(), Method.OPTIONS); + + HttpUriRequest httpRequest = HttpClientStack.createHttpRequest(request, null); + assertTrue(httpRequest instanceof HttpOptions); + } + + @Test public void createTraceRequest() throws Exception { + TestRequest.Trace request = new TestRequest.Trace(); + assertEquals(request.getMethod(), Method.TRACE); + + HttpUriRequest httpRequest = HttpClientStack.createHttpRequest(request, null); + assertTrue(httpRequest instanceof HttpTrace); + } + + @Test public void createPatchRequest() throws Exception { + TestRequest.Patch request = new TestRequest.Patch(); + assertEquals(request.getMethod(), Method.PATCH); + + HttpUriRequest httpRequest = HttpClientStack.createHttpRequest(request, null); + assertTrue(httpRequest instanceof HttpPatch); + } + + @Test public void createPatchRequestWithBody() throws Exception { + TestRequest.PatchWithBody request = new TestRequest.PatchWithBody(); + assertEquals(request.getMethod(), Method.PATCH); + + HttpUriRequest httpRequest = HttpClientStack.createHttpRequest(request, null); + assertTrue(httpRequest instanceof HttpPatch); + } +} diff --git a/src/test/java/com/android/volley/toolbox/HttpHeaderParserTest.java b/src/test/java/com/android/volley/toolbox/HttpHeaderParserTest.java new file mode 100644 index 0000000..b8c4847 --- /dev/null +++ b/src/test/java/com/android/volley/toolbox/HttpHeaderParserTest.java @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.volley.toolbox; + +import com.android.volley.Cache; +import com.android.volley.NetworkResponse; + +import org.apache.http.Header; +import org.apache.http.message.BasicHeader; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import static org.junit.Assert.*; + +@RunWith(RobolectricTestRunner.class) +public class HttpHeaderParserTest { + + private static long ONE_MINUTE_MILLIS = 1000L * 60; + private static long ONE_HOUR_MILLIS = 1000L * 60 * 60; + + private NetworkResponse response; + private Map<String, String> headers; + + @Before public void setUp() throws Exception { + headers = new HashMap<String, String>(); + response = new NetworkResponse(0, null, headers, false); + } + + @Test public void parseCacheHeaders_noHeaders() { + Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); + + assertNotNull(entry); + assertNull(entry.etag); + assertEquals(0, entry.serverDate); + assertEquals(0, entry.ttl); + assertEquals(0, entry.softTtl); + } + + @Test public void parseCacheHeaders_headersSet() { + headers.put("MyCustomHeader", "42"); + + Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); + + assertNotNull(entry); + assertNotNull(entry.responseHeaders); + assertEquals(1, entry.responseHeaders.size()); + assertEquals("42", entry.responseHeaders.get("MyCustomHeader")); + } + + @Test public void parseCacheHeaders_etag() { + headers.put("ETag", "Yow!"); + + Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); + + assertNotNull(entry); + assertEquals("Yow!", entry.etag); + } + + @Test public void parseCacheHeaders_normalExpire() { + long now = System.currentTimeMillis(); + headers.put("Date", rfc1123Date(now)); + headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS)); + + Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); + + assertNotNull(entry); + assertNull(entry.etag); + assertEqualsWithin(entry.serverDate, now, ONE_MINUTE_MILLIS); + assertTrue(entry.softTtl >= (now + ONE_HOUR_MILLIS)); + assertTrue(entry.ttl == entry.softTtl); + } + + @Test public void parseCacheHeaders_expiresInPast() { + long now = System.currentTimeMillis(); + headers.put("Date", rfc1123Date(now)); + headers.put("Expires", rfc1123Date(now - ONE_HOUR_MILLIS)); + + Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); + + assertNotNull(entry); + assertNull(entry.etag); + assertEqualsWithin(entry.serverDate, now, ONE_MINUTE_MILLIS); + assertEquals(0, entry.ttl); + assertEquals(0, entry.softTtl); + } + + @Test public void parseCacheHeaders_serverRelative() { + + long now = System.currentTimeMillis(); + // Set "current" date as one hour in the future + headers.put("Date", rfc1123Date(now + ONE_HOUR_MILLIS)); + // TTL four hours in the future, so should be three hours from now + headers.put("Expires", rfc1123Date(now + 4 * ONE_HOUR_MILLIS)); + + Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); + + assertEqualsWithin(now + 3 * ONE_HOUR_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); + assertEquals(entry.softTtl, entry.ttl); + } + + @Test public void parseCacheHeaders_cacheControlOverridesExpires() { + long now = System.currentTimeMillis(); + headers.put("Date", rfc1123Date(now)); + headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS)); + headers.put("Cache-Control", "public, max-age=86400"); + + Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); + + assertNotNull(entry); + assertNull(entry.etag); + assertEqualsWithin(now + 24 * ONE_HOUR_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); + assertEquals(entry.softTtl, entry.ttl); + } + + @Test public void parseCacheHeaders_cacheControlNoCache() { + long now = System.currentTimeMillis(); + headers.put("Date", rfc1123Date(now)); + headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS)); + headers.put("Cache-Control", "no-cache"); + + Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); + + assertNull(entry); + } + + @Test public void parseCacheHeaders_cacheControlMustRevalidate() { + long now = System.currentTimeMillis(); + headers.put("Date", rfc1123Date(now)); + headers.put("Expires", rfc1123Date(now + ONE_HOUR_MILLIS)); + headers.put("Cache-Control", "must-revalidate"); + + Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); + + assertNotNull(entry); + assertNull(entry.etag); + assertEqualsWithin(now, entry.ttl, ONE_MINUTE_MILLIS); + assertEquals(entry.softTtl, entry.ttl); + } + + private void assertEqualsWithin(long expected, long value, long fudgeFactor) { + long diff = Math.abs(expected - value); + assertTrue(diff < fudgeFactor); + } + + private static String rfc1123Date(long millis) { + DateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH); + return df.format(new Date(millis)); + } + + // -------------------------- + + @Test public void parseCharset() { + // Like the ones we usually see + headers.put("Content-Type", "text/plain; charset=utf-8"); + assertEquals("utf-8", HttpHeaderParser.parseCharset(headers)); + + // Extra whitespace + headers.put("Content-Type", "text/plain; charset=utf-8 "); + assertEquals("utf-8", HttpHeaderParser.parseCharset(headers)); + + // Extra parameters + headers.put("Content-Type", "text/plain; charset=utf-8; frozzle=bar"); + assertEquals("utf-8", HttpHeaderParser.parseCharset(headers)); + + // No Content-Type header + headers.clear(); + assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers)); + + // Empty value + headers.put("Content-Type", "text/plain; charset="); + assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers)); + + // None specified + headers.put("Content-Type", "text/plain"); + assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers)); + + // None specified, extra semicolon + headers.put("Content-Type", "text/plain;"); + assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers)); + } + + @Test public void parseCaseInsensitive() { + + long now = System.currentTimeMillis(); + + Header[] headersArray = new Header[5]; + headersArray[0] = new BasicHeader("eTAG", "Yow!"); + headersArray[1] = new BasicHeader("DATE", rfc1123Date(now)); + headersArray[2] = new BasicHeader("expires", rfc1123Date(now + ONE_HOUR_MILLIS)); + headersArray[3] = new BasicHeader("cache-control", "public, max-age=86400"); + headersArray[4] = new BasicHeader("content-type", "text/plain"); + + Map<String, String> headers = BasicNetwork.convertHeaders(headersArray); + NetworkResponse response = new NetworkResponse(0, null, headers, false); + Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response); + + assertNotNull(entry); + assertEquals("Yow!", entry.etag); + assertEqualsWithin(now + 24 * ONE_HOUR_MILLIS, entry.ttl, ONE_MINUTE_MILLIS); + assertEquals(entry.softTtl, entry.ttl); + assertEquals("ISO-8859-1", HttpHeaderParser.parseCharset(headers)); + } +} diff --git a/src/test/java/com/android/volley/toolbox/HurlStackTest.java b/src/test/java/com/android/volley/toolbox/HurlStackTest.java new file mode 100644 index 0000000..42aeea8 --- /dev/null +++ b/src/test/java/com/android/volley/toolbox/HurlStackTest.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.volley.toolbox; + +import com.android.volley.Request.Method; +import com.android.volley.mock.MockHttpURLConnection; +import com.android.volley.mock.TestRequest; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +import static org.junit.Assert.*; + +@RunWith(RobolectricTestRunner.class) +public class HurlStackTest { + + private MockHttpURLConnection mMockConnection; + + @Before public void setUp() throws Exception { + mMockConnection = new MockHttpURLConnection(); + } + + @Test public void connectionForDeprecatedGetRequest() throws Exception { + TestRequest.DeprecatedGet request = new TestRequest.DeprecatedGet(); + assertEquals(request.getMethod(), Method.DEPRECATED_GET_OR_POST); + + HurlStack.setConnectionParametersForRequest(mMockConnection, request); + assertEquals("GET", mMockConnection.getRequestMethod()); + assertFalse(mMockConnection.getDoOutput()); + } + + @Test public void connectionForDeprecatedPostRequest() throws Exception { + TestRequest.DeprecatedPost request = new TestRequest.DeprecatedPost(); + assertEquals(request.getMethod(), Method.DEPRECATED_GET_OR_POST); + + HurlStack.setConnectionParametersForRequest(mMockConnection, request); + assertEquals("POST", mMockConnection.getRequestMethod()); + assertTrue(mMockConnection.getDoOutput()); + } + + @Test public void connectionForGetRequest() throws Exception { + TestRequest.Get request = new TestRequest.Get(); + assertEquals(request.getMethod(), Method.GET); + + HurlStack.setConnectionParametersForRequest(mMockConnection, request); + assertEquals("GET", mMockConnection.getRequestMethod()); + assertFalse(mMockConnection.getDoOutput()); + } + + @Test public void connectionForPostRequest() throws Exception { + TestRequest.Post request = new TestRequest.Post(); + assertEquals(request.getMethod(), Method.POST); + + HurlStack.setConnectionParametersForRequest(mMockConnection, request); + assertEquals("POST", mMockConnection.getRequestMethod()); + assertFalse(mMockConnection.getDoOutput()); + } + + @Test public void connectionForPostWithBodyRequest() throws Exception { + TestRequest.PostWithBody request = new TestRequest.PostWithBody(); + assertEquals(request.getMethod(), Method.POST); + + HurlStack.setConnectionParametersForRequest(mMockConnection, request); + assertEquals("POST", mMockConnection.getRequestMethod()); + assertTrue(mMockConnection.getDoOutput()); + } + + @Test public void connectionForPutRequest() throws Exception { + TestRequest.Put request = new TestRequest.Put(); + assertEquals(request.getMethod(), Method.PUT); + + HurlStack.setConnectionParametersForRequest(mMockConnection, request); + assertEquals("PUT", mMockConnection.getRequestMethod()); + assertFalse(mMockConnection.getDoOutput()); + } + + @Test public void connectionForPutWithBodyRequest() throws Exception { + TestRequest.PutWithBody request = new TestRequest.PutWithBody(); + assertEquals(request.getMethod(), Method.PUT); + + HurlStack.setConnectionParametersForRequest(mMockConnection, request); + assertEquals("PUT", mMockConnection.getRequestMethod()); + assertTrue(mMockConnection.getDoOutput()); + } + + @Test public void connectionForDeleteRequest() throws Exception { + TestRequest.Delete request = new TestRequest.Delete(); + assertEquals(request.getMethod(), Method.DELETE); + + HurlStack.setConnectionParametersForRequest(mMockConnection, request); + assertEquals("DELETE", mMockConnection.getRequestMethod()); + assertFalse(mMockConnection.getDoOutput()); + } + + @Test public void connectionForHeadRequest() throws Exception { + TestRequest.Head request = new TestRequest.Head(); + assertEquals(request.getMethod(), Method.HEAD); + + HurlStack.setConnectionParametersForRequest(mMockConnection, request); + assertEquals("HEAD", mMockConnection.getRequestMethod()); + assertFalse(mMockConnection.getDoOutput()); + } + + @Test public void connectionForOptionsRequest() throws Exception { + TestRequest.Options request = new TestRequest.Options(); + assertEquals(request.getMethod(), Method.OPTIONS); + + HurlStack.setConnectionParametersForRequest(mMockConnection, request); + assertEquals("OPTIONS", mMockConnection.getRequestMethod()); + assertFalse(mMockConnection.getDoOutput()); + } + + @Test public void connectionForTraceRequest() throws Exception { + TestRequest.Trace request = new TestRequest.Trace(); + assertEquals(request.getMethod(), Method.TRACE); + + HurlStack.setConnectionParametersForRequest(mMockConnection, request); + assertEquals("TRACE", mMockConnection.getRequestMethod()); + assertFalse(mMockConnection.getDoOutput()); + } + + @Test public void connectionForPatchRequest() throws Exception { + TestRequest.Patch request = new TestRequest.Patch(); + assertEquals(request.getMethod(), Method.PATCH); + + HurlStack.setConnectionParametersForRequest(mMockConnection, request); + assertEquals("PATCH", mMockConnection.getRequestMethod()); + assertFalse(mMockConnection.getDoOutput()); + } + + @Test public void connectionForPatchWithBodyRequest() throws Exception { + TestRequest.PatchWithBody request = new TestRequest.PatchWithBody(); + assertEquals(request.getMethod(), Method.PATCH); + + HurlStack.setConnectionParametersForRequest(mMockConnection, request); + assertEquals("PATCH", mMockConnection.getRequestMethod()); + assertTrue(mMockConnection.getDoOutput()); + } +} diff --git a/src/test/java/com/android/volley/toolbox/ImageRequestTest.java b/src/test/java/com/android/volley/toolbox/ImageRequestTest.java new file mode 100644 index 0000000..2f4495a --- /dev/null +++ b/src/test/java/com/android/volley/toolbox/ImageRequestTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.volley.toolbox; + +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; + +import com.android.volley.NetworkResponse; +import com.android.volley.Response; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.shadows.ShadowBitmapFactory; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.Assert.*; + +@RunWith(RobolectricTestRunner.class) +public class ImageRequestTest { + + @Test public void parseNetworkResponse_resizing() throws Exception { + // This is a horrible hack but Robolectric doesn't have a way to provide + // width and height hints for decodeByteArray. It works because the byte array + // "file:fake" is ASCII encodable and thus the name in Robolectric's fake + // bitmap creator survives as-is, and provideWidthAndHeightHints puts + // "file:" + name in its lookaside map. I write all this because it will + // probably break mysteriously at some point and I feel terrible about your + // having to debug it. + byte[] jpegBytes = "file:fake".getBytes(); + ShadowBitmapFactory.provideWidthAndHeightHints("fake", 1024, 500); + NetworkResponse jpeg = new NetworkResponse(jpegBytes); + + // No resize + verifyResize(jpeg, 0, 0, 1024, 500); + + // Exact sizes + verifyResize(jpeg, 512, 250, 512, 250); // exactly half + verifyResize(jpeg, 511, 249, 509, 249); // just under half + verifyResize(jpeg, 1080, 500, 1024, 500); // larger + verifyResize(jpeg, 500, 500, 500, 244); // keep same ratio + + // Specify only width, preserve aspect ratio + verifyResize(jpeg, 512, 0, 512, 250); + verifyResize(jpeg, 800, 0, 800, 390); + verifyResize(jpeg, 1024, 0, 1024, 500); + + // Specify only height, preserve aspect ratio + verifyResize(jpeg, 0, 250, 512, 250); + verifyResize(jpeg, 0, 391, 800, 391); + verifyResize(jpeg, 0, 500, 1024, 500); + } + + private void verifyResize(NetworkResponse networkResponse, int maxWidth, int maxHeight, + int expectedWidth, int expectedHeight) { + ImageRequest request = new ImageRequest( + "", null, maxWidth, maxHeight, Config.RGB_565, null); + Response<Bitmap> response = request.parseNetworkResponse(networkResponse); + assertNotNull(response); + assertTrue(response.isSuccess()); + Bitmap bitmap = response.result; + assertNotNull(bitmap); + assertEquals(expectedWidth, bitmap.getWidth()); + assertEquals(expectedHeight, bitmap.getHeight()); + } + + @Test public void findBestSampleSize() { + // desired == actual == 1 + assertEquals(1, ImageRequest.findBestSampleSize(100, 150, 100, 150)); + + // exactly half == 2 + assertEquals(2, ImageRequest.findBestSampleSize(280, 160, 140, 80)); + + // just over half == 1 + assertEquals(1, ImageRequest.findBestSampleSize(1000, 800, 501, 401)); + + // just under 1/4 == 4 + assertEquals(4, ImageRequest.findBestSampleSize(100, 200, 24, 50)); + } + + private static byte[] readInputStream(InputStream in) throws IOException { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int count; + while ((count = in.read(buffer)) != -1) { + bytes.write(buffer, 0, count); + } + in.close(); + return bytes.toByteArray(); + } +} diff --git a/src/test/java/com/android/volley/toolbox/NetworkImageViewTest.java b/src/test/java/com/android/volley/toolbox/NetworkImageViewTest.java new file mode 100644 index 0000000..48c81b6 --- /dev/null +++ b/src/test/java/com/android/volley/toolbox/NetworkImageViewTest.java @@ -0,0 +1,53 @@ +package com.android.volley.toolbox; + +import android.view.ViewGroup.LayoutParams; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricTestRunner; + +import static org.junit.Assert.*; + +@RunWith(RobolectricTestRunner.class) +public class NetworkImageViewTest { + private NetworkImageView mNIV; + private MockImageLoader mMockImageLoader; + + @Before public void setUp() throws Exception { + mMockImageLoader = new MockImageLoader(); + mNIV = new NetworkImageView(Robolectric.application); + } + + @Test public void setImageUrl_requestsImage() { + mNIV.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); + mNIV.setImageUrl("http://foo", mMockImageLoader); + assertEquals("http://foo", mMockImageLoader.lastRequestUrl); + assertEquals(0, mMockImageLoader.lastMaxWidth); + assertEquals(0, mMockImageLoader.lastMaxHeight); + } + + // public void testSetImageUrl_setsMaxSize() { + // // TODO: Not sure how to make getWidth() return something from an + // // instrumentation test. Write this test once it's figured out. + // } + + private class MockImageLoader extends ImageLoader { + public MockImageLoader() { + super(null, null); + } + + public String lastRequestUrl; + public int lastMaxWidth; + public int lastMaxHeight; + + public ImageContainer get(String requestUrl, ImageListener imageListener, int maxWidth, + int maxHeight) { + lastRequestUrl = requestUrl; + lastMaxWidth = maxWidth; + lastMaxHeight = maxHeight; + return null; + } + } +} diff --git a/src/test/java/com/android/volley/toolbox/PoolingByteArrayOutputStreamTest.java b/src/test/java/com/android/volley/toolbox/PoolingByteArrayOutputStreamTest.java new file mode 100644 index 0000000..c3bfac7 --- /dev/null +++ b/src/test/java/com/android/volley/toolbox/PoolingByteArrayOutputStreamTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.volley.toolbox; + +import java.io.IOException; +import java.util.Arrays; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class PoolingByteArrayOutputStreamTest { + @Test public void pooledOneBuffer() throws IOException { + ByteArrayPool pool = new ByteArrayPool(32768); + writeOneBuffer(pool); + writeOneBuffer(pool); + writeOneBuffer(pool); + } + + @Test public void pooledIndividualWrites() throws IOException { + ByteArrayPool pool = new ByteArrayPool(32768); + writeBytesIndividually(pool); + writeBytesIndividually(pool); + writeBytesIndividually(pool); + } + + @Test public void unpooled() throws IOException { + ByteArrayPool pool = new ByteArrayPool(0); + writeOneBuffer(pool); + writeOneBuffer(pool); + writeOneBuffer(pool); + } + + @Test public void unpooledIndividualWrites() throws IOException { + ByteArrayPool pool = new ByteArrayPool(0); + writeBytesIndividually(pool); + writeBytesIndividually(pool); + writeBytesIndividually(pool); + } + + private void writeOneBuffer(ByteArrayPool pool) throws IOException { + byte[] data = new byte[16384]; + for (int i = 0; i < data.length; i++) { + data[i] = (byte) (i & 0xff); + } + PoolingByteArrayOutputStream os = new PoolingByteArrayOutputStream(pool); + os.write(data); + + assertTrue(Arrays.equals(data, os.toByteArray())); + } + + private void writeBytesIndividually(ByteArrayPool pool) { + byte[] data = new byte[16384]; + for (int i = 0; i < data.length; i++) { + data[i] = (byte) (i & 0xff); + } + PoolingByteArrayOutputStream os = new PoolingByteArrayOutputStream(pool); + for (int i = 0; i < data.length; i++) { + os.write(data[i]); + } + + assertTrue(Arrays.equals(data, os.toByteArray())); + } +} |