private void assertAdaptersEqual(TestAdapter a1, TestAdapter a2) {
   assertEquals(a1.mItems.size(), a2.mItems.size());
   for (int i = 0; i < a1.mItems.size(); i++) {
     TestAdapter.Item item = a1.mItems.get(i);
     assertSame(item, a2.mItems.get(i));
     assertEquals(0, item.getUpdateCount());
   }
   assertEquals(0, a1.mPendingAdded.size());
   assertEquals(0, a2.mPendingAdded.size());
 }
 @Test
 public void testAddProcess() {
   setupBasic(0, 0, 0);
   add(0, 1);
   preProcess();
   assertEquals(0, mAdapterHelper.mPendingUpdates.size());
 }
 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 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));
 }
 void assertDispatch(int firstPass, int secondPass) {
   assertEquals(firstPass, mFirstPassUpdates.size());
   assertEquals(secondPass, mSecondPassUpdates.size());
 }
 public void assertOps(List<AdapterHelper.UpdateOp> actual, AdapterHelper.UpdateOp... expected) {
   assertEquals(expected.length, actual.size());
   for (int i = 0; i < expected.length; i++) {
     assertEquals(expected[i], actual.get(i));
   }
 }
 @Test
 public void testDeleteCount() {
   setupBasic(1, 0, 0);
   rm(0, 1);
   assertEquals(1, mAdapterHelper.mPendingUpdates.size());
 }
 @Test
 public void testAddCount() {
   setupBasic(0, 0, 0);
   add(0, 1);
   assertEquals(1, mAdapterHelper.mPendingUpdates.size());
 }