ObjectAdapterTest.java revision ac5fe7c617c66850fff75a9fce9979c6e5674b0f
18f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu/*
28f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu * Copyright (C) 2017 The Android Open Source Project
38f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu *
48f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu * Licensed under the Apache License, Version 2.0 (the "License");
58f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu * you may not use this file except in compliance with the License.
68f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu * You may obtain a copy of the License at
78f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu *
88f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu *      http://www.apache.org/licenses/LICENSE-2.0
98f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu *
108f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu * Unless required by applicable law or agreed to in writing, software
118f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu * distributed under the License is distributed on an "AS IS" BASIS,
128f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu * See the License for the specific language governing permissions and
148f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu * limitations under the License.
158f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu */
168f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.leanback.widget;
188f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
198f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Guimport static org.junit.Assert.assertEquals;
2057ac90cf3fc528ac56b6b83718541624173b1368jingjiangliimport static org.junit.Assert.assertTrue;
2157ac90cf3fc528ac56b6b83718541624173b1368jingjiangliimport static org.mockito.ArgumentMatchers.any;
2257ac90cf3fc528ac56b6b83718541624173b1368jingjiangliimport static org.mockito.ArgumentMatchers.anyInt;
2308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangliimport static org.mockito.ArgumentMatchers.eq;
2408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangliimport static org.mockito.Mockito.atLeast;
2557ac90cf3fc528ac56b6b83718541624173b1368jingjiangliimport static org.mockito.Mockito.never;
263a4653f65ea030436063343d23210e8c987edaadDake Guimport static org.mockito.Mockito.times;
278f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
2808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangliimport android.content.Context;
2908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangliimport android.os.Bundle;
30ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.Nullable;
3108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangliimport android.support.test.InstrumentationRegistry;
328f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Guimport android.support.test.filters.SmallTest;
33ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.R;
34ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.recyclerview.widget.RecyclerView;
3508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangliimport android.view.View;
3608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangliimport android.view.ViewGroup;
3708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangliimport android.widget.FrameLayout;
388f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
3908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangliimport org.junit.Before;
408f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Guimport org.junit.Test;
418f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Guimport org.junit.runner.RunWith;
428f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Guimport org.junit.runners.JUnit4;
438f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Guimport org.mockito.Mockito;
448f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
458f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Guimport java.util.ArrayList;
4608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangliimport java.util.List;
478f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
488f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu@SmallTest
498f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu@RunWith(JUnit4.class)
508f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gupublic class ObjectAdapterTest {
518f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
5208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private static final String ID = "id";
5308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private static final String STRING_MEMBER_ONE = "stringMemberOne";
5408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private static final String STRING_MEMBER_TWO = "stringMemberTwo";
5508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private static final String NOT_RELATED_STRING_MEMBER = "notRelatedStringMember";
5608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
578f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu    protected ItemBridgeAdapter mBridgeAdapter;
5808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    protected ArrayObjectAdapter mAdapter;
598f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
6008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private ArrayList mItems;
6108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private DiffCallback<AdapterItem> mMockedCallback;
6208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private DiffCallback<AdapterItem> mCallbackWithoutPayload;
6308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private RecyclerView.AdapterDataObserver mObserver;
6408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
6508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private Context mContext;
6608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private ListRowPresenter mListRowPresenter;
6708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private ListRowPresenter.ViewHolder mListVh;
6808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private ArrayObjectAdapter mRowsAdapter;
6908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private AdapterItemPresenter mAdapterItemPresenter;
7008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
7108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private ListRow mRow;
728f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
7308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
7408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * This type is used to test setItems() API.
7508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
7608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private static class AdapterItem {
7757ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        private int mId;
7808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        private String mStringMemberOne;
7957ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
8008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // mStringMemberTwo is only used to test if correct payload can be generated.
8108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        private String mStringMemberTwo;
8208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
8308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // not related string will not impact the result of our equals function.
8408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Used to verify if payload computing process still honor the rule set by
8508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // areContentsTheSame() method
8608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        private String mNotRelatedStringMember;
8708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
8808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem(int id, String stringMemberOne) {
8908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            mId = id;
9008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            mStringMemberOne = stringMemberOne;
9108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            mStringMemberTwo = "";
9208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            mNotRelatedStringMember = "";
9308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        }
9408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
9508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem(int id, String stringMemberOne, String stringMemberTwo) {
9608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            mId = id;
9708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            mStringMemberOne = stringMemberOne;
9808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            mStringMemberTwo = stringMemberTwo;
9908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            mNotRelatedStringMember = "";
10008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        }
10108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
10208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem(int id, String stringMemberOne, String stringMemberTwo,
10308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                String notRelatedStringMember) {
10408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            mId = id;
10508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            mStringMemberOne = stringMemberOne;
10608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            mStringMemberTwo = stringMemberTwo;
10708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            mNotRelatedStringMember = notRelatedStringMember;
10857ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        }
10957ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
11057ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        public int getId() {
11157ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            return mId;
11257ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        }
11357ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
11408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        public String getStringMemberOne() {
11508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            return mStringMemberOne;
11608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        }
11708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
11808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        public String getStringMemberTwo() {
11908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            return mStringMemberTwo;
12008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        }
12108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
12208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        public String getNotRelatedStringMember() {
12308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            return mNotRelatedStringMember;
12408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        }
12508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
12657ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        @Override
12757ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        public boolean equals(Object o) {
12857ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            if (this == o) return true;
12957ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            if (o == null || getClass() != o.getClass()) return false;
13057ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
13108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            AdapterItem that = (AdapterItem) o;
13257ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
13308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            if (mId != that.mId) return false;
13408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            if (mStringMemberOne != null ? !mStringMemberOne.equals(that.mStringMemberOne)
13508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                    : that.mStringMemberOne != null) {
13608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                return false;
13708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            }
13808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            return mStringMemberTwo != null ? mStringMemberTwo.equals(that.mStringMemberTwo)
13908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                    : that.mStringMemberTwo == null;
14057ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        }
14157ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
14257ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        @Override
14357ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        public int hashCode() {
14457ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            int result = mId;
14508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            result = 31 * result + (mStringMemberOne != null ? mStringMemberOne.hashCode() : 0);
14608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            result = 31 * result + (mStringMemberTwo != null ? mStringMemberTwo.hashCode() : 0);
14757ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            return result;
14857ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        }
14957ac90cf3fc528ac56b6b83718541624173b1368jingjiangli    }
15057ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
15108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
15208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Extend from DiffCallback extended class to define the rule to compare if two items are the
15308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * same/ have the same content and how to calculate the payload.
15408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     *
15508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * The payload will only be calculated when the two items are the same but with different
15608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * contents. So we make this class as a public class which can be mocked by mockito to verify
15708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * if the calculation process satisfies our requirement.
15808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
15908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public static class DiffCallbackPayloadTesting extends DiffCallback<AdapterItem> {
16008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Using item's mId as the standard to judge if two items is the same
16108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        @Override
16208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        public boolean areItemsTheSame(AdapterItem oldItem, AdapterItem newItem) {
16308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            return oldItem.getId() == newItem.getId();
16408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        }
16508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
16608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Using equals method to judge if two items have the same content.
16708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        @Override
16808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        public boolean areContentsTheSame(AdapterItem oldItem, AdapterItem newItem) {
16908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            return oldItem.equals(newItem);
17008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        }
17108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
17208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        @Nullable
17308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        @Override
17408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        public Object getChangePayload(AdapterItem oldItem,
17508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                AdapterItem newItem) {
17608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            Bundle diff = new Bundle();
17708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            if (oldItem.getId() != newItem.getId()) {
17808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                diff.putInt(ID, newItem.getId());
17908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            }
18008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
18108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            if (!oldItem.getStringMemberOne().equals(newItem.getStringMemberOne())) {
18208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                diff.putString(STRING_MEMBER_ONE, newItem.getStringMemberOne());
18308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            }
18408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
18508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            if (!oldItem.getStringMemberTwo().equals(newItem.getStringMemberTwo())) {
18608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                diff.putString(STRING_MEMBER_TWO, newItem.getStringMemberTwo());
18708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            }
18808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
18908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            if (!oldItem.getNotRelatedStringMember().equals(newItem.getNotRelatedStringMember())) {
19008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                diff.putString(NOT_RELATED_STRING_MEMBER, newItem.getNotRelatedStringMember());
19108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            }
19208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
19308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            if (diff.size() == 0) {
19408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                return null;
19508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            }
19608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            return diff;
19708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        }
19808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
19908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
20008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
20108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * The presenter designed for adapter item.
20208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     *
20308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * The reason to set this class as a public class is for Mockito to mock it. So we can observe
20408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * method's dispatching easily
20508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
20608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public static class AdapterItemPresenter extends Presenter {
20708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        int mWidth;
20808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        int mHeight;
20908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
21008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItemPresenter() {
21108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            this(100, 100);
21208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        }
21308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
21408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItemPresenter(int width, int height) {
21508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            mWidth = width;
21608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            mHeight = height;
21708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        }
21808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
21908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        @Override
22008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        public ViewHolder onCreateViewHolder(ViewGroup parent) {
22108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            View view = new View(parent.getContext());
22208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            view.setFocusable(true);
22308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            view.setId(R.id.lb_action_button);
22408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            view.setLayoutParams(new ViewGroup.LayoutParams(mWidth, mHeight));
22508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            return new Presenter.ViewHolder(view);
22608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        }
22708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
22808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        @Override
22908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        public void onBindViewHolder(ViewHolder viewHolder, Object item) {
23008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            // no - op
23108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        }
23208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
23308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        @Override
23408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        public void onUnbindViewHolder(ViewHolder viewHolder) {
23508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            // no - op
23608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        }
23708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
23808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        @Override
23908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        public void onBindViewHolder(ViewHolder viewHolder, Object item,
24008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                List<Object> payloads) {
24108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            // no - op
24208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        }
24308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
24408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
24508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
24608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
24708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Initialize test-related members.
24808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
24908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Before
25008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void setup() {
25108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter = new ArrayObjectAdapter();
2528f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu        mBridgeAdapter = new ItemBridgeAdapter(mAdapter);
25308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems = new ArrayList();
25408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mMockedCallback = Mockito.spy(DiffCallbackPayloadTesting.class);
2558f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
25608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // the diff callback without calculating the payload
25708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mCallbackWithoutPayload = new DiffCallback<AdapterItem>() {
25808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
25908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            // Using item's mId as the standard to judge if two items is the same
26008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            @Override
26108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            public boolean areItemsTheSame(AdapterItem oldItem, AdapterItem newItem) {
26208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                return oldItem.getId() == newItem.getId();
26308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            }
26408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
26508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            // Using equals method to judge if two items have the same content.
26608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            @Override
26708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            public boolean areContentsTheSame(AdapterItem oldItem, AdapterItem newItem) {
26808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                return oldItem.equals(newItem);
26908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            }
27008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        };
27108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
27208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Spy the RecyclerView.AdapterObserver
27308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mObserver = Mockito.spy(RecyclerView.AdapterDataObserver.class);
27408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
27508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // register observer so we can observe the events
27608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mBridgeAdapter.registerAdapterDataObserver(mObserver);
27708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
27808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // obtain context through instrumentation registry
27908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
28008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
28108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        //
28208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        ListRowPresenter listRowPresenter = new ListRowPresenter();
28308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mListRowPresenter = Mockito.spy(listRowPresenter);
28408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
28508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // mock item presenter
28608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItemPresenter adapterItemPresenter = new AdapterItemPresenter();
28708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapterItemPresenter = Mockito.spy(adapterItemPresenter);
28808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mRow = new ListRow(new ArrayObjectAdapter(mAdapterItemPresenter));
28908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
29008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
29108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
29208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * The following test case is mainly focused on the basic functionality provided by
29308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Object Adapter.
29408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     *
29508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * The key purpose for this test is to make sure when adapter send out a signal through
29608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * notify function, it will finally be intercepted by recycler view's observer
29708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
29808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
29908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testBasicFunctionality() {
30008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("a");
30108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("b");
30208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("c");
30308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.addAll(0, mItems);
3048f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
30557ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        // size
30608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertEquals(mAdapter.size(), 3);
30757ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
30857ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        // get
30908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertEquals(mAdapter.get(0), "a");
31008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertEquals(mAdapter.get(1), "b");
31108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertEquals(mAdapter.get(2), "c");
31257ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
31357ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        // indexOf
31408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertEquals(mAdapter.indexOf("a"), 0);
31508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertEquals(mAdapter.indexOf("b"), 1);
31608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertEquals(mAdapter.indexOf("c"), 2);
31757ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
3188f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu        // insert
31908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.add(1, "a1");
32008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeInserted(1, 1);
32108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertAdapterContent(mAdapter, new Object[]{"a", "a1", "b", "c"});
32208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
3238f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
3248f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu        // insert multiple
3258f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu        ArrayList newItems1 = new ArrayList();
3268f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu        newItems1.add("a2");
3278f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu        newItems1.add("a3");
32808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.addAll(1, newItems1);
32908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeInserted(1, 2);
33008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertAdapterContent(mAdapter, new Object[]{"a", "a2", "a3", "a1", "b", "c"});
33108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
3328f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
3338f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu        // update
33408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.notifyArrayItemRangeChanged(2, 3);
33508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeChanged(2, 3);
33608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertAdapterContent(mAdapter, new Object[]{"a", "a2", "a3", "a1", "b", "c"});
33708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
3388f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
3398f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu        // remove
34008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.removeItems(1, 4);
34108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeRemoved(1, 4);
34208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertAdapterContent(mAdapter, new Object[]{"a", "c"});
34308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
3448f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
3458f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu        // move
34608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.move(0, 1);
34708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeMoved(0, 1, 1);
34808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertAdapterContent(mAdapter, new Object[]{"c", "a"});
34908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
35057ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
35157ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        // replace
35208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.replace(0, "a");
35308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeChanged(0, 1);
35408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertAdapterContent(mAdapter, new Object[]{"a", "a"});
35508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
35608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.replace(1, "b");
35708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeChanged(1, 1);
35808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertAdapterContent(mAdapter, new Object[]{"a", "b"});
35908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
36057ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
36157ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        // remove multiple
36208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
36308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("a");
36408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("b");
36508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.addAll(0, mItems);
36608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.removeItems(0, 2);
36708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeRemoved(0, 2);
36808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertAdapterContent(mAdapter, new Object[]{"a", "b"});
36908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
37057ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
37157ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        // clear
37208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.clear();
37308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeRemoved(0, 2);
37408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertAdapterContent(mAdapter, new Object[]{});
37508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
37657ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
37757ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        // isImmediateNotifySupported
37808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertTrue(mAdapter.isImmediateNotifySupported());
37908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
38057ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
3813a4653f65ea030436063343d23210e8c987edaadDake Gu
3823a4653f65ea030436063343d23210e8c987edaadDake Gu    @Test
3833a4653f65ea030436063343d23210e8c987edaadDake Gu    public void testSetItemsNoDiffCallback() {
3843a4653f65ea030436063343d23210e8c987edaadDake Gu        mItems.add(new AdapterItem(1, "a"));
3853a4653f65ea030436063343d23210e8c987edaadDake Gu        mItems.add(new AdapterItem(2, "b"));
3863a4653f65ea030436063343d23210e8c987edaadDake Gu        mItems.add(new AdapterItem(3, "c"));
3873a4653f65ea030436063343d23210e8c987edaadDake Gu        mAdapter.setItems(mItems, null);
3883a4653f65ea030436063343d23210e8c987edaadDake Gu        Mockito.verify(mObserver, times(1)).onChanged();
3893a4653f65ea030436063343d23210e8c987edaadDake Gu        Mockito.verify(mObserver, never()).onItemRangeInserted(anyInt(), anyInt());
3903a4653f65ea030436063343d23210e8c987edaadDake Gu        Mockito.verify(mObserver, never()).onItemRangeRemoved(anyInt(), anyInt());
3913a4653f65ea030436063343d23210e8c987edaadDake Gu        Mockito.verify(mObserver, never()).onItemRangeMoved(anyInt(), anyInt(), anyInt());
3923a4653f65ea030436063343d23210e8c987edaadDake Gu
3933a4653f65ea030436063343d23210e8c987edaadDake Gu        mItems.add(new AdapterItem(4, "a"));
3943a4653f65ea030436063343d23210e8c987edaadDake Gu        mItems.add(new AdapterItem(5, "b"));
3953a4653f65ea030436063343d23210e8c987edaadDake Gu        mItems.add(new AdapterItem(6, "c"));
3963a4653f65ea030436063343d23210e8c987edaadDake Gu        mAdapter.setItems(mItems, null);
3973a4653f65ea030436063343d23210e8c987edaadDake Gu        Mockito.verify(mObserver, times(2)).onChanged();
3983a4653f65ea030436063343d23210e8c987edaadDake Gu        Mockito.verify(mObserver, never()).onItemRangeInserted(anyInt(), anyInt());
3993a4653f65ea030436063343d23210e8c987edaadDake Gu        Mockito.verify(mObserver, never()).onItemRangeRemoved(anyInt(), anyInt());
4003a4653f65ea030436063343d23210e8c987edaadDake Gu        Mockito.verify(mObserver, never()).onItemRangeMoved(anyInt(), anyInt(), anyInt());
4013a4653f65ea030436063343d23210e8c987edaadDake Gu    }
4023a4653f65ea030436063343d23210e8c987edaadDake Gu
40308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
40408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * The following test cases are mainly focused on the basic functionality provided by setItems
40508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * function
40608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     *
40708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * It can be deemed as an extension to the previous test, and won't consider payload in this
40808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * test case.
40908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     *
41008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test0 will treat all items as the same item with same content.
41108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
41208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
41308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testSetItemsMethod0() {
41408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("a");
41508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("b");
41608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("c");
41757ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
41808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        DiffCallback<String> callback = new DiffCallback<String>() {
41957ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
42057ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            // Always treat two items are the same.
42157ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            @Override
42257ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            public boolean areItemsTheSame(String oldItem, String newItem) {
42357ac90cf3fc528ac56b6b83718541624173b1368jingjiangli                return true;
42457ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            }
42557ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
42657ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            // Always treat two items have the same content.
42757ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            @Override
42857ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            public boolean areContentsTheSame(String oldItem, String newItem) {
42957ac90cf3fc528ac56b6b83718541624173b1368jingjiangli                return true;
43057ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            }
43157ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        };
43257ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
43308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, callback);
43408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // verify method dispatching
43508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeInserted(0, 3);
43657ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
43708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Clear previous items and set a new list of items.
43808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
43908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("a");
44008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("b");
44108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("c");
44257ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
44308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
44408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
44508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, callback);
44608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
44708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // verify method dispatching
44808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeChanged(anyInt(), anyInt(), any());
44908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeMoved(anyInt(), anyInt(), anyInt());
45008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeRemoved(anyInt(), anyInt());
45108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeInserted(anyInt(), anyInt());
45208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertAdapterContent(mAdapter, new Object[]{"a", "b", "c"});
45308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
45408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
45508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
45608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test1 will treat all items as the same item with same content.
45708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
45808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
45908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testSetItemsMethod1() {
46008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("a");
46108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("b");
46208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("c");
46308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
46408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        DiffCallback<String> callback = new DiffCallback<String>() {
46557ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
46657ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            // Always treat two items are the different.
46757ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            @Override
46857ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            public boolean areItemsTheSame(String oldItem, String newItem) {
46957ac90cf3fc528ac56b6b83718541624173b1368jingjiangli                return false;
47057ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            }
47157ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
47257ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            // Always treat two items have the different content.
47357ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            @Override
47457ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            public boolean areContentsTheSame(String oldItem, String newItem) {
47557ac90cf3fc528ac56b6b83718541624173b1368jingjiangli                return false;
47657ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            }
47757ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        };
47857ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
47908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, callback);
48008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // verify method dispatching
48108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeInserted(0, 3);
48208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
48308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Clear previous items and set a new list of items.
48408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
48508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("a");
48608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("b");
48708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add("c");
48808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
48908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
49008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
49108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, callback);
49257ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
49357ac90cf3fc528ac56b6b83718541624173b1368jingjiangli        // No change or move event should be fired under current callback.
49408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeChanged(anyInt(), anyInt(), any());
49508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeMoved(anyInt(), anyInt(), anyInt());
49608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeRemoved(0, 3);
49708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeInserted(0, 3);
49808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertAdapterContent(mAdapter, new Object[]{"a", "b", "c"});
49908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
50057ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
50108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
50208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test2 will trigger notifyItemRangeChanged event
50308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
50408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
50508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testSetItemsMethod2() {
50608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // initial item list
50708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(1, "a"));
50808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(2, "b"));
50908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(3, "c"));
51008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mCallbackWithoutPayload);
51157ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
51208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Clear previous items and set a new list of items.
51308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
51408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(1, "a"));
51508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(2, "c"));
51608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(3, "b"));
51757ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
51808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
51908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
52008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mCallbackWithoutPayload);
52108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
52208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // verify method dispatching
52308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeChanged(1, 2, null);
52408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
52508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
52608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
52708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
52808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test3 will trigger notifyItemMoved event
52908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
53008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
53108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testSetItemsMethod3() {
53208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // initial item list
53308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(1, "a"));
53408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(2, "b"));
53508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(3, "c"));
53608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mCallbackWithoutPayload);
53708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
53808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Clear previous items and set a new list of items.
53908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
54008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(2, "b"));
54108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(1, "a"));
54208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(3, "c"));
54308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
54408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
54508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
54608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mCallbackWithoutPayload);
54708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
54808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // verify method dispatching
54908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeMoved(1, 0, 1);
55008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
55108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
55208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
55308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test4 will trigger notifyItemRangeRemoved event
55408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
55508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
55608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testSetItemsMethod4() {
55708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // initial item list
55808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(1, "a"));
55908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(2, "b"));
56008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(3, "c"));
56108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mCallbackWithoutPayload);
56208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
56308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Clear previous items and set a new list of items.
56408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
56508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(2, "b"));
56608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(3, "c"));
56708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
56808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
56908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
57008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mCallbackWithoutPayload);
57108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
57208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // verify method dispatching
57308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeRemoved(0, 1);
57408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
57508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
57608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
57708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test5 will trigger notifyItemRangeInserted event
57808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
57908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
58008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testSetItemsMethod5() {
58108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // initial item list
58208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(1, "a"));
58308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(2, "b"));
58408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(3, "c"));
58508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mCallbackWithoutPayload);
58608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
58708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Clear previous items and set a new list of items.
58808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
58908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(1, "a"));
59008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(2, "b"));
59108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(3, "c"));
59208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(4, "d"));
59308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
59408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
59508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
59608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mCallbackWithoutPayload);
59708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
59808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // verify method dispatching
59908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeInserted(3, 1);
60008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
60108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
60208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
60308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
60408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test6 will trigger notifyItemRangeInserted event and notifyItemRangeRemoved event
60508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * simultaneously
60608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
60708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
60808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testSetItemsMethod6() {
60908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // initial item list
61008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(1, "a"));
61108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(2, "b"));
61208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(3, "c"));
61308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mCallbackWithoutPayload);
61408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
61508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Clear previous items and set a new list of items.
61608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
61708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(2, "a"));
61808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(2, "b"));
61908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(3, "c"));
62008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
62108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
62208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
62308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mCallbackWithoutPayload);
62408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
62508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // verify method dispatching
62608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeRemoved(0, 1);
62708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeInserted(0, 1);
62808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
62908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
63008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
63108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test7 will trigger notifyItemRangeMoved and notifyItemRangeChanged event simultaneously
63208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
63308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
63408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testItemsMethod7() {
63508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // initial item list
63608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(1, "a"));
63708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(2, "b"));
63808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(3, "c"));
63908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mCallbackWithoutPayload);
64008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
64108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Clear previous items and set a new list of items.
64208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
64308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(1, "aa"));
64408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(3, "c"));
64508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(2, "b"));
64608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
64708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
64808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
64908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mCallbackWithoutPayload);
65008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
65108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // verify method dispatching
65208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeChanged(0, 1, null);
65308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeMoved(2, 1, 1);
65408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
65508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
65608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
65708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test8 will trigger multiple items insertion event
65808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
65908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
66008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testSetItemsMethod8() {
66108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
66208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // initial item list
66308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.clear();
66408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(0, "a"));
66508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(1, "b"));
66608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.clear();
66708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mCallbackWithoutPayload);
66808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
66908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Clear previous items and set a new list of items.
67008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
67108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(0, "a"));
67208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(1, "b"));
67308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(2, "c"));
67408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(new AdapterItem(3, "d"));
67508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
67608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
67708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
67808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mCallbackWithoutPayload);
67908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
68008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // verify method dispatching
68108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeInserted(2, 2);
68208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
68308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
68408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
68508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
68608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
68708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * The following test cases are mainly focused on testing setItems method when we need to
68808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * calculate payload
68908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     *
69008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * The payload should only be calculated when two items are same but with different contents.
69108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * I.e. the calculate payload method should only be executed when the previous condition is
69208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * satisfied. In this test case we use a mocked callback object to verify it and compare the
69308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * calculated payload with our expected payload.
69408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     *
69508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test 0 will calculate the difference on string member one.
69608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
69708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
69808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testPayloadCalculation0() {
69908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem oldItem = new AdapterItem(1, "a", "a");
70008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(oldItem);
70108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
70208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
70308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Create a new item list which contain a new AdapterItem object
70408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // test if payload is computed correctly by changing string member 1
70508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
70608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem newItem = new AdapterItem(1, "aa", "a");
70708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(newItem);
70808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
70908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
71008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
71108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
71208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mMockedCallback);
71308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
71408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
71508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Create expected payload manually for verification
71608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Bundle expectedPayload0 = new Bundle();
71708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        expectedPayload0.putString(STRING_MEMBER_ONE, newItem.getStringMemberOne());
71808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
71908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // make sure no other event will be triggered in current scenario
72008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeInserted(anyInt(), anyInt());
72108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeRemoved(anyInt(), anyInt());
72208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeMoved(anyInt(), anyInt(), anyInt());
72308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
72408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Check if getChangePayload is executed as we expected
72508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeChanged(anyInt(), anyInt(), eq(null));
72608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mMockedCallback).getChangePayload(oldItem,
72708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                newItem);
72808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
72908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // compare the two bundles by iterating each member
73008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Bundle calculatedBundle0 = (Bundle) mMockedCallback.getChangePayload(
73108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                oldItem, newItem);
73208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        compareTwoBundles(calculatedBundle0, expectedPayload0);
73308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
73408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
73508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
73608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
73708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test 1 will calculate the difference on string member two.
73808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
73908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
74008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testPayloadComputation1() {
74108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem oldItem = new AdapterItem(1, "a", "a");
74208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(oldItem);
74308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
74408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
74508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Create a new item list which contain a new AdapterItem object
74608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // test if payload is computed correctly by changing string member 2
74708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
74808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem newItem = new AdapterItem(1, "a", "aa");
74908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(newItem);
75008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
75108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
75208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
75308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mMockedCallback);
75408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
75508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
75608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Create expected payload manually for verification
75708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Bundle expectedPayload0 = new Bundle();
75808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        expectedPayload0.putString(STRING_MEMBER_TWO, newItem.getStringMemberTwo());
75908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
76008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // make sure no other event will be triggered in current scenario
76108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeInserted(anyInt(), anyInt());
76208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeRemoved(anyInt(), anyInt());
76308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeMoved(anyInt(), anyInt(), anyInt());
76408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
76508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Check if getChangePayload is executed as we expected
76608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeChanged(anyInt(), anyInt(), eq(null));
76708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mMockedCallback).getChangePayload(oldItem,
76808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                newItem);
76908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
77008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // compare the two bundles by iterating each member
77108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Bundle calculatedBundle0 = (Bundle) mMockedCallback.getChangePayload(
77208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                oldItem, newItem);
77308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        compareTwoBundles(calculatedBundle0, expectedPayload0);
77408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
77508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
77608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
77708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
77808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test 1 will calculate the difference on string member one and string member two.
77908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
78008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
78108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testPayloadComputation2() {
78208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem oldItem = new AdapterItem(1, "a", "a");
78308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(oldItem);
78408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
78508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
78608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Create a new item list which contain a new AdapterItem object
78708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // test if payload is computed correctly by changing string member 1 and string member 2
78808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
78908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem newItem = new AdapterItem(1, "aa", "aa");
79008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(newItem);
79108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
79208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
79308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
79408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mMockedCallback);
79508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
79608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
79708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Create expected payload manually for verification
79808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Bundle expectedPayload0 = new Bundle();
79908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        expectedPayload0.putString(STRING_MEMBER_ONE, newItem.getStringMemberOne());
80008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        expectedPayload0.putString(STRING_MEMBER_TWO, newItem.getStringMemberTwo());
80108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
80208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // make sure no other event will be triggered in current scenario
80308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeInserted(anyInt(), anyInt());
80408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeRemoved(anyInt(), anyInt());
80508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeMoved(anyInt(), anyInt(), anyInt());
80608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
80708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Check if getChangePayload is executed as we expected
80808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeChanged(anyInt(), anyInt(), eq(null));
80908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mMockedCallback).getChangePayload(oldItem,
81008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                newItem);
81108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
81208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // compare the two bundles by iterating each member
81308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Bundle calculatedBundle0 = (Bundle) mMockedCallback.getChangePayload(
81408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                oldItem, newItem);
81508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        compareTwoBundles(calculatedBundle0, expectedPayload0);
81608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
81708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
81808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
81908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
82008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test payload computation process under the condition when two items are not the same
82108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * based on areItemsTheSame function in DiffUtilCallback
82208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
82308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
82408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testPayloadComputationNewItem0() {
82508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem oldItem = new AdapterItem(1, "a", "a");
82608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(oldItem);
82708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
82808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
82908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Create a new item list which contain a new AdapterItem object
83008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // The id of the new item is changed, and will be treated as a new item according to the
83108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // rule we set in the callback. This test case is to verify the getChangePayload
83208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // method still honor the standard we set up to judge new item
83308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
83408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem newItem = new AdapterItem(2, "a", "a");
83508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(newItem);
83608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
83708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
83808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
83908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mMockedCallback);
84008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
84108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
84208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Make sure only remove/ insert event will be fired under this circumstance
84308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeRemoved(0, 1);
84408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeInserted(0, 1);
84508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeChanged(anyInt(), anyInt(), any());
84608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mMockedCallback, never()).getChangePayload((AdapterItem) any(),
84708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                (AdapterItem) any());
84808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
84908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
85008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
85108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
85208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test payload computation process under the condition when two items are not the same
85308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * based on areItemsTheSame function in DiffUtilCallback
85408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     *
85508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * But in test 1 we have changed string member one for sanity check.
85608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
85708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
85808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testPayloadComputationNewItem1() {
85908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem oldItem = new AdapterItem(1, "a", "a");
86008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(oldItem);
86108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
86208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
86308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Create a new item list which contain a new AdapterItem object
86408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // The id of the new item is changed, and will be treated as a new item according to the
86508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // rule we set in the callback. This test case is to verify the getChangePayload
86608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // method still honor the standard we set up to judge new item
86708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
86808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem newItem = new AdapterItem(2, "aa", "a");
86908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(newItem);
87008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
87108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
87208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
87308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mMockedCallback);
87408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
87508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
87608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Make sure only remove/ insert event will be fired under this circumstance
87708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeRemoved(0, 1);
87808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeInserted(0, 1);
87908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeChanged(anyInt(), anyInt(), any());
88008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mMockedCallback, never()).getChangePayload((AdapterItem) any(),
88108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                (AdapterItem) any());
88208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
88308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
88408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
88508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
88608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test payload computation process under the condition when two items are not the same
88708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * based on areItemsTheSame function in DiffUtilCallback
88808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     *
88908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * But in test 2 we have changed string member two for sanity check.
89008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
89108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
89208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testPayloadComputationNewItem2() {
89308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem oldItem = new AdapterItem(1, "a", "a");
89408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(oldItem);
89508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
89608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
89708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Create a new item list which contain a new AdapterItem object
89808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // The id of the new item is changed, and will be treated as a new item according to the
89908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // rule we set in the callback. This test case is to verify the getChangePayload
90008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // method still honor the standard we set up to judge new item
90108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
90208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem newItem = new AdapterItem(2, "a", "aa");
90308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(newItem);
90408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
90508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
90608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
90708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mMockedCallback);
90808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
90908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
91008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Make sure only remove/ insert event will be fired under this circumstance
91108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeRemoved(0, 1);
91208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeInserted(0, 1);
91308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeChanged(anyInt(), anyInt(), any());
91408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mMockedCallback, never()).getChangePayload((AdapterItem) any(),
91508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                (AdapterItem) any());
91608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
91708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
91808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
91908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
92008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test payload computation process under the condition when two items are not the same
92108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * based on areItemsTheSame function in DiffUtilCallback
92208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     *
92308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * But in test 3 we have changed string member one and string member two for sanity check.
92408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
92508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
92608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testPayloadComputationNewItem3() {
92708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem oldItem = new AdapterItem(1, "a", "a");
92808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(oldItem);
92908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
93008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
93108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Create a new item list which contain a new AdapterItem object
93208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // The id of the new item is changed, and will be treated as a new item according to the
93308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // rule we set in the callback. This test case is to verify the getChangePayload
93408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // method still honor the standard we set up to judge new item
93508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
93608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem newItem = new AdapterItem(2, "aa", "aa");
93708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(newItem);
93808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
93908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
94008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
94108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mMockedCallback);
94208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
94308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
94408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Make sure only remove/ insert event will be fired under this circumstance
94508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeRemoved(0, 1);
94608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver).onItemRangeInserted(0, 1);
94708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeChanged(anyInt(), anyInt(), any());
94808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mMockedCallback, never()).getChangePayload((AdapterItem) any(),
94908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                (AdapterItem) any());
95008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
95108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
95208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
95308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Test payload computation process under the condition when two items have the same content
95408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * based on areContentsTheSame function in DiffUtilCallback
95508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
95608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
95708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testPayloadComputationSameContent() {
95808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem oldItem = new AdapterItem(1, "a", "a", "a");
95908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(oldItem);
96008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
96108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
96208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Create a new item list which contain a new AdapterItem object
96308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // The non-related string member of the new item is changed, but the two items are still
96408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // the same as well as the item's content according to the rule we set in the callback.
96508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // This test case is to verify the getChangePayload method still honor the standard
96608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // we set up to determine if a new object is 1. a new item 2. has the same content as the
96708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // previous one
96808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.clear();
96908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem newItem = new AdapterItem(1, "a", "a", "aa");
97008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mItems.add(newItem);
97108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
97208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // reset mocked object before calling setItems method
97308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mObserver);
97408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.reset(mMockedCallback);
97508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mAdapter.setItems(mItems, mMockedCallback);
97608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
97708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // Make sure no even will be fired up in this circumstance
97808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeRemoved(anyInt(), anyInt());
97908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeInserted(anyInt(), anyInt());
98008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mObserver, never()).onItemRangeChanged(anyInt(), anyInt(), any());
98108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        Mockito.verify(mMockedCallback, never()).getChangePayload((AdapterItem) any(),
98208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                (AdapterItem) any());
98308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
98408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
98508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
98608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
98708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * This test case is targeted at real ui testing. I.e. making sure when the change of adapter's
98808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * items will trigger the rebinding of view holder with payload. That's item presenter's
98908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * onBindViewHolder method with payload supporting.
99008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     *
99108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
99208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    @Test
99308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    public void testPresenterAndItemBridgeAdapter() {
99408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // data set one
99508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        final List<AdapterItem> dataSetOne = new ArrayList<>();
99608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem dataSetOne0 = new AdapterItem(1, "a");
99708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem dataSetOne1 = new AdapterItem(2, "b");
99808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem dataSetOne2 = new AdapterItem(3, "c");
99908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem dataSetOne3 = new AdapterItem(4, "d");
100008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem dataSetOne4 = new AdapterItem(5, "3");
100108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        dataSetOne.add(dataSetOne0);
100208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        dataSetOne.add(dataSetOne1);
100308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        dataSetOne.add(dataSetOne2);
100408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        dataSetOne.add(dataSetOne3);
100508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        dataSetOne.add(dataSetOne4);
100608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
100708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        // data set two
100808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        final List<AdapterItem> dataSetTwo = new ArrayList<>();
100908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem dataSetTwo0 = new AdapterItem(1, "aa");
101008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem dataSetTwo1 = new AdapterItem(2, "bb");
101108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem dataSetTwo2 = new AdapterItem(3, "cc");
101208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem dataSetTwo3 = new AdapterItem(4, "dd");
101308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        AdapterItem dataSetTwo4 = new AdapterItem(5, "ee");
101408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        dataSetTwo.add(dataSetTwo0);
101508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        dataSetTwo.add(dataSetTwo1);
101608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        dataSetTwo.add(dataSetTwo2);
101708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        dataSetTwo.add(dataSetTwo3);
101808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        dataSetTwo.add(dataSetTwo4);
101908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
102008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        ((ArrayObjectAdapter) mRow.getAdapter()).addAll(0, dataSetOne);
102108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
102257ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            @Override
102308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            public void run() {
102408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
102508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                // obtain frame layout through context.
102608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                final ViewGroup parent = new FrameLayout(mContext);
102708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
102808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                // create view holder and obtain the view object from view holder
102908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                // add view object to our layout
103008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                Presenter.ViewHolder containerVh = mListRowPresenter.onCreateViewHolder(parent);
103108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                parent.addView(containerVh.view, 1000, 1000);
103208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
103308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                // set rows adapter and add row to that adapter
103408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                mRowsAdapter = new ArrayObjectAdapter();
103508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                mRowsAdapter.add(mRow);
103608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
103708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                // use the presenter to bind row view holder explicitly. So the itemBridgeAdapter
103808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                // will be connected to the adapter inside of the listRow successfully.
103908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                mListVh = (ListRowPresenter.ViewHolder) mListRowPresenter.getRowViewHolder(
104008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                        containerVh);
104108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                mListRowPresenter.onBindRowViewHolder(mListVh, mRow);
104208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
104308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                // layout the list row in recycler view
104408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                runRecyclerViewLayout();
104508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
104608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                // reset mocked presenter
104708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                Mockito.reset(mListRowPresenter);
104808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                Mockito.reset(mAdapterItemPresenter);
104908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
105008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                // calling setItem's method to trigger the diff computation
105108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                ((ArrayObjectAdapter) mRow.getAdapter()).setItems(dataSetTwo,
105208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                        new DiffCallbackPayloadTesting());
105308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
105408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                // re-layout the recycler view to trigger getViewForPosition event
105508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                runRecyclerViewLayout();
105608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli
105708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                // verify method execution
105808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                Mockito.verify(mAdapterItemPresenter, never()).onBindViewHolder(
105908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                        (RowPresenter.ViewHolder) any(), (Object) any());
106008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                Mockito.verify(mAdapterItemPresenter, atLeast(5)).onBindViewHolder(
106108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                        (RowPresenter.ViewHolder) any(), (Object) any(), (List<Object>) any());
106257ac90cf3fc528ac56b6b83718541624173b1368jingjiangli            }
106308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        });
106408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
106557ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
106608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
106708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Helper function to layout recycler view
106808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * So the recycler view will execute the getView() method then the onBindViewHolder() method
106908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * from presenter will be executed
107008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
107108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private void runRecyclerViewLayout() {
107208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mListVh.view.measure(View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY),
107308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY));
107408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        mListVh.view.layout(0, 0, 1000, 1000);
107508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
107657ac90cf3fc528ac56b6b83718541624173b1368jingjiangli
107708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
107808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Helper function to compare two bundles through iterating the fields.
107908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     *
108008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * @param bundle1 bundle 1
108108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * @param bundle2 bundle 2
108208a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
108308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private void compareTwoBundles(Bundle bundle1, Bundle bundle2) {
108408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertEquals(bundle1.getInt(ID), bundle2.getInt(ID));
108508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertEquals(bundle1.getString(STRING_MEMBER_ONE), bundle2.getString(
108608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                STRING_MEMBER_ONE));
108708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertEquals(bundle1.getString(STRING_MEMBER_TWO), bundle2.getString(
108808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                STRING_MEMBER_TWO));
108908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertEquals(bundle1.getString(NOT_RELATED_STRING_MEMBER),
109008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli                bundle2.getString(NOT_RELATED_STRING_MEMBER));
10918f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu    }
10928f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu
109308a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    /**
109408a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     * Helper function to test the content in adapter
109508a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli     */
109608a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    private static void assertAdapterContent(ObjectAdapter adapter, Object[] data) {
109708a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        assertEquals(adapter.size(), data.length);
109808a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        for (int i = 0; i < adapter.size(); i++) {
109908a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli            assertEquals(adapter.get(i), data[i]);
110008a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli        }
110108a38559a3751252fc8a1f36db0a431508a8f7d5jingjiangli    }
11028f2085a2ea231e3d81232b54a44be78eacbdbd61Dake Gu}
1103