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