1a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar/*
2a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar * Copyright (C) 2014 The Android Open Source Project
3a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar *
4a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
5a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar * you may not use this file except in compliance with the License.
6a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar * You may obtain a copy of the License at
7a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar *
8a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
9a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar *
10a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar * Unless required by applicable law or agreed to in writing, software
11a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
12a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar * See the License for the specific language governing permissions and
14a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar * limitations under the License.
15a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar */
16a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
17a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyarpackage android.support.v7.util;
18a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
19a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyarimport junit.framework.TestCase;
20a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
21be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyarimport org.junit.Before;
22be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyarimport org.junit.Test;
23be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyarimport org.junit.runner.RunWith;
24be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyarimport org.junit.runners.JUnit4;
25a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
26a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyarimport java.util.ArrayList;
277fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheevimport java.util.Collection;
28a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyarimport java.util.Collections;
29a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyarimport java.util.Comparator;
30a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyarimport java.util.List;
31a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyarimport java.util.Random;
32a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
33be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar@RunWith(JUnit4.class)
34a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyarpublic class SortedListTest extends TestCase {
35a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
36a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    SortedList<Item> mList;
37a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    List<Pair> mAdditions = new ArrayList<Pair>();
38a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    List<Pair> mRemovals = new ArrayList<Pair>();
39a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    List<Pair> mMoves = new ArrayList<Pair>();
40a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    List<Pair> mUpdates = new ArrayList<Pair>();
41a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    private SortedList.Callback<Item> mCallback;
427fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    InsertedCallback<Item> mInsertedCallback;
437fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    ChangedCallback<Item> mChangedCallback;
44a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
45a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    private Comparator<? super Item> sItemComparator = new Comparator<Item>() {
46a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        @Override
47a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        public int compare(Item o1, Item o2) {
48a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            return mCallback.compare(o1, o2);
49a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        }
50a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    };
51a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
527fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    private abstract class InsertedCallback<T> {
537fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        public abstract void onInserted(int position, int count);
547fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
557fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
567fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    private abstract class ChangedCallback<T> {
577fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        public abstract void onChanged(int position, int count);
587fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
597fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
60a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    @Override
61be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Before
62a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    public void setUp() throws Exception {
63a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        super.setUp();
64a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        mCallback = new SortedList.Callback<Item>() {
65a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            @Override
66a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            public int compare(Item o1, Item o2) {
67a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                return o1.cmpField < o2.cmpField ? -1 : (o1.cmpField == o2.cmpField ? 0 : 1);
68a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
69a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
70a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            @Override
71a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            public void onInserted(int position, int count) {
72a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                mAdditions.add(new Pair(position, count));
737fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                if (mInsertedCallback != null) {
747fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    mInsertedCallback.onInserted(position, count);
757fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                }
76a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
77a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
78a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            @Override
79a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            public void onRemoved(int position, int count) {
80a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                mRemovals.add(new Pair(position, count));
81a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
82a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
83a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            @Override
84a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            public void onMoved(int fromPosition, int toPosition) {
85a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                mMoves.add(new Pair(fromPosition, toPosition));
86a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
87a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
88a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            @Override
89a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            public void onChanged(int position, int count) {
90a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                mUpdates.add(new Pair(position, count));
917fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                if (mChangedCallback != null) {
927fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    mChangedCallback.onChanged(position, count);
937fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                }
94a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
95a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
96a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            @Override
97a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            public boolean areContentsTheSame(Item oldItem, Item newItem) {
98a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                return oldItem.cmpField == newItem.cmpField && oldItem.data == newItem.data;
99a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
100a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
101a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            @Override
102a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            public boolean areItemsTheSame(Item item1, Item item2) {
103a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                return item1.id == item2.id;
104a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
105a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        };
1067fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mInsertedCallback = null;
1077fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mChangedCallback = null;
108a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        mList = new SortedList<Item>(Item.class, mCallback);
109a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    }
110a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
111be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
112a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    public void testEmpty() {
113a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals("empty", mList.size(), 0);
114a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    }
115a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
116be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
117a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    public void testAdd() {
118a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        Item item = new Item();
119a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(insert(item), 0);
120a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(size(), 1);
121a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertTrue(mAdditions.contains(new Pair(0, 1)));
122a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        Item item2 = new Item();
123a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        item2.cmpField = item.cmpField + 1;
124a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(insert(item2), 1);
125a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(size(), 2);
126a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertTrue(mAdditions.contains(new Pair(1, 1)));
127a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        Item item3 = new Item();
128a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        item3.cmpField = item.cmpField - 1;
129a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        mAdditions.clear();
130a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(insert(item3), 0);
131a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(size(), 3);
132a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertTrue(mAdditions.contains(new Pair(0, 1)));
133a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    }
134a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
135be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
136a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    public void testAddDuplicate() {
137a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        Item item = new Item();
138a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        Item item2 = new Item(item.id, item.cmpField);
139a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        item2.data = item.data;
140a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        insert(item);
141a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(0, insert(item2));
142a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(1, size());
143a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(1, mAdditions.size());
144a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(0, mUpdates.size());
145a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    }
146a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
147be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
148a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    public void testRemove() {
149a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        Item item = new Item();
150a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertFalse(remove(item));
151a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(0, mRemovals.size());
152a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        insert(item);
153a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertTrue(remove(item));
154a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(1, mRemovals.size());
155a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertTrue(mRemovals.contains(new Pair(0, 1)));
156a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(0, size());
157a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertFalse(remove(item));
158a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(1, mRemovals.size());
159a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    }
160a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
161be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
162a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    public void testRemove2() {
163a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        Item item = new Item();
164a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        Item item2 = new Item(item.cmpField);
165a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        insert(item);
166a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertFalse(remove(item2));
167a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(0, mRemovals.size());
168a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    }
169a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
170be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
17112833d36969f1540dd5fc6fe32a25fa8b52a8e0bYigit Boyar    public void clearTest() {
17212833d36969f1540dd5fc6fe32a25fa8b52a8e0bYigit Boyar        insert(new Item(1));
17312833d36969f1540dd5fc6fe32a25fa8b52a8e0bYigit Boyar        insert(new Item(2));
17412833d36969f1540dd5fc6fe32a25fa8b52a8e0bYigit Boyar        assertEquals(2, mList.size());
17512833d36969f1540dd5fc6fe32a25fa8b52a8e0bYigit Boyar        mList.clear();
17612833d36969f1540dd5fc6fe32a25fa8b52a8e0bYigit Boyar        assertEquals(0, mList.size());
17712833d36969f1540dd5fc6fe32a25fa8b52a8e0bYigit Boyar        insert(new Item(3));
17812833d36969f1540dd5fc6fe32a25fa8b52a8e0bYigit Boyar        assertEquals(1, mList.size());
17912833d36969f1540dd5fc6fe32a25fa8b52a8e0bYigit Boyar    }
18012833d36969f1540dd5fc6fe32a25fa8b52a8e0bYigit Boyar
18112833d36969f1540dd5fc6fe32a25fa8b52a8e0bYigit Boyar    @Test
182a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    public void testBatch() {
183a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        mList.beginBatchedUpdates();
184be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar        for (int i = 0; i < 5; i++) {
185a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            mList.add(new Item(i));
186a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        }
187a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertEquals(0, mAdditions.size());
188a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        mList.endBatchedUpdates();
189a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        assertTrue(mAdditions.contains(new Pair(0, 5)));
190a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    }
191a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
192be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    @Test
193a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    public void testRandom() throws Throwable {
194a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        Random random = new Random(System.nanoTime());
195a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        List<Item> copy = new ArrayList<Item>();
196a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        StringBuilder log = new StringBuilder();
197a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        try {
198a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            for (int i = 0; i < 10000; i++) {
199a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                switch (random.nextInt(3)) {
200a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                    case 0://ADD
201a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                        Item item = new Item();
202a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                        copy.add(item);
203a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                        insert(item);
204be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar                        log.append("add ").append(item).append("\n");
205a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                        break;
206a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                    case 1://REMOVE
207a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                        if (copy.size() > 0) {
208a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            int index = random.nextInt(mList.size());
209a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            item = mList.get(index);
210be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar                            log.append("remove ").append(item).append("\n");
211a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            assertTrue(copy.remove(item));
212a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            assertTrue(mList.remove(item));
213a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                        }
214a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                        break;
215a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                    case 2://UPDATE
216a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                        if (copy.size() > 0) {
217a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            int index = random.nextInt(mList.size());
218a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            item = mList.get(index);
219a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            // TODO this cannot work
220a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            Item newItem = new Item(item.id, item.cmpField);
221be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar                            log.append("update ").append(item).append(" to ").append(newItem)
222be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar                                    .append("\n");
223a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            while (newItem.data == item.data) {
224a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                                newItem.data = random.nextInt(1000);
225a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            }
226a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            int itemIndex = mList.add(newItem);
227a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            copy.remove(item);
228a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            copy.add(newItem);
229a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            assertSame(mList.get(itemIndex), newItem);
230a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            assertNotSame(mList.get(index), item);
231a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                        }
232a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                        break;
233a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                    case 3:// UPDATE AT
234a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                        if (copy.size() > 0) {
235a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            int index = random.nextInt(mList.size());
236a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            item = mList.get(index);
237a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            Item newItem = new Item(item.id, random.nextInt());
238a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            mList.updateItemAt(index, newItem);
239a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            copy.remove(item);
240a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                            copy.add(newItem);
241a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                        }
242a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                }
243a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                int lastCmp = Integer.MIN_VALUE;
244be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar                for (int index = 0; index < copy.size(); index++) {
245a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                    assertFalse(mList.indexOf(copy.get(index)) == SortedList.INVALID_POSITION);
246a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                    assertTrue(mList.get(index).cmpField >= lastCmp);
247a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                    lastCmp = mList.get(index).cmpField;
248a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                    assertTrue(copy.contains(mList.get(index)));
249a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                }
250a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
251be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar                for (int index = 0; index < mList.size(); index++) {
252a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                    assertNotNull(mList.mData[index]);
253a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                }
254be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar                for (int index = mList.size(); index < mList.mData.length; index++) {
255a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                    assertNull(mList.mData[index]);
256a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                }
257a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
258a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
259a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        } catch (Throwable t) {
260a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            Collections.sort(copy, sItemComparator);
261a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            log.append("Items:\n");
262a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            for (Item item : copy) {
263a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                log.append(item).append("\n");
264a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
265a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            log.append("SortedList:\n");
266be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar            for (int i = 0; i < mList.size(); i++) {
267a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                log.append(mList.get(i)).append("\n");
268a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
269a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
270a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            throw new Throwable(" \nlog:\n" + log.toString(), t);
271a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        }
272a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    }
273a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
2747fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    private static Item[] createItems(int idFrom, int idTo, int idStep) {
2757fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        final int count = (idTo - idFrom) / idStep + 1;
2767fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        Item[] items = new Item[count];
2777fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        int id = idFrom;
2787fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int i = 0; i < count; i++) {
2797fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            Item item = new Item(id, id);
2807fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            item.data = id;
2817fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            items[i] = item;
2827fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            id += idStep;
2837fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
2847fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        return items;
2857fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
2867fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
2877fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    private static Item[] shuffle(Item[] items) {
2887fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        Random random = new Random(System.nanoTime());
2897fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        final int count = items.length;
2907fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int i = 0; i < count; i++) {
2917fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            int pos1 = random.nextInt(count);
2927fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            int pos2 = random.nextInt(count);
2937fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            if (pos1 != pos2) {
2947fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                Item temp = items[pos1];
2957fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                items[pos1] = items[pos2];
2967fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                items[pos2] = temp;
2977fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            }
2987fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
2997fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        return items;
3007fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
3017fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
3027fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    private void assertIntegrity(int size, String context) {
3037fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(context + ": incorrect size", size, size());
3047fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        int rangeStart = 0;
3057fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int i = 0; i < size(); i++) {
3067fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            Item item = mList.get(i);
3077fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            assertNotNull(context + ": get returned null @" + i, item);
3087fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            assertEquals(context + ": incorrect indexOf result @" + i, i, mList.indexOf(item));
3097fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            if (i == 0) {
3107fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                continue;
3117fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            }
3127fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
3137fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            final int compare = mCallback.compare(mList.get(i - 1), item);
3147fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            assertTrue(context + ": incorrect sorting order @" + i, compare <= 0);
3157fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
3167fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            if (compare == 0) {
3177fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                for (int j = rangeStart; j < i; j++) {
3187fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    assertFalse(context + ": duplicates found @" + j + " and " + i,
3197fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                            mCallback.areItemsTheSame(mList.get(j), item));
3207fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                }
3217fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            } else {
3227fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                rangeStart = i;
3237fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            }
3247fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
3257fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
3267fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
3277fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    private void assertSequentialOrder() {
3287fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int i = 0; i < size(); i++) {
3297fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            assertEquals(i, mList.get(i).cmpField);
3307fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
3317fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
3327fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
3337fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    @Test
3347fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    public void testAddAllMerge() throws Throwable {
3357fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(new Item[0]);
3367fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertIntegrity(0, "addAll, empty list, empty input");
3377fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(0, mAdditions.size());
3387fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
3397fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Add first 5 even numbers. Test adding to an empty list.
3407fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(createItems(0, 8, 2));
3417fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertIntegrity(5, "addAll, empty list, non-empty input");
3427fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(1, mAdditions.size());
3437fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertTrue(mAdditions.contains(new Pair(0, 5)));
3447fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
3457fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(new Item[0]);
3467fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertIntegrity(5, "addAll, non-empty list, empty input");
3477fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(1, mAdditions.size());
3487fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
3497fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Add 5 more even numbers, shuffled (test pre-sorting).
3507fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(shuffle(createItems(10, 18, 2)));
3517fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertIntegrity(10, "addAll, shuffled input");
3527fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(2, mAdditions.size());
3537fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertTrue(mAdditions.contains(new Pair(5, 5)));
3547fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
3557fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Add 5 more even numbers, reversed (test pre-sorting).
3567fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(shuffle(createItems(28, 20, -2)));
3577fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertIntegrity(15, "addAll, reversed input");
3587fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(3, mAdditions.size());
3597fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertTrue(mAdditions.contains(new Pair(10, 5)));
3607fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
3617fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Add first 10 odd numbers.
3627fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Test the merge when the new items run out first.
3637fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(createItems(1, 19, 2));
3647fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertIntegrity(25, "addAll, merging in the middle");
3657fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(13, mAdditions.size());
3667fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int i = 1; i <= 19; i += 2) {
3677fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            assertTrue(mAdditions.contains(new Pair(i, 1)));
3687fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
3697fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
3707fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Add 10 more odd numbers.
3717fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Test the merge when the old items run out first.
3727fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(createItems(21, 39, 2));
3737fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertIntegrity(35, "addAll, merging at the end");
3747fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(18, mAdditions.size());
3757fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int i = 21; i <= 27; i += 2) {
3767fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            assertTrue(mAdditions.contains(new Pair(i, 1)));
3777fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
3787fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertTrue(mAdditions.contains(new Pair(29, 6)));
3797fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
3807fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Add 5 more even numbers.
3817fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(createItems(30, 38, 2));
3827fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertIntegrity(40, "addAll, merging more");
3837fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(23, mAdditions.size());
3847fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int i = 30; i <= 38; i += 2) {
3857fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            assertTrue(mAdditions.contains(new Pair(i, 1)));
3867fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
3877fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
3887fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(0, mMoves.size());
3897fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(0, mUpdates.size());
3907fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(0, mRemovals.size());
3917fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
3927fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertSequentialOrder();
3937fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
3947fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
3957fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    @Test
3967fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    public void testAddAllUpdates() throws Throwable {
3977fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Add first 5 even numbers.
3987fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        Item[] evenItems = createItems(0, 8, 2);
3997fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (Item item : evenItems) {
4007fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            item.data = 1;
4017fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
4027fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(evenItems);
4037fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(5, size());
4047fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(1, mAdditions.size());
4057fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertTrue(mAdditions.contains(new Pair(0, 5)));
4067fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(0, mUpdates.size());
4077fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
4087fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        Item[] sameEvenItems = createItems(0, 8, 2);
4097fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (Item item : sameEvenItems) {
4107fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            item.data = 1;
4117fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
4127fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(sameEvenItems);
4137fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(1, mAdditions.size());
4147fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(0, mUpdates.size());
4157fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
4167fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        Item[] newEvenItems = createItems(0, 8, 2);
4177fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (Item item : newEvenItems) {
4187fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            item.data = 2;
4197fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
4207fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(newEvenItems);
4217fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(5, size());
4227fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(1, mAdditions.size());
4237fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(1, mUpdates.size());
4247fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertTrue(mUpdates.contains(new Pair(0, 5)));
4257fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int i = 0; i < 5; i++) {
4267fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            assertEquals(2, mList.get(i).data);
4277fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
4287fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
4297fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Add all numbers from 0 to 9
4307fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        Item[] sequentialItems = createItems(0, 9, 1);
4317fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (Item item : sequentialItems) {
4327fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            item.data = 3;
4337fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
4347fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(sequentialItems);
4357fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
4367fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Odd numbers should have been added.
4377fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(6, mAdditions.size());
4387fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int i = 0; i < 5; i++) {
4397fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            assertTrue(mAdditions.contains(new Pair(i * 2 + 1, 1)));
4407fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
4417fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
4427fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // All even items should have been updated.
4437fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(6, mUpdates.size());
4447fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int i = 0; i < 5; i++) {
4457fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            assertTrue(mUpdates.contains(new Pair(i * 2, 1)));
4467fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
4477fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
4487fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(10, size());
4497fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
4507fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // All items should have the latest data value.
4517fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int i = 0; i < 10; i++) {
4527fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            assertEquals(3, mList.get(i).data);
4537fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
4547fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(0, mMoves.size());
4557fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(0, mRemovals.size());
4567fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertSequentialOrder();
4577fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
4587fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
4597fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    @Test
4607fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    public void testAddAllWithDuplicates() throws Throwable {
4617fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        final int maxCmpField = 5;
4627fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        final int idsPerCmpField = 10;
4637fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        final int maxUniqueId = maxCmpField * idsPerCmpField;
4647fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        final int maxGeneration = 5;
4657fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
4667fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        Item[] items = new Item[maxUniqueId * maxGeneration];
4677fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
4687fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        int index = 0;
4697fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int generation = 0; generation < maxGeneration; generation++) {
4707fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            int uniqueId = 0;
4717fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            for (int cmpField = 0; cmpField < maxCmpField; cmpField++) {
4727fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                for (int id = 0; id < idsPerCmpField; id++) {
4737fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    Item item = new Item(uniqueId++, cmpField);
4747fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    item.data = generation;
4757fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    items[index++] = item;
4767fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                }
4777fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            }
4787fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
4797fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
4807fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(items);
4817fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
4827fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertIntegrity(maxUniqueId, "addAll with duplicates");
4837fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
4847fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Check that the most recent items have made it to the list.
4857fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int i = 0; i != size(); i++) {
4867fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            Item item = mList.get(i);
4877fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            assertEquals(maxGeneration - 1, item.data);
4887fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
4897fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
4907fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
4917fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    @Test
4927fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    public void testAddAllFast() throws Throwable {
4937fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(new Item[0], true);
4947fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertIntegrity(0, "addAll(T[],boolean), empty list, with empty input");
4957fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(0, mAdditions.size());
4967fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
4977fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(createItems(0, 9, 1), true);
4987fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertIntegrity(10, "addAll(T[],boolean), empty list, non-empty input");
4997fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(1, mAdditions.size());
5007fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertTrue(mAdditions.contains(new Pair(0, 10)));
5017fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5027fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(new Item[0], true);
5037fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(1, mAdditions.size());
5047fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertIntegrity(10, "addAll(T[],boolean), non-empty list, empty input");
5057fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5067fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(createItems(10, 19, 1), true);
5077fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(2, mAdditions.size());
5087fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertTrue(mAdditions.contains(new Pair(10, 10)));
5097fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertIntegrity(20, "addAll(T[],boolean), non-empty list, non-empty input");
5107fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
5117fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5127fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    @Test
5137fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    public void testAddAllCollection() throws Throwable {
5147fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        Collection<Item> itemList = new ArrayList<Item>();
5157fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int i = 0; i < 5; i++) {
5167fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            itemList.add(new Item(i));
5177fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
5187fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(itemList);
5197fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5207fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(1, mAdditions.size());
5217fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertTrue(mAdditions.contains(new Pair(0, itemList.size())));
5227fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertIntegrity(itemList.size(), "addAll on collection");
5237fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
5247fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5257fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    @Test
5267fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    public void testAddAllStableSort() {
5277fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        int id = 0;
5287fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        Item item = new Item(id++, 0);
5297fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.add(item);
5307fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5317fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Create a few items with the same sort order.
5327fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        Item[] items = new Item[3];
5337fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int i = 0; i < 3; i++) {
5347fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            items[i] = new Item(id++, item.cmpField);
5357fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            assertEquals(0, mCallback.compare(item, items[i]));
5367fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
5377fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5387fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(items);
5397fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(1 + items.length, size());
5407fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5417fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Check that the order has been preserved.
5427fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (int i = 0; i < size(); i++) {
5437fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            assertEquals(i, mList.get(i).id);
5447fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
5457fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
5467fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5477fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5487fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    @Test
5497fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    public void testAddAllAccessFromCallbacks() {
5507fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Add first 5 even numbers.
5517fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        Item[] evenItems = createItems(0, 8, 2);
5527fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (Item item : evenItems) {
5537fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            item.data = 1;
5547fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
5557fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5567fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mInsertedCallback = new InsertedCallback<Item>() {
5577fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            @Override
5587fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            public void onInserted(int position, int count) {
5597fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                assertEquals(0, position);
5607fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                assertEquals(5, count);
5617fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                for (int i = 0; i < count; i++) {
5627fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    assertEquals(i * 2, mList.get(i).id);
5637fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                }
5647fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                assertIntegrity(5, "onInserted(" + position + ", " + count + ")");
5657fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            }
5667fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        };
5677fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5687fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(evenItems);
5697fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(1, mAdditions.size());
5707fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(0, mUpdates.size());
5717fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5727fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Add all numbers from 0 to 9. This should trigger 5 change and 5 insert notifications.
5737fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        Item[] sequentialItems = createItems(0, 9, 1);
5747fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (Item item : sequentialItems) {
5757fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            item.data = 2;
5767fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
5777fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5787fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mChangedCallback = new ChangedCallback<Item>() {
5797fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            int expectedSize = 5;
5807fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5817fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            @Override
5827fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            public void onChanged(int position, int count) {
5837fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                assertEquals(1, count);
5847fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                assertEquals(position, mList.get(position).id);
5857fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                assertIntegrity(++expectedSize, "onChanged(" + position + ")");
5867fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            }
5877fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        };
5887fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5897fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mInsertedCallback = new InsertedCallback<Item>() {
5907fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            int expectedSize = 5;
5917fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
5927fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            @Override
5937fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            public void onInserted(int position, int count) {
5947fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                assertEquals(1, count);
5957fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                assertEquals(position, mList.get(position).id);
5967fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                assertIntegrity(++expectedSize, "onInserted(" + position + ")");
5977fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            }
5987fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        };
5997fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
6007fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(sequentialItems);
6017fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(6, mAdditions.size());
6027fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(5, mUpdates.size());
6037fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
6047fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
6057fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    @Test
6067fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    public void testModificationFromCallbackThrows() {
6077fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        final Item extraItem = new Item(0);
6087fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
6097fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        Item[] items = createItems(1, 5, 2);
6107fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (Item item : items) {
6117fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            item.data = 1;
6127fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
6137fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(items);
6147fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
6157fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mInsertedCallback = new InsertedCallback<Item>() {
6167fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            @Override
6177fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            public void onInserted(int position, int count) {
6187fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                try {
6197fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    mList.add(new Item());
6207fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    fail("add must throw from within a callback");
6217fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                } catch (IllegalStateException e) {
6227fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                }
6237fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                try {
6247fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    mList.addAll(createItems(0, 0, 1));
6257fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    fail("addAll must throw from within a callback");
6267fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                } catch (IllegalStateException e) {
6277fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                }
6287fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                try {
6297fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    mList.addAll(createItems(0, 0, 1), true);
6307fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    fail("addAll(T[],boolean) must throw from within a callback");
6317fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                } catch (IllegalStateException e) {
6327fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                }
6337fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                try {
6347fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    mList.remove(extraItem);
6357fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    fail("remove must throw from within a callback");
6367fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                } catch (IllegalStateException e) {
6377fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                }
6387fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                try {
6397fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    mList.removeItemAt(0);
6407fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    fail("removeItemAt must throw from within a callback");
6417fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                } catch (IllegalStateException e) {
6427fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                }
6437fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                try {
6447fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    mList.updateItemAt(0, extraItem);
6457fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    fail("updateItemAt must throw from within a callback");
6467fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                } catch (IllegalStateException e) {
6477fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                }
6487fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                try {
6497fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    mList.recalculatePositionOfItemAt(0);
6507fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    fail("recalculatePositionOfItemAt must throw from within a callback");
6517fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                } catch (IllegalStateException e) {
6527fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                }
6537fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                try {
6547fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    mList.clear();
6557fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                    fail("recalculatePositionOfItemAt must throw from within a callback");
6567fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                } catch (IllegalStateException e) {
6577fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev                }
6587fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            }
6597fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        };
6607fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
6617fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // Make sure that the last one notification is change, so that the above callback is
6627fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        // not called from endBatchUpdates when the nested alls are actually OK.
6637fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        items = createItems(1, 5, 1);
6647fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        for (Item item : items) {
6657fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev            item.data = 2;
6667fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        }
6677fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(items);
6687fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertIntegrity(5, "Modification from callback");
6697fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
6707fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
6717fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    @Test
6727fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    public void testAddAllOutsideBatchedUpdates() {
6737fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.add(new Item(1));
6747fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(1, mAdditions.size());
6757fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.add(new Item(2));
6767fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(2, mAdditions.size());
6777fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(new Item(3), new Item(4));
6787fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(3, mAdditions.size());
6797fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.add(new Item(5));
6807fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(4, mAdditions.size());
6817fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.add(new Item(6));
6827fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(5, mAdditions.size());
6837fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
6847fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
6857fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    @Test
6867fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    public void testAddAllInsideBatchedUpdates() {
6877fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.beginBatchedUpdates();
6887fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
6897fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.add(new Item(1));
6907fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(0, mAdditions.size());
6917fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.add(new Item(2));
6927fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(0, mAdditions.size());
6937fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.addAll(new Item(3), new Item(4));
6947fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(0, mAdditions.size());
6957fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.add(new Item(5));
6967fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(0, mAdditions.size());
6977fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.add(new Item(6));
6987fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(0, mAdditions.size());
6997fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
7007fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        mList.endBatchedUpdates();
7017fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
7027fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertEquals(1, mAdditions.size());
7037fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev        assertTrue(mAdditions.contains(new Pair(0, 6)));
7047fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev    }
7057fa39157f88d13bc417dab8db7c13e342a14cba0Vladislav Kaznacheev
706a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    private int size() {
707a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        return mList.size();
708a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    }
709a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
710a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    private int insert(Item item) {
711a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        return mList.add(item);
712a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    }
713a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
714be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar    private boolean remove(Item item) {
715a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        return mList.remove(item);
716a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    }
717a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
718a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    static class Item {
719be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar
720a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        static int idCounter = 0;
721a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        final int id;
722a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
723a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        int cmpField;
724a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
725a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        int data = (int) (Math.random() * 1000);//used for comparison
726a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
727a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        public Item() {
728be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar            id = idCounter++;
729a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            cmpField = (int) (Math.random() * 1000);
730a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        }
731a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
732a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        public Item(int cmpField) {
733be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar            id = idCounter++;
734a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            this.cmpField = cmpField;
735a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        }
736a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
737a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        public Item(int id, int cmpField) {
738a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            this.id = id;
739a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            this.cmpField = cmpField;
740a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        }
741a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
742a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        @Override
743a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        public boolean equals(Object o) {
744a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            if (this == o) {
745a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                return true;
746a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
747a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            if (o == null || getClass() != o.getClass()) {
748a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                return false;
749a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
750a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
751a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            Item item = (Item) o;
752a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
753a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            if (cmpField != item.cmpField) {
754a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                return false;
755a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
756a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            if (id != item.id) {
757a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                return false;
758a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
759a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
760a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            return true;
761a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        }
762a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
763a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        @Override
764a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        public int hashCode() {
765a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            int result = id;
766a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            result = 31 * result + cmpField;
767a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            return result;
768a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        }
769a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
770a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        @Override
771a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        public String toString() {
772a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            return "Item{" +
773a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                    "id=" + id +
774a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                    ", cmpField=" + cmpField +
775a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                    ", data=" + data +
776a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                    '}';
777a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        }
778a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    }
779a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
780a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    private static final class Pair {
781be7a54a6e02c9230a08e63f1c964907d129b6a10Yigit Boyar
782a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        final int first, second;
783a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
784a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        public Pair(int first) {
785a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            this.first = first;
786a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            this.second = Integer.MIN_VALUE;
787a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        }
788a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
789a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        public Pair(int first, int second) {
790a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            this.first = first;
791a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            this.second = second;
792a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        }
793a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
794a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        @Override
795a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        public boolean equals(Object o) {
796a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            if (this == o) {
797a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                return true;
798a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
799a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            if (o == null || getClass() != o.getClass()) {
800a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                return false;
801a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
802a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
803a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            Pair pair = (Pair) o;
804a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
805a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            if (first != pair.first) {
806a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                return false;
807a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
808a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            if (second != pair.second) {
809a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar                return false;
810a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            }
811a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
812a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            return true;
813a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        }
814a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar
815a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        @Override
816a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        public int hashCode() {
817a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            int result = first;
818a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            result = 31 * result + second;
819a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar            return result;
820a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar        }
821a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar    }
822a3d5bb01bc01733999d84c452a27012c57ab369cYigit Boyar}