@Test
 public void testFindPositionOffsetInPreLayout() {
   setupBasic(50, 25, 10);
   rm(24, 5);
   mAdapterHelper.preProcess();
   // since 25 is invisible, we offset by one while checking
   assertEquals("find position for view 23", 23, mAdapterHelper.findPositionOffset(23));
   assertEquals("find position for view 24", -1, mAdapterHelper.findPositionOffset(24));
   assertEquals("find position for view 25", -1, mAdapterHelper.findPositionOffset(25));
   assertEquals("find position for view 26", -1, mAdapterHelper.findPositionOffset(26));
   assertEquals("find position for view 27", -1, mAdapterHelper.findPositionOffset(27));
   assertEquals("find position for view 28", 24, mAdapterHelper.findPositionOffset(28));
   assertEquals("find position for view 29", 25, mAdapterHelper.findPositionOffset(29));
 }
 public void update(int index, int count) {
   for (int i = 0; i < count; i++) {
     mItems.get(index + i).update();
   }
   mAdapterHelper.addUpdateOp(
       new AdapterHelper.UpdateOp(AdapterHelper.UpdateOp.UPDATE, index, count));
 }
 public void remove(int index, int count) {
   for (int i = 0; i < count; i++) {
     mItems.remove(index);
   }
   mAdapterHelper.addUpdateOp(
       new AdapterHelper.UpdateOp(AdapterHelper.UpdateOp.REMOVE, index, count));
 }
 void preProcess() {
   for (MockViewHolder vh : mViewHolders) {
     final int ind = mTestAdapter.mItems.indexOf(vh.mItem);
     assertEquals(
         "actual adapter position should match",
         ind,
         mAdapterHelper.applyPendingUpdatesToPosition(vh.mPosition));
   }
   mAdapterHelper.preProcess();
   for (int i = 0; i < mPreProcessClone.mItems.size(); i++) {
     TestAdapter.Item item = mPreProcessClone.mItems.get(i);
     final int preLayoutIndex = mPreLayoutItems.indexOf(item);
     final int endIndex = mTestAdapter.mItems.indexOf(item);
     if (preLayoutIndex != -1) {
       assertEquals(
           "find position offset should work properly for existing elements"
               + i
               + " at pre layout position "
               + preLayoutIndex
               + " and post layout position "
               + endIndex,
           endIndex,
           mAdapterHelper.findPositionOffset(preLayoutIndex));
     }
   }
   // make sure visible view holders still have continuous positions
   final StringBuilder vhLogBuilder = new StringBuilder();
   for (ViewHolder vh : mViewHolders) {
     vhLogBuilder.append("\n").append(vh.toString());
   }
   if (mViewHolders.size() > 0) {
     final String vhLog = vhLogBuilder.toString();
     final int start = mViewHolders.get(0).getLayoutPosition();
     for (int i = 1; i < mViewHolders.size(); i++) {
       assertEquals(
           "view holder positions should be continious in pre-layout" + vhLog,
           start + i,
           mViewHolders.get(i).getLayoutPosition());
     }
   }
   mAdapterHelper.consumePostponedUpdates();
   // now assert these two adapters have identical data.
   mPreProcessClone.applyOps(mFirstPassUpdates, mTestAdapter);
   mPreProcessClone.applyOps(mSecondPassUpdates, mTestAdapter);
   assertAdaptersEqual(mTestAdapter, mPreProcessClone);
 }
 @Test
 public void testSinglePass() {
   setupBasic(10, 2, 3);
   add(2, 1);
   rm(1, 2);
   add(1, 5);
   mAdapterHelper.consumeUpdatesInOnePass();
   assertDispatch(0, 3);
 }
 public void add(int index, int count) {
   for (int i = 0; i < count; i++) {
     Item item = new Item();
     mPendingAdded.add(item);
     mItems.add(index + i, item);
   }
   mAdapterHelper.addUpdateOp(
       new AdapterHelper.UpdateOp(AdapterHelper.UpdateOp.ADD, index, count));
 }
 @Test
 public void testChangeAll() throws Exception {
   try {
     setupBasic(5, 0, 3);
     up(0, 5);
     mAdapterHelper.preProcess();
   } catch (Throwable t) {
     throw new Exception(mLog.toString());
   }
 }
 public void move(int from, int to) {
   mItems.add(to, mItems.remove(from));
   mAdapterHelper.addUpdateOp(new AdapterHelper.UpdateOp(AdapterHelper.UpdateOp.MOVE, from, to));
 }