提交 e52ac307 编写于 作者: S Sam Judd

Add runner implementations and tests

上级 bbcff628
package com.bumptech.glide.resize;
import com.bumptech.glide.resize.cache.DiskCache;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class ResourceRunnerTest {
@Test
public void testDiskCacheIsAlwaysChecked() {
String id = "asdf";
DiskCache diskCache = mock(DiskCache.class);
ResourceDecoder decoder = mock(ResourceDecoder.class);
ResourceRunner runner = new ResourceRunner(id, diskCache, decoder, mock(SourceResourceRunner.class),
mock(ExecutorService.class), mock(ResourceCallback.class));
runner.run();
verify(diskCache).get(eq(id));
}
@Test
public void testCacheDecoderIsCalledIfInCache() {
String id = "asdf";
DiskCache diskCache = mock(DiskCache.class);
InputStream result = new ByteArrayInputStream(new byte[0]);
when(diskCache.get(eq(id))).thenReturn(result);
ResourceDecoder decoder = mock(ResourceDecoder.class);
ResourceRunner runner = new ResourceRunner(id, diskCache, decoder, mock(SourceResourceRunner.class),
mock(ExecutorService.class), mock(ResourceCallback.class));
runner.run();
verify(decoder).decode(eq(result));
}
@Test
public void callbackIsCalledIfCacheDecodeSucceeds() {
String id = "asdf";
DiskCache diskCache = mock(DiskCache.class);
InputStream is = new ByteArrayInputStream(new byte[0]);
when(diskCache.get(eq(id))).thenReturn(is);
Resource result = mock(Resource.class);
ResourceDecoder decoder = mock(ResourceDecoder.class);
when(decoder.decode(eq(is))).thenReturn(result);
ResourceCallback cb = mock(ResourceCallback.class);
ResourceRunner runner = new ResourceRunner(id, diskCache, decoder, mock(SourceResourceRunner.class),
mock(ExecutorService.class), cb);
runner.run();
verify(cb).onResourceReady(eq(result));
}
@Test
public void testCallbackIsNotCalledIfDiskCacheReturnsNull() {
String id = "asdf";
DiskCache diskCache = mock(DiskCache.class);
when(diskCache.get(eq(id))).thenReturn(null);
ResourceCallback cb = mock(ResourceCallback.class);
ResourceRunner runner = new ResourceRunner(id, diskCache, mock(ResourceDecoder.class),
mock(SourceResourceRunner.class), mock(ExecutorService.class), cb);
runner.run();
verify(diskCache, atLeastOnce()).get(eq(id));
verify(cb, never()).onException(any(Exception.class));
}
@Test
public void testCallbackIsNotCalledIfCacheDecodeFails() {
String id = "asdf";
DiskCache diskCache = mock(DiskCache.class);
when(diskCache.get(eq(id))).thenReturn(new ByteArrayInputStream(new byte[0]));
ResourceDecoder decoder = mock(ResourceDecoder.class);
when(decoder.decode(anyObject())).thenReturn(null);
ResourceCallback cb = mock(ResourceCallback.class);
ResourceRunner runner = new ResourceRunner(id, diskCache, decoder, mock(SourceResourceRunner.class),
mock(ExecutorService.class), cb);
runner.run();
verify(cb, never()).onException(any(Exception.class));
}
@Test
public void testSourceRunnerIsQueuedIfNotInCache() {
String id = "asdf";
DiskCache diskCache = mock(DiskCache.class);
when(diskCache.get(eq(id))).thenReturn(null);
SourceResourceRunner sourceRunner = mock(SourceResourceRunner.class);
ExecutorService executorService = mock(ExecutorService.class);
ResourceRunner runner = new ResourceRunner(id, diskCache, mock(ResourceDecoder.class), sourceRunner,
executorService, mock(ResourceCallback.class));
runner.run();
verify(executorService).submit(eq(sourceRunner));
}
@Test
public void testSourceRunnerIsQueuedIfCacheDecodeFails() {
String id = "asdf";
DiskCache diskCache = mock(DiskCache.class);
when(diskCache.get(eq(id))).thenReturn(new ByteArrayInputStream(new byte[0]));
ResourceDecoder decoder = mock(ResourceDecoder.class);
when(decoder.decode(anyObject())).thenReturn(null);
SourceResourceRunner sourceRunner = mock(SourceResourceRunner.class);
ExecutorService executorService = mock(ExecutorService.class);
ResourceRunner runner = new ResourceRunner(id, diskCache, decoder, sourceRunner, executorService,
mock(ResourceCallback.class));
runner.run();
verify(executorService).submit(eq(sourceRunner));
}
}
package com.bumptech.glide.resize;
import com.bumptech.glide.loader.bitmap.resource.ResourceFetcher;
import com.bumptech.glide.resize.cache.DiskCache;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class SourceResourceRunnerTest {
private static final String ID = "asdf2";
@Test
public void testResourceFetcherIsCalled() throws Exception {
ResourceFetcher resourceFetcher = mock(ResourceFetcher.class);
SourceResourceRunner runner = new SourceResourceRunner(ID, resourceFetcher, mock(ResourceDecoder.class),
mock(ResourceEncoder.class), mock(DiskCache.class), mock(Metadata.class), mock(ResourceCallback.class));
runner.run();
verify(resourceFetcher).loadResource(any(Metadata.class));
}
@Test
public void testDecoderIsCalledIfFetched() throws Exception {
ResourceFetcher resourceFetcher = mock(ResourceFetcher.class);
Object fetched = new Object();
when(resourceFetcher.loadResource(any(Metadata.class)))
.thenReturn(fetched);
ResourceDecoder decoder = mock(ResourceDecoder.class);
SourceResourceRunner runner = new SourceResourceRunner(ID, resourceFetcher, decoder,
mock(ResourceEncoder.class), mock(DiskCache.class), mock(Metadata.class), mock(ResourceCallback.class));
runner.run();
verify(decoder).decode(eq(fetched));
}
@Test
public void testCallbackIsCalledIfFetchedAndDecoded() throws Exception {
ResourceFetcher resourceFetcher = mock(ResourceFetcher.class);
InputStream is = new ByteArrayInputStream(new byte[0]);
when(resourceFetcher.loadResource(any(Metadata.class))).thenReturn(is);
ResourceDecoder decoder = mock(ResourceDecoder.class);
Resource result = mock(Resource.class);
when(decoder.decode(eq(is))).thenReturn(result);
ResourceCallback cb = mock(ResourceCallback.class);
SourceResourceRunner runner = new SourceResourceRunner(ID, resourceFetcher, decoder,
mock(ResourceEncoder.class), mock(DiskCache.class), mock(Metadata.class), cb);
runner.run();
verify(cb).onResourceReady(eq(result));
}
@Test
public void testResourceIsWrittenToCacheIfFetchedAndDecoded() throws Exception {
ResourceFetcher resourceFetcher = mock(ResourceFetcher.class);
InputStream is = new ByteArrayInputStream(new byte[0]);
when(resourceFetcher.loadResource(any(Metadata.class))).thenReturn(is);
ResourceDecoder decoder = mock(ResourceDecoder.class);
Resource result = mock(Resource.class);
when(decoder.decode(eq(is))).thenReturn(result);
DiskCache diskCache = mock(DiskCache.class);
final OutputStream expected = new ByteArrayOutputStream();
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
DiskCache.Writer writer = (DiskCache.Writer) invocation.getArguments()[1];
writer.write(expected);
return null;
}
}).when(diskCache).put(eq(ID), any(DiskCache.Writer.class));
ResourceEncoder encoder = mock(ResourceEncoder.class);
SourceResourceRunner runner = new SourceResourceRunner(ID, resourceFetcher, decoder, encoder, diskCache,
mock(Metadata.class), mock(ResourceCallback.class));
runner.run();
verify(encoder).encode(eq(result), eq(expected));
}
@Test
public void testCallbackIsCalledIfFetchFails() throws Exception {
ResourceFetcher fetcher = mock(ResourceFetcher.class);
Exception expected = new Exception("Test");
when(fetcher.loadResource(any(Metadata.class))).thenThrow(expected);
ResourceCallback cb = mock(ResourceCallback.class);
SourceResourceRunner runner = new SourceResourceRunner(ID, fetcher, mock(ResourceDecoder.class),
mock(ResourceEncoder.class), mock(DiskCache.class), mock(Metadata.class), cb);
runner.run();
verify(cb).onException(eq(expected));
}
@Test
public void testCallbackIsCalledIfDecodeFails() throws Exception {
ResourceFetcher fetcher = mock(ResourceFetcher.class);
when(fetcher.loadResource(any(Metadata.class))).thenReturn(new Object());
ResourceDecoder decoder = mock(ResourceDecoder.class);
when(decoder.decode(anyObject())).thenReturn(null);
ResourceCallback cb = mock(ResourceCallback.class);
SourceResourceRunner runner = new SourceResourceRunner(ID, fetcher, decoder, mock(ResourceEncoder.class),
mock(DiskCache.class), mock(Metadata.class), cb);
runner.run();
verify(cb).onException((Exception) isNull());
}
}
package com.bumptech.glide.resize;
public interface Resource<T> {
public T get();
}
package com.bumptech.glide.resize;
interface ResourceCallback {
public void onResourceReady(Resource resource);
public void onException(Exception e);
}
package com.bumptech.glide.resize;
public interface ResourceDecoder<T> {
public Resource decode(T source);
}
package com.bumptech.glide.resize;
import java.io.OutputStream;
public interface ResourceEncoder<T> {
public void encode(Resource<T> resource, OutputStream os);
}
package com.bumptech.glide.resize;
import com.bumptech.glide.resize.cache.DiskCache;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
public class ResourceRunner implements Runnable {
private final String id;
private final SourceResourceRunner sourceRunner;
private final ExecutorService executorService;
private final ResourceCallback cb;
private final ResourceDecoder<InputStream> cacheDecoder;
private final DiskCache diskCache;
public ResourceRunner(String id, DiskCache diskCache, ResourceDecoder<InputStream> cacheDecoder,
SourceResourceRunner sourceRunner, ExecutorService executorService, ResourceCallback cb) {
this.id = id;
this.diskCache = diskCache;
this.cacheDecoder = cacheDecoder;
this.sourceRunner = sourceRunner;
this.executorService = executorService;
this.cb = cb;
}
@Override
public void run() {
Resource fromCache = loadFromDiskCache();
if (fromCache != null) {
cb.onResourceReady(fromCache);
} else {
executorService.submit(sourceRunner);
}
}
private Resource loadFromDiskCache() {
Resource result = null;
InputStream fromCache = diskCache.get(id);
if (fromCache != null) {
result = cacheDecoder.decode(fromCache);
}
return result;
}
}
package com.bumptech.glide.resize;
import com.bumptech.glide.loader.bitmap.resource.ResourceFetcher;
import com.bumptech.glide.resize.cache.DiskCache;
import java.io.OutputStream;
public class SourceResourceRunner<T> implements Runnable, DiskCache.Writer {
private final String id;
private final ResourceFetcher<T> resourceFetcher;
private final ResourceDecoder<T> decoder;
private final ResourceEncoder<T> encoder;
private DiskCache diskCache;
private Metadata metadata;
private ResourceCallback cb;
private Resource result;
public SourceResourceRunner(String id, ResourceFetcher<T> resourceFetcher, ResourceDecoder<T> decoder,
ResourceEncoder<T> encoder, DiskCache diskCache, Metadata metadata, ResourceCallback cb) {
this.id = id;
this.resourceFetcher = resourceFetcher;
this.decoder = decoder;
this.encoder = encoder;
this.diskCache = diskCache;
this.metadata = metadata;
this.cb = cb;
}
@Override
public void run() {
try {
result = null;
T toDecode = resourceFetcher.loadResource(metadata);
if (toDecode != null) {
result = decoder.decode(toDecode);
}
if (result != null) {
diskCache.put(id, this);
cb.onResourceReady(result);
} else {
cb.onException(null);
}
} catch (Exception e) {
cb.onException(e);
}
}
@Override
public void write(OutputStream os) {
encoder.encode(result, os);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册