1/*
2 * Copyright (C) 2010 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 */
16package com.android.contacts.widget;
17
18import android.content.Context;
19import android.database.DataSetObserver;
20import android.test.AndroidTestCase;
21import android.view.View;
22import android.view.ViewGroup;
23import android.widget.ArrayAdapter;
24
25import com.google.common.collect.Lists;
26
27import java.util.ArrayList;
28import java.util.HashMap;
29import java.util.HashSet;
30import java.util.List;
31
32/**
33 * Tests for {@link CompositeListAdapter}.
34 */
35public class CompositeListAdapterTest extends AndroidTestCase {
36
37    private final class MockAdapter extends ArrayAdapter<String> {
38        boolean allItemsEnabled = true;
39        HashSet<Integer> enabledItems = new HashSet<Integer>();
40        int viewTypeCount = 1;
41        HashMap<Integer, Integer> viewTypes = new HashMap<Integer, Integer>();
42
43        private MockAdapter(Context context, List<String> objects) {
44            super(context, android.R.layout.simple_list_item_1, objects);
45            for (int i = 0; i < objects.size(); i++) {
46                viewTypes.put(i, 0);
47            }
48        }
49
50        @Override
51        public View getView(int position, View convertView, ViewGroup parent) {
52            return new MockView(getContext(), position);
53        }
54
55        @Override
56        public boolean areAllItemsEnabled() {
57            return allItemsEnabled;
58        }
59
60        @Override
61        public boolean isEnabled(int position) {
62            return enabledItems.contains(position);
63        }
64
65        @Override
66        public int getViewTypeCount() {
67            return viewTypeCount;
68        }
69
70        @Override
71        public int getItemViewType(int position) {
72            return viewTypes.get(position);
73        }
74    }
75
76    private final class MockView extends View {
77        public MockView(Context context, int position) {
78            super(context);
79            setTag(position);
80        }
81    }
82
83    private final class TestDataSetObserver extends DataSetObserver {
84
85        public int changeCount;
86        public int invalidationCount;
87
88        @Override
89        public void onChanged() {
90            changeCount++;
91        }
92
93        @Override
94        public void onInvalidated() {
95            invalidationCount++;
96        }
97    }
98
99    private MockAdapter mAdapter1;
100    private MockAdapter mAdapter2;
101    private MockAdapter mAdapter3;
102
103    @Override
104    protected void setUp() throws Exception {
105        super.setUp();
106        mAdapter1 = new MockAdapter(getContext(), Lists.newArrayList("A", "B"));
107        mAdapter2 = new MockAdapter(getContext(), new ArrayList<String>());
108        mAdapter3 = new MockAdapter(getContext(), Lists.newArrayList("C", "D", "E"));
109    }
110
111    public void testGetCount() {
112        CompositeListAdapter adapter = new CompositeListAdapter();
113        adapter.addAdapter(mAdapter1);
114        adapter.addAdapter(mAdapter2);
115        adapter.addAdapter(mAdapter3);
116
117        assertEquals(5, adapter.getCount());
118    }
119
120    public void testGetCountWithInvalidation() {
121        CompositeListAdapter adapter = new CompositeListAdapter();
122        assertEquals(0, adapter.getCount());
123
124        adapter.addAdapter(mAdapter1);
125        assertEquals(2, adapter.getCount());
126
127        adapter.addAdapter(mAdapter2);
128        assertEquals(2, adapter.getCount());
129
130        adapter.addAdapter(mAdapter3);
131        assertEquals(5, adapter.getCount());
132    }
133
134    public void testGetItem() {
135        CompositeListAdapter adapter = new CompositeListAdapter();
136        adapter.addAdapter(mAdapter1);
137        adapter.addAdapter(mAdapter2);
138        adapter.addAdapter(mAdapter3);
139
140        assertEquals("A", adapter.getItem(0));
141        assertEquals("B", adapter.getItem(1));
142        assertEquals("C", adapter.getItem(2));
143        assertEquals("D", adapter.getItem(3));
144        assertEquals("E", adapter.getItem(4));
145    }
146
147    public void testGetItemId() {
148        CompositeListAdapter adapter = new CompositeListAdapter();
149        adapter.addAdapter(mAdapter1);
150        adapter.addAdapter(mAdapter2);
151        adapter.addAdapter(mAdapter3);
152
153        assertEquals(0, adapter.getItemId(0));
154        assertEquals(1, adapter.getItemId(1));
155        assertEquals(0, adapter.getItemId(2));
156        assertEquals(1, adapter.getItemId(3));
157        assertEquals(2, adapter.getItemId(4));
158    }
159
160    public void testGetView() {
161        CompositeListAdapter adapter = new CompositeListAdapter();
162        adapter.addAdapter(mAdapter1);
163        adapter.addAdapter(mAdapter2);
164        adapter.addAdapter(mAdapter3);
165
166        assertEquals(0, adapter.getView(0, null, null).getTag());
167        assertEquals(1, adapter.getView(1, null, null).getTag());
168        assertEquals(0, adapter.getView(2, null, null).getTag());
169        assertEquals(1, adapter.getView(3, null, null).getTag());
170        assertEquals(2, adapter.getView(4, null, null).getTag());
171    }
172
173    public void testGetViewTypeCount() {
174        mAdapter1.viewTypeCount = 2;
175        mAdapter2.viewTypeCount = 3;
176        CompositeListAdapter adapter = new CompositeListAdapter();
177        adapter.addAdapter(mAdapter1);
178        adapter.addAdapter(mAdapter2);
179        adapter.addAdapter(mAdapter3);
180
181        // Note that mAdapter2 adds an implicit +1
182        assertEquals(6, adapter.getViewTypeCount());
183    }
184
185    public void testGetItemViewType() {
186        mAdapter1.viewTypeCount = 2;
187        mAdapter1.viewTypes.put(0, 1);
188        mAdapter1.viewTypes.put(1, 0);
189
190        mAdapter3.viewTypeCount = 3;
191        mAdapter3.viewTypes.put(0, 1);
192        mAdapter3.viewTypes.put(1, 2);
193        mAdapter3.viewTypes.put(2, 0);
194
195        CompositeListAdapter adapter = new CompositeListAdapter();
196        adapter.addAdapter(mAdapter1);
197        adapter.addAdapter(mAdapter2);
198        adapter.addAdapter(mAdapter3);
199
200        assertEquals(1, adapter.getItemViewType(0));
201        assertEquals(0, adapter.getItemViewType(1));
202
203        // Note: mAdapter2 throws in a +1
204
205        assertEquals(4, adapter.getItemViewType(2));
206        assertEquals(5, adapter.getItemViewType(3));
207        assertEquals(3, adapter.getItemViewType(4));
208    }
209
210    public void testNotifyDataSetChangedPropagated() {
211        CompositeListAdapter adapter = new CompositeListAdapter();
212        adapter.addAdapter(mAdapter1);
213        adapter.addAdapter(mAdapter2);
214
215        TestDataSetObserver observer = new TestDataSetObserver();
216        adapter.registerDataSetObserver(observer);
217        mAdapter1.add("X");
218
219        assertEquals(1, observer.changeCount);
220        assertEquals(0, observer.invalidationCount);
221        assertEquals(3, adapter.getCount());
222        assertEquals("A", adapter.getItem(0));
223        assertEquals("B", adapter.getItem(1));
224        assertEquals("X", adapter.getItem(2));
225
226        mAdapter2.add("Y");
227        assertEquals(2, observer.changeCount);
228        assertEquals(0, observer.invalidationCount);
229        assertEquals(4, adapter.getCount());
230        assertEquals("A", adapter.getItem(0));
231        assertEquals("B", adapter.getItem(1));
232        assertEquals("X", adapter.getItem(2));
233        assertEquals("Y", adapter.getItem(3));
234
235    }
236
237    public void testNotifyDataSetChangedOnAddingAdapter() {
238        CompositeListAdapter adapter = new CompositeListAdapter();
239        adapter.addAdapter(mAdapter1);
240
241        TestDataSetObserver observer = new TestDataSetObserver();
242        adapter.registerDataSetObserver(observer);
243        adapter.addAdapter(mAdapter3);
244
245        assertEquals(1, observer.changeCount);
246        assertEquals(0, observer.invalidationCount);
247        assertEquals(5, adapter.getCount());
248        assertEquals("A", adapter.getItem(0));
249        assertEquals("B", adapter.getItem(1));
250        assertEquals("C", adapter.getItem(2));
251        assertEquals("D", adapter.getItem(3));
252        assertEquals("E", adapter.getItem(4));
253    }
254
255    public void testNotifyDataSetInvalidated() {
256        CompositeListAdapter adapter = new CompositeListAdapter();
257        adapter.addAdapter(mAdapter1);
258
259        TestDataSetObserver observer = new TestDataSetObserver();
260        adapter.registerDataSetObserver(observer);
261
262        mAdapter1.remove("A");
263        assertEquals(1, observer.changeCount);
264        assertEquals(0, observer.invalidationCount);
265        assertEquals(1, adapter.getCount());
266
267        mAdapter1.remove("B");
268        assertEquals(1, observer.changeCount);
269        assertEquals(1, observer.invalidationCount);
270        assertEquals(0, adapter.getCount());
271    }
272
273    public void testAreAllItemsEnabled() {
274        CompositeListAdapter adapter = new CompositeListAdapter();
275        adapter.addAdapter(mAdapter1);
276        adapter.addAdapter(mAdapter3);
277
278        assertTrue(adapter.areAllItemsEnabled());
279    }
280
281    public void testAreAllItemsEnabledWithInvalidation() {
282        CompositeListAdapter adapter = new CompositeListAdapter();
283        adapter.addAdapter(mAdapter1);
284        assertTrue(adapter.areAllItemsEnabled());
285
286        mAdapter3.allItemsEnabled = false;
287        adapter.addAdapter(mAdapter3);
288
289        assertFalse(adapter.areAllItemsEnabled());
290    }
291
292    public void testIsEnabled() {
293        mAdapter1.allItemsEnabled = false;
294        mAdapter1.enabledItems.add(1);
295
296        CompositeListAdapter adapter = new CompositeListAdapter();
297        adapter.addAdapter(mAdapter1);
298        adapter.addAdapter(mAdapter2);
299        adapter.addAdapter(mAdapter3);
300
301        assertFalse(adapter.isEnabled(0));
302        assertTrue(adapter.isEnabled(1));
303        assertTrue(adapter.isEnabled(2));
304        assertTrue(adapter.isEnabled(3));
305        assertTrue(adapter.isEnabled(4));
306    }
307
308    public void testIsEnabledWhenAllEnabledAtLeastOneAdapter() {
309        mAdapter1.allItemsEnabled = false;
310        mAdapter1.enabledItems.add(1);
311        mAdapter3.allItemsEnabled = false;
312        mAdapter3.enabledItems.add(1);
313
314        CompositeListAdapter adapter = new CompositeListAdapter();
315        adapter.addAdapter(mAdapter1);
316        adapter.addAdapter(mAdapter3);
317
318        assertFalse(adapter.isEnabled(0));
319        assertTrue(adapter.isEnabled(1));
320        assertFalse(adapter.isEnabled(2));
321        assertTrue(adapter.isEnabled(3));
322        assertFalse(adapter.isEnabled(4));
323    }
324}
325