// should append result items, set previous cursor, and call notifyChanged
 @Test
 public void testPreviousCallback_successReceivedItems() {
   delegate = new TimelineDelegate<>(mockTimeline, mockObservable, testItems);
   final TimelineStateHolder timelineStateHolder =
       new TimelineStateHolder(
           new TimelineCursor(ANY_POSITION, ANY_POSITION),
           new TimelineCursor(ANY_POSITION, ANY_POSITION));
   final TimelineDelegate.PreviousCallback cb = delegate.new PreviousCallback(timelineStateHolder);
   cb.success(new Result<>(new TimelineResult<>(TEST_TIMELINE_CURSOR, testExtraItems), null));
   // assert the previous TimelineCursor is set on the ScrollStateHolder
   assertEquals(TEST_MIN_POSITION, timelineStateHolder.positionForPrevious());
   assertEquals(ANY_POSITION, timelineStateHolder.positionForNext());
   // assert that extra items were appended in order received
   assertEquals(TOTAL_ITEMS, delegate.itemList.size());
   assertEquals(TEST_ITEM_2, delegate.getItem(0));
   assertEquals(TEST_ITEM_1, delegate.getItem(1));
   assertEquals(TEST_ITEM_4, delegate.getItem(2));
   assertEquals(TEST_ITEM_3, delegate.getItem(3));
   // assert observer's notifyChanged is called
   verify(mockObservable).notifyChanged();
 }
 @Test
 public void testGetLastItem_loadsPrevious() {
   final Timeline<TestItem> fakeTimeline =
       new FakeItemTimeline(NUM_ITEMS, ANY_POSITION, ANY_POSITION);
   delegate = new TimelineDelegate<>(fakeTimeline, mockObservable, null);
   delegate.refresh(null);
   // refresh loads latest items (notifyChange)
   verify(mockObservable).notifyChanged();
   delegate.getItem(NUM_ITEMS - 1);
   // assert items are added and notifyChanged is called again
   assertEquals(2 * NUM_ITEMS, delegate.getCount());
   verify(mockObservable, times(2)).notifyChanged();
 }
 // should clear items with result items, set next cursor, and call notifyChanged
 @Test
 public void testRefreshCallback_successReceivedItems() {
   delegate = new TimelineDelegate<>(mockTimeline, mockObservable, testItems);
   final TimelineStateHolder timelineStateHolder =
       new TimelineStateHolder(
           new TimelineCursor(ANY_POSITION, ANY_POSITION),
           new TimelineCursor(ANY_POSITION, ANY_POSITION));
   final TimelineDelegate.RefreshCallback cb =
       delegate.new RefreshCallback(null, timelineStateHolder);
   cb.success(new Result<>(new TimelineResult<>(TEST_TIMELINE_CURSOR, testExtraItems), null));
   // assert the next TimelineCursor is set on the ScrollStateHolder, previous unchanged
   assertEquals(TEST_MAX_POSITION, timelineStateHolder.positionForNext());
   assertEquals(ANY_POSITION, timelineStateHolder.positionForPrevious());
   // assert that extra items replaced the old items
   assertEquals(testExtraItems.size(), delegate.itemList.size());
   assertEquals(TEST_ITEM_4, delegate.getItem(0));
   assertEquals(TEST_ITEM_3, delegate.getItem(1));
   // assert observer's notifyChanged is called
   verify(mockObservable).notifyChanged();
 }
 @Test
 public void testGetItem() {
   delegate = new TimelineDelegate<>(mockTimeline, null, testItems);
   assertEquals(TEST_ITEM_2, delegate.getItem(0));
   assertEquals(TEST_ITEM_1, delegate.getItem(1));
 }