Skip to content

Commit

Permalink
Merge pull request #273 from DavidWiesner/feature-ListPreloader-suppo…
Browse files Browse the repository at this point in the history
…rt-multiple-sizes

Feature list preloader support multiple target sizes
  • Loading branch information
sjudd committed Nov 21, 2014
2 parents 72e93e6 + 0618cf0 commit dc80fe4
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 103 deletions.
216 changes: 157 additions & 59 deletions library/src/androidTest/java/com/bumptech/glide/ListPreloaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,26 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import com.bumptech.glide.request.target.SizeReadyCallback;
import com.bumptech.glide.request.target.Target;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.verification.VerificationMode;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
Expand All @@ -21,43 +33,53 @@
@Config(manifest = Config.NONE, emulateSdk = 18)
public class ListPreloaderTest {

@Mock
private BitmapRequestBuilder request;

@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}

@Test
public void testGetItemsIsCalledIncreasing() {
final AtomicBoolean called = new AtomicBoolean(false);
final AtomicInteger calledCount = new AtomicInteger();

ListPreloaderAdapter preloaderAdapter = new ListPreloaderAdapter() {
@Override
public List<Object> getPreloadItems(int start, int end) {
public List<Object> getPreloadItems(int position) {
called.set(true);
assertEquals(11, start);
assertEquals(21, end);
return super.getPreloadItems(start, end);
final int count = calledCount.getAndIncrement();
assertEquals(11 + count, position);
return super.getPreloadItems(position);
}
};
ListPreloader<Object> preloader = new ListPreloader<Object>(preloaderAdapter, preloaderAdapter, 10);
preloader.onScroll(null, 1, 10, 30);
assertTrue(called.get());
assertEquals(10, calledCount.get());
}

@Test
public void testGetItemsIsCalledInOrderIncreasing() {
final int toPreload = 10;
final List<Object> objects = new ArrayList<Object>();
for (int i = 0; i < toPreload; i++) {
objects.add(new Object());
objects.add(new Integer(i));
}

ListPreloaderAdapter preloaderAdapter = new ListPreloaderAdapter() {

public int expectedPosition;

@Override
public int[] getPreloadSize(Object item) {
public int[] getPreloadSize(Object item, int adapterPostion, int itemPosition) {
return new int[]{10, 10};
}

@Override
public List<Object> getPreloadItems(int start, int end) {
return objects;
public List<Object> getPreloadItems(int position) {
return objects.subList(position - 11, position + 1 - 11);
}

@Override
Expand All @@ -68,24 +90,25 @@ public BitmapRequestBuilder getPreloadRequestBuilder(Object item) {
}
};
ListPreloader<Object> preloader = new ListPreloader<Object>(preloaderAdapter, preloaderAdapter,
toPreload);
preloader.onScroll(null, 1, 10, 30);
toPreload);
preloader.onScroll(null, 1, 10, 20);
}

@Test
public void testGetItemsIsCalledDecreasing() {
final AtomicBoolean called = new AtomicBoolean(false);
final AtomicInteger calledCount = new AtomicInteger();
ListPreloaderAdapter preloaderAdapter = new ListPreloaderAdapter() {
@Override
public List<Object> getPreloadItems(int start, int end) {
public List<Object> getPreloadItems(int position) {
// Ignore the preload caused from us starting at the end
if (start == 40) {
if (position >= 40) {
return Collections.emptyList();
}
final int count = calledCount.getAndIncrement();
called.set(true);
assertEquals(19, start);
assertEquals(29, end);
return super.getPreloadItems(start, end);
assertEquals(28 - count, position);
return super.getPreloadItems(position);
}
};
ListPreloader<Object> preloader = new ListPreloader<Object>(preloaderAdapter, preloaderAdapter, 10);
Expand All @@ -106,16 +129,16 @@ public void testGetItemsIsCalledInOrderDecreasing() {
int expectedPosition = toPreload - 1;

@Override
public int[] getPreloadSize(Object item) {
public int[] getPreloadSize(Object item, int adapterPostion, int itemPosition) {
return new int[]{10, 10};
}

@Override
public List<Object> getPreloadItems(int start, int end) {
if (start == 40) {
return Collections.emptyList();
public List<Object> getPreloadItems(int position) {
if (position == 40) {
return null;
}
return objects;
return objects.subList(position, position + 1);
}

@Override
Expand All @@ -126,20 +149,21 @@ public BitmapRequestBuilder getPreloadRequestBuilder(Object item) {
}
};
ListPreloader<Object> preloader = new ListPreloader<Object>(preloaderAdapter, preloaderAdapter, toPreload);
preloader.onScroll(null, 30, 10, 40);
preloader.onScroll(null, 29, 10, 40);
preloader.onScroll(null, 30, 10, 10);
preloader.onScroll(null, 29, 10, 10);
}

@Test
public void testGetItemsIsNeverCalledWithEndGreaterThanTotalItems() {
final AtomicBoolean called = new AtomicBoolean(false);
final AtomicInteger calledCount = new AtomicInteger();
ListPreloaderAdapter preloaderAdapter = new ListPreloaderAdapter() {
@Override
public List<Object> getPreloadItems(int start, int end) {
public List<Object> getPreloadItems(int position) {
called.set(true);
assertEquals(26, start);
assertEquals(30, end);
return super.getPreloadItems(start, end);
final int count = calledCount.getAndIncrement();
assertEquals(26 + count, position);
return super.getPreloadItems(position);
}
};
ListPreloader<Object> preloader = new ListPreloader<Object>(preloaderAdapter, preloaderAdapter, 10);
Expand All @@ -150,16 +174,17 @@ public List<Object> getPreloadItems(int start, int end) {
@Test
public void testGetItemsIsNeverCalledWithStartLessThanZero() {
final AtomicBoolean called = new AtomicBoolean(false);
final AtomicInteger calledCount = new AtomicInteger();
ListPreloaderAdapter preloaderAdapter = new ListPreloaderAdapter() {
@Override
public List<Object> getPreloadItems(int start, int end) {
if (start == 17) {
public List<Object> getPreloadItems(int position) {
if (position >= 17) {
return Collections.emptyList();
}
called.set(true);
assertEquals(0, start);
assertEquals(6, end);
return super.getPreloadItems(start, end);
final int count = calledCount.getAndIncrement();
assertEquals(5 - count, position);
return super.getPreloadItems(position);
}
};

Expand All @@ -174,52 +199,124 @@ public void testDontPreloadItemsRepeatedlyWhileIncreasing() {
final AtomicInteger called = new AtomicInteger();
ListPreloaderAdapter preloaderAdapter = new ListPreloaderAdapter() {
@Override
public List<Object> getPreloadItems(int start, int end) {
public List<Object> getPreloadItems(int position) {
final int current = called.getAndIncrement();
if (current == 0) {
assertEquals(11, start);
assertEquals(21, end);
} else if (current == 1) {
assertEquals(21, start);
assertEquals(24, end);
}
return super.getPreloadItems(start, end);
assertEquals(11 + current, position);
return super.getPreloadItems(position);
}
};

ListPreloader<Object> preloader = new ListPreloader<Object>(preloaderAdapter, preloaderAdapter, 10);
preloader.onScroll(null, 1, 10, 30);
preloader.onScroll(null, 4, 10, 30);

assertEquals(2, called.get());
assertEquals(13, called.get());
}

@Test
public void testDontPreloadItemsRepeatedlyWhileDecreasing() {
final AtomicInteger called = new AtomicInteger();
ListPreloaderAdapter preloaderAdapter = new ListPreloaderAdapter() {
@Override
public List<Object> getPreloadItems(int start, int end) {
if (start == 30) {
public List<Object> getPreloadItems(int position) {
if (position >= 20) {
return Collections.emptyList();
}
final int current = called.getAndIncrement();
if (current == 0) {
assertEquals(10, start);
assertEquals(20, end);
} else if (current == 1) {
assertEquals(7, start);
assertEquals(10, end);
}
return super.getPreloadItems(start, end);
assertEquals(19 - current, position);
return super.getPreloadItems(position);
}
};

ListPreloader<Object> preloader = new ListPreloader<Object>(preloaderAdapter, preloaderAdapter, 10);
preloader.onScroll(null, 21, 10, 30);
preloader.onScroll(null, 20, 10, 30);
preloader.onScroll(null, 17, 10, 30);
assertEquals(2, called.get());
assertEquals(13, called.get());
}

@Test
public void testMultipleItemsForPositionIncreasing() throws NoSuchFieldException {
final List<Object> objects = new ArrayList<Object>();
objects.add(new Object());
objects.add(new Object());
ListPreloaderAdapter preloaderAdapter = new ListPreloaderAdapter() {
public int expectedPosition = (1 + 10) * 2;

@Override
public List<Object> getPreloadItems(int position) {
return objects;
}

@Override
public int[] getPreloadSize(Object item, int adapterPostion, int itemPosition) {
assertEquals(expectedPosition / 2, adapterPostion);
assertEquals(expectedPosition % 2, itemPosition);
expectedPosition++;
return itemPosition == 0 ? new int[]{10, 11} : new int[]{20, 21};
}

@Override
public GenericRequestBuilder getPreloadRequestBuilder(Object item) {
return request;
}
};
ListPreloader<Object> preloader = new ListPreloader<Object>(preloaderAdapter, preloaderAdapter, 10);
Iterable<Integer> expected = Arrays.asList(10, 11, 20, 21, 10, 11, 20, 21);

preloader.onScroll(null, 1, 10, 1 + 10 + 2);

List<Integer> allValues = getTagetsSizes(request, times(4));
assertEquals(expected, allValues);
}

@Test
public void testMultipleItemsForPositionDecreasing() throws NoSuchFieldException {
final List<Object> objects = new ArrayList<Object>();
objects.add(new Object());
objects.add(new Object());
ListPreloaderAdapter preloaderAdapter = new ListPreloaderAdapter() {
int expectedPosition = objects.size() * 2 - 1;

@Override
public List<Object> getPreloadItems(int position) {
return objects;
}

@Override
public int[] getPreloadSize(Object item, int adapterPostion, int itemPosition) {
assertEquals(expectedPosition / 2, adapterPostion);
assertEquals(expectedPosition % 2, itemPosition);
expectedPosition--;
return itemPosition == 0 ? new int[]{10, 11} : new int[]{20, 21};
}

@Override
public GenericRequestBuilder getPreloadRequestBuilder(Object item) {
return request;
}
};
ListPreloader<Object> preloader = new ListPreloader<Object>(preloaderAdapter, preloaderAdapter, 10);
Iterable<Integer> expected = Arrays.asList(20, 21, 10, 11, 20, 21, 10, 11);

preloader.onScroll(null, 3, 2, 3 + 2);
preloader.onScroll(null, 2, 2, 3 + 2);

List<Integer> allValues = getTagetsSizes(request, times(4));
assertEquals(expected, allValues);
}

private List<Integer> getTagetsSizes(BitmapRequestBuilder requestBuilder, VerificationMode callVerificationMode) {
ArgumentCaptor<Integer> integerArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
ArgumentCaptor<Target> targetArgumentCaptor = ArgumentCaptor.forClass(Target.class);
SizeReadyCallback cb = mock(SizeReadyCallback.class);
VerificationMode mode = atLeastOnce();
verify(requestBuilder, mode).into(targetArgumentCaptor.capture());
for (Target target : targetArgumentCaptor.getAllValues()) {
target.getSize(cb);
}
verify(cb, mode).onSizeReady(integerArgumentCaptor.capture(), integerArgumentCaptor.capture());
return integerArgumentCaptor.getAllValues();
}

@Test
Expand All @@ -230,8 +327,8 @@ public void testItemsArePreloadedWithGlide() {
final HashSet<Object> loadedObjects = new HashSet<Object>();
ListPreloaderAdapter preloaderAdapter = new ListPreloaderAdapter() {
@Override
public List<Object> getPreloadItems(int start, int end) {
return objects;
public List<Object> getPreloadItems(int position) {
return objects.subList(position - 11, position - 10);
}

@Override
Expand All @@ -241,7 +338,8 @@ public GenericRequestBuilder getPreloadRequestBuilder(Object item) {
}
};
ListPreloader<Object> preloader = new ListPreloader<Object>(preloaderAdapter, preloaderAdapter, 10);
preloader.onScroll(null, 1, 10, 30);

preloader.onScroll(null, 1, 10, 13);
assertThat(loadedObjects).containsAllIn(objects);
}

Expand All @@ -252,8 +350,8 @@ public ListPreloaderAdapter() {
}

@Override
public List<Object> getPreloadItems(int start, int end) {
ArrayList<Object> result = new ArrayList<Object>(end - start);
public List<Object> getPreloadItems(int position) {
ArrayList<Object> result = new ArrayList<Object>(1);
Collections.fill(result, new Object());
return result;
}
Expand All @@ -264,7 +362,7 @@ public GenericRequestBuilder getPreloadRequestBuilder(Object item) {
}

@Override
public int[] getPreloadSize(Object item) {
public int[] getPreloadSize(Object item, int adapterPostion, int itemPosition) {
return new int[]{100, 100};
}
}
Expand Down
Loading

0 comments on commit dc80fe4

Please sign in to comment.