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