18ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar/*
2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 The Android Open Source Project
38ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar *
48ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
58ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar * you may not use this file except in compliance with the License.
68ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar * You may obtain a copy of the License at
78ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar *
88ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
98ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar *
108ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar * Unless required by applicable law or agreed to in writing, software
118ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
128ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar * See the License for the specific language governing permissions and
148ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar * limitations under the License.
158ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar */
168ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.recyclerview.widget;
188ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
19ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.recyclerview.widget.RecyclerView.ViewHolder;
20754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikas
21ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyarimport static org.junit.Assert.assertEquals;
22fa39e2bca1b284ad7c931d9194287770b7b507faAurimas Liutikasimport static org.junit.Assert.assertFalse;
23ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyarimport static org.junit.Assert.assertSame;
24ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar
25754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport android.support.test.filters.SmallTest;
26754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport android.view.View;
27754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikas
28be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyarimport org.junit.Before;
29ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyarimport org.junit.Rule;
30be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyarimport org.junit.Test;
31ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyarimport org.junit.rules.TestWatcher;
32ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyarimport org.junit.runner.Description;
33be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyarimport org.junit.runner.RunWith;
34be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyarimport org.junit.runners.JUnit4;
35ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyarimport org.mockito.Mockito;
36be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar
378ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyarimport java.util.ArrayList;
388ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyarimport java.util.LinkedList;
398ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyarimport java.util.List;
408ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyarimport java.util.Queue;
418ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyarimport java.util.Random;
428ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyarimport java.util.concurrent.atomic.AtomicInteger;
438ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
44be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar@RunWith(JUnit4.class)
45f1b288ec2104488f4a92e911b0ab80c8f0f3e9d1Yigit Boyar@SmallTest
46ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyarpublic class AdapterHelperTest {
478ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
481faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    private static final boolean DEBUG = false;
491faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
50245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar    private boolean mCollectLogs = false;
51245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar
521faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    private static final String TAG = "AHT";
538ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
54ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    private List<MockViewHolder> mViewHolders;
558ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
56ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    private AdapterHelper mAdapterHelper;
578ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
58ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    private List<AdapterHelper.UpdateOp> mFirstPassUpdates, mSecondPassUpdates;
598ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
608ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    TestAdapter mTestAdapter;
618ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
62ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    private TestAdapter mPreProcessClone;
63ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    // we clone adapter pre-process to run operations to see result
648ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
651faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    private List<TestAdapter.Item> mPreLayoutItems;
661faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
67245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar    private StringBuilder mLog = new StringBuilder();
68245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar
69ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    @Rule
70ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    public TestWatcher reportErrorLog = new TestWatcher() {
71ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar        @Override
72ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar        protected void failed(Throwable e, Description description) {
73ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar            System.out.println(mLog.toString());
74245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar        }
75ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar
76ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar        @Override
77ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar        protected void succeeded(Description description) {
78ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar        }
79ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    };
80245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar
81be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Before
82be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    public void cleanState() {
83245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar        mLog.setLength(0);
84ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar        mPreLayoutItems = new ArrayList<>();
85ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar        mViewHolders = new ArrayList<>();
86ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar        mFirstPassUpdates = new ArrayList<>();
87ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar        mSecondPassUpdates = new ArrayList<>();
88e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        mPreProcessClone = null;
898ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        mAdapterHelper = new AdapterHelper(new AdapterHelper.Callback() {
908ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            @Override
918ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            public RecyclerView.ViewHolder findViewHolder(int position) {
928ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                for (ViewHolder vh : mViewHolders) {
93a910619e83d0052e1d81aa5fe532821a2f99d76cYigit Boyar                    if (vh.mPosition == position && !vh.isRemoved()) {
948ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                        return vh;
958ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    }
968ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                }
978ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                return null;
988ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
998ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1008ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            @Override
1018ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            public void offsetPositionsForRemovingInvisible(int positionStart, int itemCount) {
1028ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                final int positionEnd = positionStart + itemCount;
1038ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                for (ViewHolder holder : mViewHolders) {
1048ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    if (holder.mPosition >= positionEnd) {
1058ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                        holder.offsetPosition(-itemCount, true);
1068ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    } else if (holder.mPosition >= positionStart) {
1074b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar                        holder.flagRemovedAndOffsetPosition(positionStart - 1, -itemCount, true);
1088ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    }
1098ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                }
1108ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
1118ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1128ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            @Override
1138ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            public void offsetPositionsForRemovingLaidOutOrNewView(int positionStart,
1148ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    int itemCount) {
1158ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                final int positionEnd = positionStart + itemCount;
1168ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                for (ViewHolder holder : mViewHolders) {
1178ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    if (holder.mPosition >= positionEnd) {
1188ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                        holder.offsetPosition(-itemCount, false);
1198ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    } else if (holder.mPosition >= positionStart) {
1204b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar                        holder.flagRemovedAndOffsetPosition(positionStart - 1, -itemCount, false);
1218ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    }
1228ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                }
1238ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
1248ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1258ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            @Override
12621b345f101abc385496f42d250e580d21f1287b6Dake Gu            public void markViewHoldersUpdated(int positionStart, int itemCount, Object payload) {
1278ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                final int positionEnd = positionStart + itemCount;
1288ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                for (ViewHolder holder : mViewHolders) {
1298ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    if (holder.mPosition >= positionStart && holder.mPosition < positionEnd) {
1308ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                        holder.addFlags(ViewHolder.FLAG_UPDATE);
13121b345f101abc385496f42d250e580d21f1287b6Dake Gu                        holder.addChangePayload(payload);
1328ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    }
1338ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                }
1348ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
1358ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1368ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            @Override
1378ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            public void onDispatchFirstPass(AdapterHelper.UpdateOp updateOp) {
1381faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                if (DEBUG) {
139245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar                    log("first pass:" + updateOp.toString());
1401faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                }
14116e5adf5416248d97f2aeaa9d5e17bb5093130ebYigit Boyar                for (ViewHolder viewHolder : mViewHolders) {
142be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar                    for (int i = 0; i < updateOp.itemCount; i++) {
1434b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar                        // events are dispatched before view holders are updated for consistency
144fa39e2bca1b284ad7c931d9194287770b7b507faAurimas Liutikas                        assertFalse("update op should not match any existing view holders",
145115ba0c7b2a14aa4cd0273952195e1d8f6468f87Yigit Boyar                                viewHolder.getLayoutPosition() == updateOp.positionStart + i);
146c50c4cad31d73e574b27bb3d7581542975e37263Yigit Boyar                    }
14716e5adf5416248d97f2aeaa9d5e17bb5093130ebYigit Boyar                }
148c50c4cad31d73e574b27bb3d7581542975e37263Yigit Boyar
1498ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                mFirstPassUpdates.add(updateOp);
1508ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
1518ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1528ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            @Override
1538ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            public void onDispatchSecondPass(AdapterHelper.UpdateOp updateOp) {
1541faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                if (DEBUG) {
155245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar                    log("second pass:" + updateOp.toString());
1561faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                }
1578ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                mSecondPassUpdates.add(updateOp);
1588ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
1598ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1608ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            @Override
1618ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            public void offsetPositionsForAdd(int positionStart, int itemCount) {
1628ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                for (ViewHolder holder : mViewHolders) {
1638ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    if (holder != null && holder.mPosition >= positionStart) {
1648ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                        holder.offsetPosition(itemCount, false);
1658ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    }
1668ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                }
1678ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
1681faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
1691faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar            @Override
1701faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar            public void offsetPositionsForMove(int from, int to) {
1711faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                final int start, end, inBetweenOffset;
1721faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                if (from < to) {
1731faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                    start = from;
1741faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                    end = to;
1751faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                    inBetweenOffset = -1;
1761faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                } else {
1771faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                    start = to;
1781faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                    end = from;
1791faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                    inBetweenOffset = 1;
1801faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                }
1811faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                for (ViewHolder holder : mViewHolders) {
1821faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                    if (holder == null || holder.mPosition < start || holder.mPosition > end) {
1831faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                        continue;
1841faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                    }
1854b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar                    if (holder.mPosition == from) {
1864b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar                        holder.offsetPosition(to - from, false);
1874b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar                    } else {
1884b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar                        holder.offsetPosition(inBetweenOffset, false);
1894bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar                    }
1904bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar                }
1914bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar            }
1924b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        }, true);
1938ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
1948ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
195245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar    void log(String msg) {
196245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar        if (mCollectLogs) {
197245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar            mLog.append(msg).append("\n");
198245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar        } else {
199ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar            System.out.println(TAG + ":" + msg);
200245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar        }
201245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar    }
202245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar
2038ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    void setupBasic(int count, int visibleStart, int visibleCount) {
2041faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        if (DEBUG) {
205245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar            log("setupBasic(" + count + "," + visibleStart + "," + visibleCount + ");");
2061faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        }
2078ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        mTestAdapter = new TestAdapter(count, mAdapterHelper);
2088ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        for (int i = 0; i < visibleCount; i++) {
2098ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            addViewHolder(visibleStart + i);
2108ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        }
2118ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        mPreProcessClone = mTestAdapter.createCopy();
2128ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
2138ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
214115ba0c7b2a14aa4cd0273952195e1d8f6468f87Yigit Boyar    private void addViewHolder(int position) {
215ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar        MockViewHolder viewHolder = new MockViewHolder();
216115ba0c7b2a14aa4cd0273952195e1d8f6468f87Yigit Boyar        viewHolder.mPosition = position;
217115ba0c7b2a14aa4cd0273952195e1d8f6468f87Yigit Boyar        viewHolder.mItem = mTestAdapter.mItems.get(position);
2188ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        mViewHolders.add(viewHolder);
2198ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
2208ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
221be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
222e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar    public void testChangeAll() throws Exception {
223e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        try {
224e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar            setupBasic(5, 0, 3);
225e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar            up(0, 5);
226e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar            mAdapterHelper.preProcess();
227e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        } catch (Throwable t) {
228e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar            throw new Exception(mLog.toString());
229e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        }
230e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar    }
231e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar
232be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
2334bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar    public void testFindPositionOffsetInPreLayout() {
2344bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar        setupBasic(50, 25, 10);
2354bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar        rm(24, 5);
2364bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar        mAdapterHelper.preProcess();
2374bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar        // since 25 is invisible, we offset by one while checking
2384bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar        assertEquals("find position for view 23",
2394bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar                23, mAdapterHelper.findPositionOffset(23));
2404bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar        assertEquals("find position for view 24",
2414bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar                -1, mAdapterHelper.findPositionOffset(24));
2424bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar        assertEquals("find position for view 25",
2434bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar                -1, mAdapterHelper.findPositionOffset(25));
2444bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar        assertEquals("find position for view 26",
2454bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar                -1, mAdapterHelper.findPositionOffset(26));
2464bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar        assertEquals("find position for view 27",
2474bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar                -1, mAdapterHelper.findPositionOffset(27));
2484bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar        assertEquals("find position for view 28",
2494bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar                24, mAdapterHelper.findPositionOffset(28));
2504bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar        assertEquals("find position for view 29",
2514bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar                25, mAdapterHelper.findPositionOffset(29));
2524bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar    }
2534bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar
254be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
2554143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    public void testNotifyAfterPre() {
2564143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        setupBasic(10, 2, 3);
2574143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        add(2, 1);
2584143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        mAdapterHelper.preProcess();
2594143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        add(3, 1);
2604143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        mAdapterHelper.consumeUpdatesInOnePass();
2614143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        mPreProcessClone.applyOps(mFirstPassUpdates, mTestAdapter);
2624143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        mPreProcessClone.applyOps(mSecondPassUpdates, mTestAdapter);
2634143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar        assertAdaptersEqual(mTestAdapter, mPreProcessClone);
2644143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    }
2654143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar
2664143554adb9b31b700b6876a251a64419e6111e2Yigit Boyar    @Test
2678ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    public void testSinglePass() {
2688ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        setupBasic(10, 2, 3);
2698ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        add(2, 1);
2708ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(1, 2);
2718ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        add(1, 5);
2728ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        mAdapterHelper.consumeUpdatesInOnePass();
2738ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertDispatch(0, 3);
2748ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
2758ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
276be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
2778ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    public void testDeleteVisible() {
2788ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        setupBasic(10, 2, 3);
2798ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(2, 1);
2808ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        preProcess();
2818ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertDispatch(0, 1);
2828ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
2838ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
284be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
2858ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    public void testDeleteInvisible() {
2868ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        setupBasic(10, 3, 4);
2878ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(2, 1);
2888ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        preProcess();
2898ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertDispatch(1, 0);
2908ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
2918ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
292be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
2938ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    public void testAddCount() {
2948ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        setupBasic(0, 0, 0);
2958ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        add(0, 1);
2968ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertEquals(1, mAdapterHelper.mPendingUpdates.size());
2978ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
2988ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
299be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
3008ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    public void testDeleteCount() {
3018ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        setupBasic(1, 0, 0);
3028ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(0, 1);
3038ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertEquals(1, mAdapterHelper.mPendingUpdates.size());
3048ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
3058ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
306be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
3078ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    public void testAddProcess() {
3088ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        setupBasic(0, 0, 0);
3098ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        add(0, 1);
3108ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        preProcess();
3118ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertEquals(0, mAdapterHelper.mPendingUpdates.size());
3128ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
3138ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
314be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
3158ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    public void testAddRemoveSeparate() {
3168ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        setupBasic(10, 2, 2);
3178ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        add(6, 1);
3188ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(5, 1);
3198ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        preProcess();
3208ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertDispatch(1, 1);
3218ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
3228ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
323be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
3241faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario1() {
3258ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        setupBasic(10, 3, 2);
3268ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(4, 1);
3278ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(3, 1);
3288ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(3, 1);
3298ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        preProcess();
3308ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertDispatch(1, 2);
3318ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
3328ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
333be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
3348ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    public void testDivideDelete() {
3358ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        setupBasic(10, 3, 4);
3368ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(2, 2);
3378ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        preProcess();
3388ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertDispatch(1, 1);
3398ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
3408ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
341be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
3421faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario2() {
3438ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        setupBasic(10, 3, 3); // 3-4-5
3448ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        add(4, 2); // 3 a b 4 5
3458ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(0, 1); // (0) 3(2) a(3) b(4) 4(3) 5(4)
3468ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(1, 3); // (1,2) (x) a(1) b(2) 4(3)
3478ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        preProcess();
3488ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertDispatch(2, 2);
3498ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
3508ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
351be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
3521faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario3() {
3538ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        setupBasic(10, 2, 2);
3548ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(0, 5);
3558ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        preProcess();
3568ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertDispatch(2, 1);
3578ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertOps(mFirstPassUpdates, rmOp(0, 2), rmOp(2, 1));
3588ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertOps(mSecondPassUpdates, rmOp(0, 2));
3598ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
3601faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    // TODO test MOVE then remove items in between.
3611faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    // TODO test MOVE then remove it, make sure it is not dispatched
3628ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
363be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
3641faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario4() {
3658ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        setupBasic(5, 0, 5);
3668ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        // 0 1 2 3 4
3678ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        // 0 1 2 a b 3 4
3688ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        // 0 2 a b 3 4
3698ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        // 0 c d 2 a b 3 4
3708ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        // 0 c d 2 a 4
3718ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        // c d 2 a 4
3728ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        // pre: 0 1 2 3 4
3738ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        add(3, 2);
3748ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(1, 1);
3758ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        add(1, 2);
3768ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(5, 2);
3778ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(0, 1);
3788ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        preProcess();
3798ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
3808ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
381be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
3821faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario5() {
3838ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        setupBasic(5, 0, 5);
3848ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        // 0 1 2 3 4
3858ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        // 0 1 2 a b 3 4
3868ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        // 0 1 b 3 4
3878ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        // pre: 0 1 2 3 4
3888ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        // pre w/ adap: 0 1 2 b 3 4
3898ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        add(3, 2);
3908ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        rm(2, 2);
3918ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        preProcess();
3928ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
3938ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
394be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
3951faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario6() {
3961faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar//        setupBasic(47, 19, 24);
3971faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar//        mv(11, 12);
3981faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar//        add(24, 16);
3991faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar//        rm(9, 3);
4001faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        setupBasic(10, 5, 3);
4011faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(2, 3);
4021faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        add(6, 4);
4031faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(4, 1);
4041faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
4051faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
4061faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
407be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
4081faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario8() {
4091faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        setupBasic(68, 51, 13);
4101faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(22, 11);
4111faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(22, 52);
4121faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(37, 19);
4131faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        add(12, 38);
4141faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
4151faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
4161faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
417be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
4181faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario9() {
4191faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        setupBasic(44, 3, 7);
4201faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        add(7, 21);
4211faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(31, 3);
4221faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(32, 11);
4231faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(29, 5);
4241faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(30, 32);
4251faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        add(25, 32);
4261faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(15, 66);
4271faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
4281faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
4291faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
430be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
4311faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario10() {
4321faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        setupBasic(14, 10, 3);
4331faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(4, 4);
4341faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        add(5, 11);
4351faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(5, 18);
4361faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(2, 9);
4371faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
4381faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
4391faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
440be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
4411faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario11() {
4421faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        setupBasic(78, 3, 64);
4431faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(34, 28);
4441faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        add(1, 11);
4451faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(9, 74);
4461faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
4471faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
4481faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
449be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
4501faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario12() {
4511faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        setupBasic(38, 9, 7);
4521faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(26, 3);
4531faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(29, 15);
4541faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(30, 1);
4551faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
4561faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
4571faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
458be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
4591faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario13() {
4601faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        setupBasic(49, 41, 3);
4611faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(30, 13);
4621faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        add(4, 10);
4631faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(3, 38);
4641faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(20, 17);
4651faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(18, 23);
4661faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
4671faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
4681faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
469be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
4701faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario14() {
4711faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        setupBasic(24, 3, 11);
4721faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(2, 15);
4731faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(2, 1);
4741faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        add(2, 34);
4751faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        add(11, 3);
4761faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(10, 25);
4771faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(13, 6);
4781faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(4, 4);
4791faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(6, 4);
4801faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
4811faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
4821faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
483be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
4841faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario15() {
4851faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        setupBasic(10, 8, 1);
4861faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(6, 1);
4871faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(1, 4);
4881faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(3, 1);
4891faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
4901faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
4911faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
492be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
4931faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario16() {
4941faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        setupBasic(10, 3, 3);
4951faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(2, 1);
4961faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(1, 7);
4971faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(0, 1);
4981faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
4991faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
5001faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
501be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
5021faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario17() {
5031faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        setupBasic(10, 8, 1);
5041faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(1, 0);
5051faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(5, 1);
5061faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(1, 7);
5071faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
5081faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
5091faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
510be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
511ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    public void testScenario18() {
5121faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        setupBasic(10, 1, 4);
5131faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        add(2, 11);
5141faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(16, 1);
5151faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        add(3, 1);
5161faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        rm(9, 10);
5171faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
5181faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
5191faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
520be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
5211faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario19() {
522e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        setupBasic(10, 8, 1);
523e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        mv(9, 7);
524e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        mv(9, 3);
525be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(5, 4);
5261faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
5271faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
5281faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
529be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
5301faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario20() {
531be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 7, 1);
532be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(9, 1);
533be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(3, 9);
534be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(7, 2);
5351faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
5361faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
5371faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
538be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
5391faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario21() {
540be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 5, 2);
541be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(1, 0);
542be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(9, 1);
543be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(2, 3);
5441faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
5451faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
5461faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
547be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
5481faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario22() {
549be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 7, 2);
550e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        add(2, 16);
551be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(20, 9);
552be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(17, 6);
5531faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
5541faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
5551faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
556be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
5571faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario23() {
558be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 5, 3);
559e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        mv(9, 6);
560e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        add(4, 15);
561be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(21, 3);
5621faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
5631faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
5641faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
565be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
5661faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario24() {
567be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 1, 6);
568e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        add(6, 5);
569e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        mv(14, 6);
570be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(7, 6);
5711faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
5721faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
5731faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
574be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
5751faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario25() {
576be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 3, 4);
577be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(3, 9);
578be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(5, 4);
5791faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
5801faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
5811faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
582be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
5834b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenario25a() {
584be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 3, 4);
585be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(6, 4);
586be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(3, 5);
5874b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        preProcess();
5884b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
5894b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
590be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
5911faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testScenario26() {
592be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 4, 4);
593be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(3, 5);
594e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        mv(2, 0);
595be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(1, 0);
596e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        rm(1, 1);
597e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        mv(0, 2);
5981faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
5991faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
6001faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
601be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
602d7e2f2ab1d253133fa54f309e74a7ee384c33971Yigit Boyar    public void testScenario27() {
603e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        setupBasic(10, 0, 3);
604be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(9, 4);
605be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(8, 4);
606e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        add(7, 6);
607e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        rm(5, 5);
6081faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
6091faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
6101faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
611be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
612245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar    public void testScenerio28() {
613be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 4, 1);
614e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        mv(8, 6);
615e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        rm(8, 1);
616be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(7, 5);
617e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        rm(3, 3);
618be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(1, 4);
619245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar        preProcess();
620245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar    }
621245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar
622be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
623e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar    public void testScenerio29() {
624e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        setupBasic(10, 6, 3);
625e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        mv(3, 6);
626be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(6, 2);
627e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        add(5, 5);
628e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar    }
629e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar
630be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
631ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    public void testScenerio30() {
632e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        mCollectLogs = true;
633be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 3, 1);
634be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(3, 2);
635be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(2, 5);
636e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        preProcess();
637e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar    }
638e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar
639be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
640ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    public void testScenerio31() {
6414b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        mCollectLogs = true;
642be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 3, 1);
643be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(3, 1);
644be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(2, 3);
6454b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        preProcess();
6464b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
6474b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
648be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
6494b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenerio32() {
650be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 8, 1);
651be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        add(9, 2);
652be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        add(7, 39);
653be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(0, 39);
654be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(36, 20);
655be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        add(1, 48);
656be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(22, 98);
657be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(96, 29);
658be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(36, 29);
659be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        add(60, 36);
660be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        add(127, 34);
661be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(142, 22);
662be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(12, 69);
663be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(116, 13);
664be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(118, 19);
665be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(94, 69);
666be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(98, 21);
667be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        add(89, 18);
668be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(94, 70);
669be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(71, 8);
670be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(54, 26);
671be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        add(2, 20);
672be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(78, 84);
673be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(56, 2);
674be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(1, 79);
675be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(76, 7);
676be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(57, 12);
677be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(30, 27);
678be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        add(24, 13);
679be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        add(21, 5);
680be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(11, 27);
681be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(32, 1);
682be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(0, 5);
683be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(14, 9);
684be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(15, 12);
685be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(19, 1);
686be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(7, 1);
687be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(10, 4);
688be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(4, 3);
689be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(16, 1);
690be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(13, 5);
691be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(2, 8);
692be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        add(10, 19);
693be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        add(15, 42);
6944b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        preProcess();
6954b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
6964b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
697be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
6984b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenerio33() throws Throwable {
6994b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        try {
7004b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            mCollectLogs = true;
7014b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            setupBasic(10, 7, 1);
7024b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            mv(0, 6);
7034b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            up(0, 7);
7044b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            preProcess();
7054b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        } catch (Throwable t) {
7064b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            throw new Throwable(t.getMessage() + "\n" + mLog.toString());
7074b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        }
7084b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
7094b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
710be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
7114b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenerio34() {
712be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 6, 1);
713be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(9, 7);
714be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(5, 2);
715be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(4, 3);
7164b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        preProcess();
7174b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
7184b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
719be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
7204b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenerio35() {
721be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 4, 4);
722be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(1, 4);
723be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(2, 7);
724be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(0, 1);
7254b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        preProcess();
7264b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
7274b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
728be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
7294b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenerio36() {
730be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 7, 2);
731be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(4, 1);
732be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(1, 6);
733be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(4, 4);
7344b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        preProcess();
7354b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
7364b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
737be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
7384b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenerio37() throws Throwable {
7394b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        try {
7404b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            mCollectLogs = true;
7414b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            setupBasic(10, 5, 2);
7424b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            mv(3, 6);
7434b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            rm(4, 4);
7444b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            rm(3, 2);
7454b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            preProcess();
7464b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        } catch (Throwable t) {
7474b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            throw new Throwable(t.getMessage() + "\n" + mLog.toString());
7484b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        }
7494b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
7504b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
751be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
7524b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenerio38() {
753be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 2, 2);
754be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        add(0, 24);
755be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(26, 4);
756be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(1, 24);
7574b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        preProcess();
7584b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
7594b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
760be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
7614b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenerio39() {
762be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 7, 1);
763be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(0, 2);
764be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(8, 1);
765be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(2, 6);
7664b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        preProcess();
7674b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
7684b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
769be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
7704b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenerio40() {
771be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 5, 3);
772be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(5, 4);
773be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(0, 5);
774be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(2, 3);
7754b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        preProcess();
7764b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
7774b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
778be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
7794b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenerio41() {
780be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 7, 2);
781be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(4, 9);
782be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(0, 6);
783be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(0, 1);
7844b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        preProcess();
7854b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
7864b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
787be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
7884b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenerio42() {
789be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 6, 2);
790be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(5, 9);
791be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(5, 1);
792be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(2, 6);
7934b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        preProcess();
7944b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
7954b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
796be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
7974b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenerio43() {
798be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 1, 6);
799be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(6, 8);
800be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(3, 5);
8014b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        up(3, 1);
8024b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        preProcess();
8034b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
8044b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
805be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
8064b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenerio44() {
807be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 5, 2);
808be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(6, 4);
809be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(4, 1);
810be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(5, 3);
8114b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        preProcess();
8124b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
8134b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
814be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
8154b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenerio45() {
816be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 4, 2);
8174b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        rm(1, 4);
8184b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        preProcess();
8194b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
8204b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
821be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
8224b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    public void testScenerio46() {
823be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        setupBasic(10, 4, 3);
824be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        up(6, 1);
825be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        mv(8, 0);
826be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        rm(2, 7);
8274b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        preProcess();
8284b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar    }
8294b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
830be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
8311faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    public void testMoveAdded() {
8321faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        setupBasic(10, 2, 2);
8331faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        add(3, 5);
8341faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mv(4, 2);
8351faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        preProcess();
8361faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
8371faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
838be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
83921b345f101abc385496f42d250e580d21f1287b6Dake Gu    public void testPayloads() {
84021b345f101abc385496f42d250e580d21f1287b6Dake Gu        setupBasic(10, 2, 2);
84121b345f101abc385496f42d250e580d21f1287b6Dake Gu        up(3, 3, "payload");
84221b345f101abc385496f42d250e580d21f1287b6Dake Gu        preProcess();
84321b345f101abc385496f42d250e580d21f1287b6Dake Gu        assertOps(mFirstPassUpdates, upOp(4, 2, "payload"));
84421b345f101abc385496f42d250e580d21f1287b6Dake Gu        assertOps(mSecondPassUpdates, upOp(3, 1, "payload"));
84521b345f101abc385496f42d250e580d21f1287b6Dake Gu    }
84621b345f101abc385496f42d250e580d21f1287b6Dake Gu
84721b345f101abc385496f42d250e580d21f1287b6Dake Gu    @Test
848245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar    public void testRandom() throws Throwable {
849245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar        mCollectLogs = true;
8508ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        Random random = new Random(System.nanoTime());
85190ca3086dbf66ad6bb8840e46ec8524a705e1c18Yigit Boyar        for (int i = 0; i < 100; i++) {
852245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar            try {
853ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar                log("running random test " + i);
8544b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar                randomTest(random, Math.max(40, 10 + nextInt(random, i)));
855245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar            } catch (Throwable t) {
8564b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar                throw new Throwable("failure at random test " + i + "\n" + t.getMessage()
8574b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar                        + "\n" + mLog.toString(), t);
858245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar            }
8598ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        }
8608ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
8618ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
862ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    private void randomTest(Random random, int opCount) {
8638ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        cleanState();
8641faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        if (DEBUG) {
865245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar            log("randomTest");
8661faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        }
867e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        final int count = 10;// + nextInt(random,100);
868e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        final int start = nextInt(random, count - 1);
869e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        final int layoutCount = Math.max(1, nextInt(random, count - start));
8708ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        setupBasic(count, start, layoutCount);
8718ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
8728ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        while (opCount-- > 0) {
87321b345f101abc385496f42d250e580d21f1287b6Dake Gu            final int op = nextInt(random, 5);
8748ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            switch (op) {
8751faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                case 0:
8768ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    if (mTestAdapter.mItems.size() > 1) {
877e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar                        int s = nextInt(random, mTestAdapter.mItems.size() - 1);
878e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar                        int len = Math.max(1, nextInt(random, mTestAdapter.mItems.size() - s));
8798ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                        rm(s, len);
8808ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    }
8818ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    break;
8821faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                case 1:
8831faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                    int s = mTestAdapter.mItems.size() == 0 ? 0 :
884e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar                            nextInt(random, mTestAdapter.mItems.size());
885be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar                    add(s, nextInt(random, 50));
8868ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    break;
8871faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                case 2:
8881faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                    if (mTestAdapter.mItems.size() >= 2) {
889e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar                        int from = nextInt(random, mTestAdapter.mItems.size());
8901faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                        int to;
8911faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                        do {
892e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar                            to = nextInt(random, mTestAdapter.mItems.size());
8931faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                        } while (to == from);
8941faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                        mv(from, to);
8951faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                    }
896e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar                    break;
897e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar                case 3:
898e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar                    if (mTestAdapter.mItems.size() > 1) {
899e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar                        s = nextInt(random, mTestAdapter.mItems.size() - 1);
900e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar                        int len = Math.max(1, nextInt(random, mTestAdapter.mItems.size() - s));
901e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar                        up(s, len);
902e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar                    }
903e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar                    break;
90421b345f101abc385496f42d250e580d21f1287b6Dake Gu                case 4:
90521b345f101abc385496f42d250e580d21f1287b6Dake Gu                    if (mTestAdapter.mItems.size() > 1) {
90621b345f101abc385496f42d250e580d21f1287b6Dake Gu                        s = nextInt(random, mTestAdapter.mItems.size() - 1);
90721b345f101abc385496f42d250e580d21f1287b6Dake Gu                        int len = Math.max(1, nextInt(random, mTestAdapter.mItems.size() - s));
90821b345f101abc385496f42d250e580d21f1287b6Dake Gu                        up(s, len, Integer.toString(s));
90921b345f101abc385496f42d250e580d21f1287b6Dake Gu                    }
91021b345f101abc385496f42d250e580d21f1287b6Dake Gu                    break;
9118ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
9128ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        }
9138ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        preProcess();
9148ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
9158ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
916ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    private int nextInt(Random random, int n) {
917e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        if (n == 0) {
918e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar            return 0;
919e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        }
920e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        return random.nextInt(n);
921e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar    }
922e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar
923ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    private void assertOps(List<AdapterHelper.UpdateOp> actual,
9248ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            AdapterHelper.UpdateOp... expected) {
9258ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertEquals(expected.length, actual.size());
9268ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        for (int i = 0; i < expected.length; i++) {
9278ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            assertEquals(expected[i], actual.get(i));
9288ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        }
9298ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
9308ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
931ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    private void assertDispatch(int firstPass, int secondPass) {
9328ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertEquals(firstPass, mFirstPassUpdates.size());
9338ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertEquals(secondPass, mSecondPassUpdates.size());
9348ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
9358ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
936ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    private void preProcess() {
937be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        for (MockViewHolder vh : mViewHolders) {
938115ba0c7b2a14aa4cd0273952195e1d8f6468f87Yigit Boyar            final int ind = mTestAdapter.mItems.indexOf(vh.mItem);
939115ba0c7b2a14aa4cd0273952195e1d8f6468f87Yigit Boyar            assertEquals("actual adapter position should match", ind,
940115ba0c7b2a14aa4cd0273952195e1d8f6468f87Yigit Boyar                    mAdapterHelper.applyPendingUpdatesToPosition(vh.mPosition));
941115ba0c7b2a14aa4cd0273952195e1d8f6468f87Yigit Boyar        }
9428ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        mAdapterHelper.preProcess();
9431faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        for (int i = 0; i < mPreProcessClone.mItems.size(); i++) {
9441faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar            TestAdapter.Item item = mPreProcessClone.mItems.get(i);
9451faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar            final int preLayoutIndex = mPreLayoutItems.indexOf(item);
9461faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar            final int endIndex = mTestAdapter.mItems.indexOf(item);
9474bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar            if (preLayoutIndex != -1) {
9484bacf13ec17763ba2e2d049d32a4a1dcca77a433Yigit Boyar                assertEquals("find position offset should work properly for existing elements" + i
9491faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                        + " at pre layout position " + preLayoutIndex + " and post layout position "
9501faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                        + endIndex, endIndex, mAdapterHelper.findPositionOffset(preLayoutIndex));
9511faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar            }
9521faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        }
9534b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        // make sure visible view holders still have continuous positions
9544b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        final StringBuilder vhLogBuilder = new StringBuilder();
9554b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        for (ViewHolder vh : mViewHolders) {
9564b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            vhLogBuilder.append("\n").append(vh.toString());
9574b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        }
9584b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        if (mViewHolders.size() > 0) {
9594b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            final String vhLog = vhLogBuilder.toString();
960115ba0c7b2a14aa4cd0273952195e1d8f6468f87Yigit Boyar            final int start = mViewHolders.get(0).getLayoutPosition();
9614b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            for (int i = 1; i < mViewHolders.size(); i++) {
9624b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar                assertEquals("view holder positions should be continious in pre-layout" + vhLog,
963115ba0c7b2a14aa4cd0273952195e1d8f6468f87Yigit Boyar                        start + i, mViewHolders.get(i).getLayoutPosition());
9644b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar            }
9654b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar        }
9668ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        mAdapterHelper.consumePostponedUpdates();
9678ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        // now assert these two adapters have identical data.
9688ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        mPreProcessClone.applyOps(mFirstPassUpdates, mTestAdapter);
9698ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        mPreProcessClone.applyOps(mSecondPassUpdates, mTestAdapter);
9708ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertAdaptersEqual(mTestAdapter, mPreProcessClone);
9718ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
9728ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
9738ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    private void assertAdaptersEqual(TestAdapter a1, TestAdapter a2) {
9748ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertEquals(a1.mItems.size(), a2.mItems.size());
9758ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        for (int i = 0; i < a1.mItems.size(); i++) {
9768ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            TestAdapter.Item item = a1.mItems.get(i);
9778ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            assertSame(item, a2.mItems.get(i));
9788ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            assertEquals(0, item.getUpdateCount());
9798ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        }
9808ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertEquals(0, a1.mPendingAdded.size());
9818ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        assertEquals(0, a2.mPendingAdded.size());
9828ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
9838ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
984ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    private AdapterHelper.UpdateOp op(int cmd, int start, int count) {
98521b345f101abc385496f42d250e580d21f1287b6Dake Gu        return new AdapterHelper.UpdateOp(cmd, start, count, null);
98621b345f101abc385496f42d250e580d21f1287b6Dake Gu    }
98721b345f101abc385496f42d250e580d21f1287b6Dake Gu
988ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    private AdapterHelper.UpdateOp op(int cmd, int start, int count, Object payload) {
98921b345f101abc385496f42d250e580d21f1287b6Dake Gu        return new AdapterHelper.UpdateOp(cmd, start, count, payload);
9908ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
9918ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
992ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    private AdapterHelper.UpdateOp rmOp(int start, int count) {
9938ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        return op(AdapterHelper.UpdateOp.REMOVE, start, count);
9948ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
9958ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
996ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    private AdapterHelper.UpdateOp upOp(int start, int count, @SuppressWarnings
997ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar            ("SameParameterValue") Object payload) {
99821b345f101abc385496f42d250e580d21f1287b6Dake Gu        return op(AdapterHelper.UpdateOp.UPDATE, start, count, payload);
9998ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
10008ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
10018ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    void add(int start, int count) {
10021faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        if (DEBUG) {
1003245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar            log("add(" + start + "," + count + ");");
10041faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        }
10058ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        mTestAdapter.add(start, count);
10068ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
10078ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1008ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    private boolean isItemLaidOut(int pos) {
10091faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        for (ViewHolder viewHolder : mViewHolders) {
10101faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar            if (viewHolder.mOldPosition == pos) {
10111faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                return true;
10121faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar            }
10131faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        }
10141faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        return false;
10151faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
10161faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
10171faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    private void mv(int from, int to) {
10181faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        if (DEBUG) {
1019245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar            log("mv(" + from + "," + to + ");");
10201faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        }
10211faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        mTestAdapter.move(from, to);
10221faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar    }
10231faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar
1024ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar    private void rm(int start, int count) {
10251faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        if (DEBUG) {
1026245b9720dad47a694d16a1d0f48ad462bc27989fYigit Boyar            log("rm(" + start + "," + count + ");");
10271faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        }
10281faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        for (int i = start; i < start + count; i++) {
10291faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar            if (!isItemLaidOut(i)) {
10301faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                TestAdapter.Item item = mTestAdapter.mItems.get(i);
10311faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                mPreLayoutItems.remove(item);
10321faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar            }
10331faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        }
10348ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        mTestAdapter.remove(start, count);
10358ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
10368ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
10378ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    void up(int start, int count) {
1038e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        if (DEBUG) {
1039e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar            log("up(" + start + "," + count + ");");
1040e4fde6825bba479c9b030feb8f810694d46b2f06Yigit Boyar        }
10418ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        mTestAdapter.update(start, count);
10428ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
10438ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
104421b345f101abc385496f42d250e580d21f1287b6Dake Gu    void up(int start, int count, Object payload) {
104521b345f101abc385496f42d250e580d21f1287b6Dake Gu        if (DEBUG) {
104621b345f101abc385496f42d250e580d21f1287b6Dake Gu            log("up(" + start + "," + count + "," + payload + ");");
104721b345f101abc385496f42d250e580d21f1287b6Dake Gu        }
104821b345f101abc385496f42d250e580d21f1287b6Dake Gu        mTestAdapter.update(start, count, payload);
104921b345f101abc385496f42d250e580d21f1287b6Dake Gu    }
105021b345f101abc385496f42d250e580d21f1287b6Dake Gu
10518ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    static class TestAdapter {
10528ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
10538ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        List<Item> mItems;
10548ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
10558ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        final AdapterHelper mAdapterHelper;
10568ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
10578ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        Queue<Item> mPendingAdded;
10588ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
10598ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        public TestAdapter(int initialCount, AdapterHelper container) {
1060ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar            mItems = new ArrayList<>();
10618ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            mAdapterHelper = container;
1062ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar            mPendingAdded = new LinkedList<>();
10638ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            for (int i = 0; i < initialCount; i++) {
10648ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                mItems.add(new Item());
10658ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
10668ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        }
10678ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
10688ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        public void add(int index, int count) {
10698ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            for (int i = 0; i < count; i++) {
10708ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                Item item = new Item();
10718ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                mPendingAdded.add(item);
10728ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                mItems.add(index + i, item);
10738ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
10748ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            mAdapterHelper.addUpdateOp(new AdapterHelper.UpdateOp(
107521b345f101abc385496f42d250e580d21f1287b6Dake Gu                    AdapterHelper.UpdateOp.ADD, index, count, null
10768ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            ));
10778ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        }
10788ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
10791faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        public void move(int from, int to) {
10801faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar            mItems.add(to, mItems.remove(from));
10811faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar            mAdapterHelper.addUpdateOp(new AdapterHelper.UpdateOp(
108221b345f101abc385496f42d250e580d21f1287b6Dake Gu                    AdapterHelper.UpdateOp.MOVE, from, to, null
10831faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar            ));
10841faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar        }
1085be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar
10868ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        public void remove(int index, int count) {
10878ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            for (int i = 0; i < count; i++) {
10888ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                mItems.remove(index);
10898ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
10908ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            mAdapterHelper.addUpdateOp(new AdapterHelper.UpdateOp(
109121b345f101abc385496f42d250e580d21f1287b6Dake Gu                    AdapterHelper.UpdateOp.REMOVE, index, count, null
10928ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            ));
10938ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        }
10948ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
10958ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        public void update(int index, int count) {
109621b345f101abc385496f42d250e580d21f1287b6Dake Gu            update(index, count, null);
109721b345f101abc385496f42d250e580d21f1287b6Dake Gu        }
109821b345f101abc385496f42d250e580d21f1287b6Dake Gu
109921b345f101abc385496f42d250e580d21f1287b6Dake Gu        public void update(int index, int count, Object payload) {
11008ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            for (int i = 0; i < count; i++) {
110121b345f101abc385496f42d250e580d21f1287b6Dake Gu                mItems.get(index + i).update(payload);
11028ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
11038ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            mAdapterHelper.addUpdateOp(new AdapterHelper.UpdateOp(
110421b345f101abc385496f42d250e580d21f1287b6Dake Gu                    AdapterHelper.UpdateOp.UPDATE, index, count, payload
11058ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            ));
11068ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        }
11078ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1108ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar        TestAdapter createCopy() {
11098ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            TestAdapter adapter = new TestAdapter(0, mAdapterHelper);
1110ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar            adapter.mItems.addAll(mItems);
11118ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            return adapter;
11128ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        }
11138ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1114ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar        void applyOps(List<AdapterHelper.UpdateOp> updates,
11158ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                TestAdapter dataSource) {
11168ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            for (AdapterHelper.UpdateOp op : updates) {
11178ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                switch (op.cmd) {
11188ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    case AdapterHelper.UpdateOp.ADD:
11198ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                        for (int i = 0; i < op.itemCount; i++) {
11208ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                            mItems.add(op.positionStart + i, dataSource.consumeNextAdded());
11218ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                        }
11228ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                        break;
11238ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    case AdapterHelper.UpdateOp.REMOVE:
11248ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                        for (int i = 0; i < op.itemCount; i++) {
11258ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                            mItems.remove(op.positionStart);
11268ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                        }
11278ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                        break;
11288ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                    case AdapterHelper.UpdateOp.UPDATE:
11298ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                        for (int i = 0; i < op.itemCount; i++) {
113021b345f101abc385496f42d250e580d21f1287b6Dake Gu                            mItems.get(op.positionStart + i).handleUpdate(op.payload);
11318ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                        }
11328ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                        break;
11331faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                    case AdapterHelper.UpdateOp.MOVE:
11341faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                        mItems.add(op.itemCount, mItems.remove(op.positionStart));
11351faed0c7c20fc3a0b7befabbac1beac1019effc7Yigit Boyar                        break;
11368ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                }
11378ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
11388ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        }
11398ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
11408ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        private Item consumeNextAdded() {
11418ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            return mPendingAdded.remove();
11428ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        }
11438ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
11448ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        public static class Item {
11458ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
11468ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            private static AtomicInteger itemCounter = new AtomicInteger();
11478ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1148ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar            @SuppressWarnings("unused")
11498ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            private final int id;
11508ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
11518ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            private int mVersionCount = 0;
11528ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1153ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar            private ArrayList<Object> mPayloads = new ArrayList<>();
11548ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
11558ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            public Item() {
11568ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                id = itemCounter.incrementAndGet();
11578ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
11588ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
115921b345f101abc385496f42d250e580d21f1287b6Dake Gu            public void update(Object payload) {
116021b345f101abc385496f42d250e580d21f1287b6Dake Gu                mPayloads.add(payload);
11618ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                mVersionCount++;
11628ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
11638ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1164ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar            void handleUpdate(Object payload) {
116521b345f101abc385496f42d250e580d21f1287b6Dake Gu                assertSame(payload, mPayloads.get(0));
116621b345f101abc385496f42d250e580d21f1287b6Dake Gu                mPayloads.remove(0);
11678ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar                mVersionCount--;
11688ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
11698ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar
1170ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar            int getUpdateCount() {
117121b345f101abc385496f42d250e580d21f1287b6Dake Gu                return mVersionCount;
11728ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar            }
11738ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar        }
11748ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar    }
11754b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar
1176be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    static class MockViewHolder extends RecyclerView.ViewHolder {
1177ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar        TestAdapter.Item mItem;
1178ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar
1179ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar        MockViewHolder() {
1180ee283c1b5cd9fae23716511ec4ff03c07fa36258Yigit Boyar            super(Mockito.mock(View.class));
1181be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        }
11827bfacb70bcf6cc6f9307f994dfbb14588b5ce1b6Yigit Boyar
11837bfacb70bcf6cc6f9307f994dfbb14588b5ce1b6Yigit Boyar        @Override
11847bfacb70bcf6cc6f9307f994dfbb14588b5ce1b6Yigit Boyar        public String toString() {
11857bfacb70bcf6cc6f9307f994dfbb14588b5ce1b6Yigit Boyar            return mItem == null ? "null" : mItem.toString();
11867bfacb70bcf6cc6f9307f994dfbb14588b5ce1b6Yigit Boyar        }
1187be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    }
11888ae76f91527ce850f155ce960fb9068bcd5d49f9Yigit Boyar}
1189