1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.support.v7.util;
18
19import junit.framework.TestCase;
20
21import org.junit.Test;
22import org.junit.runner.RunWith;
23import org.junit.runners.JUnit4;
24
25import android.test.suitebuilder.annotation.SmallTest;
26
27import static android.support.v7.util.SortedList.BatchedCallback.TYPE_NONE;
28import static android.support.v7.util.SortedList.BatchedCallback.TYPE_ADD;
29import static android.support.v7.util.SortedList.BatchedCallback.TYPE_REMOVE;
30import static android.support.v7.util.SortedList.BatchedCallback.TYPE_CHANGE;
31import static android.support.v7.util.SortedList.BatchedCallback.TYPE_MOVE;
32
33@RunWith(JUnit4.class)
34@SmallTest
35public class SortedListAdapterCallbackWrapperTest extends TestCase {
36
37    private int lastReceivedType = TYPE_NONE;
38    private int lastReceivedPosition = -1;
39    private int lastReceivedCount = -1;
40
41    private SortedList.Callback<Object> mCallback = new SortedList.Callback<Object>() {
42        @Override
43        public int compare(Object o1, Object o2) {
44            return 0;
45        }
46
47        @Override
48        public void onInserted(int position, int count) {
49            lastReceivedType = TYPE_ADD;
50            lastReceivedPosition = position;
51            lastReceivedCount = count;
52        }
53
54        @Override
55        public void onRemoved(int position, int count) {
56            lastReceivedType = TYPE_REMOVE;
57            lastReceivedPosition = position;
58            lastReceivedCount = count;
59        }
60
61        @Override
62        public void onMoved(int fromPosition, int toPosition) {
63            lastReceivedType = TYPE_MOVE;
64            lastReceivedPosition = fromPosition;
65            lastReceivedCount = toPosition;
66        }
67
68        @Override
69        public void onChanged(int position, int count) {
70            lastReceivedType = TYPE_CHANGE;
71            lastReceivedPosition = position;
72            lastReceivedCount = count;
73        }
74
75        @Override
76        public boolean areContentsTheSame(Object oldItem, Object newItem) {
77            return false;
78        }
79
80        @Override
81        public boolean areItemsTheSame(Object item1, Object item2) {
82            return false;
83        }
84    };
85
86    private SortedList.BatchedCallback<Object> mBatched =
87            new SortedList.BatchedCallback<Object>(mCallback);
88
89    @Test
90    public void testAdd() throws Throwable {
91        mBatched.onInserted(0, 3);
92        assertPending(TYPE_ADD, 0, 3);
93        assertLast(TYPE_NONE, -1, -1);
94        mBatched.dispatchLastEvent();
95        assertLast(TYPE_ADD, 0, 3);
96        assertPending(TYPE_NONE, -1, -1);
97    }
98
99    @Test
100    public void testRemove() throws Throwable {
101        mBatched.onRemoved(0, 3);
102        assertPending(TYPE_REMOVE, 0, 3);
103        assertLast(TYPE_NONE, -1, -1);
104        mBatched.dispatchLastEvent();
105        assertLast(TYPE_REMOVE, 0, 3);
106        assertPending(TYPE_NONE, -1, -1);
107    }
108
109    @Test
110    public void testChange() throws Throwable {
111        mBatched.onChanged(0, 3);
112        assertPending(TYPE_CHANGE, 0, 3);
113        assertLast(TYPE_NONE, -1, -1);
114        mBatched.dispatchLastEvent();
115        assertLast(TYPE_CHANGE, 0, 3);
116        assertPending(TYPE_NONE, -1, -1);
117    }
118
119    @Test
120    public void testMove() throws Throwable {
121        mBatched.onMoved(0, 3);
122        assertLast(TYPE_MOVE, 0, 3);
123        assertPending(TYPE_NONE, -1, -1);
124    }
125
126    @Test
127    public void testBatchAdd1() throws Throwable {
128        mBatched.onInserted(3, 5);
129        mBatched.onInserted(3, 2);
130        assertLast(TYPE_NONE, -1, -1);
131        mBatched.dispatchLastEvent();
132        assertLast(TYPE_ADD, 3, 7);
133        assertPending(TYPE_NONE, -1, -1);
134    }
135
136    @Test
137    public void testBatchAdd2() throws Throwable {
138        mBatched.onInserted(3, 5);
139        mBatched.onInserted(1, 2);
140        assertLast(TYPE_ADD, 3, 5);
141        mBatched.dispatchLastEvent();
142        assertLast(TYPE_ADD, 1, 2);
143        assertPending(TYPE_NONE, -1, -1);
144    }
145
146    @Test
147    public void testBatchAdd3() throws Throwable {
148        mBatched.onInserted(3, 5);
149        mBatched.onInserted(8, 2);
150        assertLast(TYPE_NONE, -1, -1);
151        mBatched.dispatchLastEvent();
152        assertLast(TYPE_ADD, 3, 7);
153        assertPending(TYPE_NONE, -1, -1);
154    }
155
156    @Test
157    public void testBatchAdd4() throws Throwable {
158        mBatched.onInserted(3, 5);
159        mBatched.onInserted(9, 2);
160        assertLast(TYPE_ADD, 3, 5);
161        mBatched.dispatchLastEvent();
162        assertLast(TYPE_ADD, 9, 2);
163        assertPending(TYPE_NONE, -1, -1);
164    }
165
166    @Test
167    public void testBatchAdd5() throws Throwable {
168        mBatched.onInserted(3, 5);
169        mBatched.onInserted(4, 1);
170        assertLast(TYPE_NONE, -1, -1);
171        mBatched.dispatchLastEvent();
172        assertLast(TYPE_ADD, 3, 6);
173        assertPending(TYPE_NONE, -1, -1);
174    }
175
176    @Test
177    public void testBatchAdd6() throws Throwable {
178        mBatched.onInserted(3, 5);
179        mBatched.onInserted(4, 1);
180        assertLast(TYPE_NONE, -1, -1);
181        mBatched.onInserted(4, 1);
182        mBatched.dispatchLastEvent();
183        assertLast(TYPE_ADD, 3, 7);
184        assertPending(TYPE_NONE, -1, -1);
185    }
186
187    @Test
188    public void testBatchAddLoop() throws Throwable {
189        for (int i = 0; i < 10; i++) {
190            mBatched.onInserted(4 + i, 1);
191            assertLast(TYPE_NONE, -1, -1);
192            assertPending(TYPE_ADD, 4, i + 1);
193        }
194        mBatched.dispatchLastEvent();
195        assertLast(TYPE_ADD, 4, 10);
196    }
197
198    @Test
199    public void testBatchAddReverseLoop() throws Throwable {
200        for (int i = 10; i >= 0; i--) {
201            mBatched.onInserted(4, 1);
202            assertLast(TYPE_NONE, -1, -1);
203            assertPending(TYPE_ADD, 4, 10 - i + 1);
204        }
205        mBatched.dispatchLastEvent();
206        assertLast(TYPE_ADD, 4, 11);
207    }
208
209    @Test
210    public void testBadBatchAddReverseLoop() throws Throwable {
211        for (int i = 10; i >= 0; i--) {
212            mBatched.onInserted(4 + i, 1);
213            if (i < 10) {
214                assertLast(TYPE_ADD, 4 + i + 1, 1);
215            }
216
217        }
218        mBatched.dispatchLastEvent();
219        assertLast(TYPE_ADD, 4, 1);
220    }
221
222    @Test
223    public void testBatchRemove1() throws Throwable {
224        mBatched.onRemoved(3, 5);
225        mBatched.onRemoved(3, 1);
226        assertLast(TYPE_NONE, -1, -1);
227        mBatched.dispatchLastEvent();
228        assertLast(TYPE_REMOVE, 3, 6);
229        assertPending(TYPE_NONE, -1, -1);
230    }
231
232    @Test
233    public void testBatchRemove2() throws Throwable {
234        mBatched.onRemoved(3, 5);
235        mBatched.onRemoved(4, 1);
236        assertLast(TYPE_REMOVE, 3, 5);
237        mBatched.dispatchLastEvent();
238        assertLast(TYPE_REMOVE, 4, 1);
239        assertPending(TYPE_NONE, -1, -1);
240    }
241
242    @Test
243    public void testBatchRemove3() throws Throwable {
244        mBatched.onRemoved(3, 5);
245        mBatched.onRemoved(2, 3);
246        assertLast(TYPE_REMOVE, 3, 5);
247        mBatched.dispatchLastEvent();
248        assertLast(TYPE_REMOVE, 2, 3);
249        assertPending(TYPE_NONE, -1, -1);
250    }
251
252    @Test
253    public void testBatchChange1() throws Throwable {
254        mBatched.onChanged(3, 5);
255        mBatched.onChanged(3, 1);
256        assertPending(TYPE_CHANGE, 3, 5);
257        assertLast(TYPE_NONE, -1, -1);
258        mBatched.dispatchLastEvent();
259        assertLast(TYPE_CHANGE, 3, 5);
260        assertPending(TYPE_NONE, -1, -1);
261    }
262
263    @Test
264    public void testBatchChange2() throws Throwable {
265        mBatched.onChanged(3, 5);
266        mBatched.onChanged(2, 7);
267        assertPending(TYPE_CHANGE, 2, 7);
268        assertLast(TYPE_NONE, -1, -1);
269        mBatched.dispatchLastEvent();
270        assertLast(TYPE_CHANGE, 2, 7);
271        assertPending(TYPE_NONE, -1, -1);
272    }
273
274    @Test
275    public void testBatchChange3() throws Throwable {
276        mBatched.onChanged(3, 5);
277        mBatched.onChanged(2, 1);
278        assertLast(TYPE_NONE, -1, -1);
279        mBatched.onChanged(8, 2);
280        assertLast(TYPE_NONE, -1, -1);
281        assertPending(TYPE_CHANGE, 2, 8);
282    }
283
284    @Test
285    public void testBatchChange4() throws Throwable {
286        mBatched.onChanged(3, 5);
287        mBatched.onChanged(1, 1);
288        assertLast(TYPE_CHANGE, 3, 5);
289        assertPending(TYPE_CHANGE, 1, 1);
290    }
291
292    @Test
293    public void testBatchChange5() throws Throwable {
294        mBatched.onChanged(3, 5);
295        mBatched.onChanged(9, 1);
296        assertLast(TYPE_CHANGE, 3, 5);
297        assertPending(TYPE_CHANGE, 9, 1);
298    }
299
300    private void assertLast(int type, int position, int count) throws Throwable {
301        try {
302            assertEquals(lastReceivedType, type);
303            if (position >= 0) {
304                assertEquals(lastReceivedPosition, position);
305            }
306            if (count >= 0) {
307                assertEquals(lastReceivedCount, count);
308            }
309        } catch (Throwable t) {
310            throw new Throwable("last event: expected=" + log(type, position, count)
311                    + " found=" + log(lastReceivedType, lastReceivedPosition,
312                    lastReceivedCount), t);
313        }
314    }
315
316    private void assertPending(int type, int position, int count) throws Throwable {
317        try {
318            assertEquals(mBatched.mLastEventType, type);
319            if (position >= 0) {
320                assertEquals(mBatched.mLastEventPosition, position);
321            }
322            if (count >= 0) {
323                assertEquals(mBatched.mLastEventCount, count);
324            }
325        } catch (Throwable t) {
326            throw new Throwable("pending event: expected=" + log(type, position, count)
327                    + " found=" + log(mBatched.mLastEventType, mBatched.mLastEventPosition,
328                    mBatched.mLastEventCount), t);
329        }
330    }
331
332    private String log(int type, int position, int count) {
333        return TYPES_NAMES[type]
334                + ", p:" + position
335                + ", c:" + count;
336    }
337
338    private static final String[] TYPES_NAMES = new String[]{"none", "add", "remove", "change",
339            "move"};
340}
341