17b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov/*
27b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov * Copyright (C) 2010 The Android Open Source Project
37b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov *
47b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License");
57b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov * you may not use this file except in compliance with the License.
67b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov * You may obtain a copy of the License at
77b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov *
87b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov *      http://www.apache.org/licenses/LICENSE-2.0
97b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov *
107b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov * Unless required by applicable law or agreed to in writing, software
117b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS,
127b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov * See the License for the specific language governing permissions and
147b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov * limitations under the License.
157b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov */
167b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
177b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikovpackage com.android.common.widget;
187b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
197b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikovimport static com.android.common.widget.GroupingListAdapter.ITEM_TYPE_GROUP_HEADER;
207b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikovimport static com.android.common.widget.GroupingListAdapter.ITEM_TYPE_IN_GROUP;
217b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikovimport static com.android.common.widget.GroupingListAdapter.ITEM_TYPE_STANDALONE;
227b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
237b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikovimport android.content.Context;
247b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikovimport android.database.Cursor;
257b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikovimport android.database.MatrixCursor;
267b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikovimport android.test.AndroidTestCase;
277b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikovimport android.text.TextUtils;
287b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikovimport android.view.View;
297b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikovimport android.view.ViewGroup;
307b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
317b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov/**
327b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov * Tests for {@link GroupingListAdapter}.
337b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov *
347b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov * Running all tests:
357b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov *
367b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov *   adb shell am instrument -e class com.android.common.widget.GroupingListAdapterTests \
377b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov *     -w com.android.common.tests/android.test.InstrumentationTestRunner
387b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov */
397b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikovpublic class GroupingListAdapterTests extends AndroidTestCase {
407b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
417b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    static private final String[] PROJECTION = new String[] {
427b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        "_id",
437b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        "group",
447b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    };
457b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
467b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    private static final int GROUPING_COLUMN_INDEX = 1;
477b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
487b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    private MatrixCursor mCursor;
497b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    private long mNextId;
507b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
517b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    private GroupingListAdapter mAdapter = new GroupingListAdapter(null) {
527b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
537b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        @Override
547b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        protected void addGroups(Cursor cursor) {
557b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            int count = cursor.getCount();
567b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            int groupItemCount = 1;
577b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            cursor.moveToFirst();
587b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            String currentValue = cursor.getString(GROUPING_COLUMN_INDEX);
597b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            for (int i = 1; i < count; i++) {
607b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov                cursor.moveToNext();
617b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov                String value = cursor.getString(GROUPING_COLUMN_INDEX);
627b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov                if (TextUtils.equals(value, currentValue)) {
637b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov                    groupItemCount++;
647b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov                } else {
657b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov                    if (groupItemCount > 1) {
667b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov                        addGroup(i - groupItemCount, groupItemCount, false);
677b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov                    }
687b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
697b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov                    groupItemCount = 1;
707b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov                    currentValue = value;
717b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov                }
727b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            }
737b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            if (groupItemCount > 1) {
747b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov                addGroup(count - groupItemCount, groupItemCount, false);
757b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            }
767b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        }
777b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
787b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        @Override
797b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        protected void bindChildView(View view, Context context, Cursor cursor) {
807b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        }
817b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
827b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        @Override
837b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        protected void bindGroupView(View view, Context context, Cursor cursor, int groupSize,
847b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov                boolean expanded) {
857b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        }
867b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
877b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        @Override
887b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        protected void bindStandAloneView(View view, Context context, Cursor cursor) {
897b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        }
907b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
917b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        @Override
927b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        protected View newChildView(Context context, ViewGroup parent) {
937b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            return null;
947b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        }
957b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
967b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        @Override
977b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        protected View newGroupView(Context context, ViewGroup parent) {
987b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            return null;
997b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        }
1007b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1017b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        @Override
1027b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        protected View newStandAloneView(Context context, ViewGroup parent) {
1037b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            return null;
1047b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        }
1057b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    };
1067b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1077b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    private void buildCursor(String... numbers) {
1087b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mCursor = new MatrixCursor(PROJECTION);
1097b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mNextId = 1;
1107b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        for (String number : numbers) {
1117b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            mCursor.addRow(new Object[]{mNextId, number});
1127b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            mNextId++;
1137b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        }
1147b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    }
1157b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1167b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    public void testGroupingWithoutGroups() {
1177b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        buildCursor("1", "2", "3");
1187b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.changeCursor(mCursor);
1197b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1207b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertEquals(3, mAdapter.getCount());
1217b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
1227b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(1, ITEM_TYPE_STANDALONE, false, 1);
1237b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(2, ITEM_TYPE_STANDALONE, false, 2);
1247b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    }
1257b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1267b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    public void testGroupingWithCollapsedGroupAtTheBeginning() {
1277b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        buildCursor("1", "1", "2");
1287b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.changeCursor(mCursor);
1297b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1307b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertEquals(2, mAdapter.getCount());
1317b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(0, ITEM_TYPE_GROUP_HEADER, false, 0);
1327b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(1, ITEM_TYPE_STANDALONE, false, 2);
1337b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    }
1347b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1357b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    public void testGroupingWithExpandedGroupAtTheBeginning() {
1367b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        buildCursor("1", "1", "2");
1377b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.changeCursor(mCursor);
1387b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.toggleGroup(0);
1397b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1407b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertEquals(4, mAdapter.getCount());
1417b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(0, ITEM_TYPE_GROUP_HEADER, true, 0);
1427b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(1, ITEM_TYPE_IN_GROUP, false, 0);
1437b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(2, ITEM_TYPE_IN_GROUP, false, 1);
1447b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(3, ITEM_TYPE_STANDALONE, false, 2);
1457b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    }
1467b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1477b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    public void testGroupingWithExpandCollapseCycleAtTheBeginning() {
1487b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        buildCursor("1", "1", "2");
1497b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.changeCursor(mCursor);
1507b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.toggleGroup(0);
1517b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.toggleGroup(0);
1527b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1537b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertEquals(2, mAdapter.getCount());
1547b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(0, ITEM_TYPE_GROUP_HEADER, false, 0);
1557b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(1, ITEM_TYPE_STANDALONE, false, 2);
1567b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    }
1577b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1587b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    public void testGroupingWithCollapsedGroupInTheMiddle() {
1597b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        buildCursor("1", "2", "2", "2", "3");
1607b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.changeCursor(mCursor);
1617b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1627b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertEquals(3, mAdapter.getCount());
1637b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
1647b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, false, 1);
1657b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(2, ITEM_TYPE_STANDALONE, false, 4);
1667b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    }
1677b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1687b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    public void testGroupingWithExpandedGroupInTheMiddle() {
1697b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        buildCursor("1", "2", "2", "2", "3");
1707b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.changeCursor(mCursor);
1717b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.toggleGroup(1);
1727b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1737b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertEquals(6, mAdapter.getCount());
1747b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
1757b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, true, 1);
1767b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(2, ITEM_TYPE_IN_GROUP, false, 1);
1777b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(3, ITEM_TYPE_IN_GROUP, false, 2);
1787b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(4, ITEM_TYPE_IN_GROUP, false, 3);
1797b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(5, ITEM_TYPE_STANDALONE, false, 4);
1807b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    }
1817b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1827b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    public void testGroupingWithCollapsedGroupAtTheEnd() {
1837b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        buildCursor("1", "2", "3", "3", "3");
1847b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.changeCursor(mCursor);
1857b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1867b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertEquals(3, mAdapter.getCount());
1877b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
1887b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(1, ITEM_TYPE_STANDALONE, false, 1);
1897b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(2, ITEM_TYPE_GROUP_HEADER, false, 2);
1907b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    }
1917b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1927b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    public void testGroupingWithExpandedGroupAtTheEnd() {
1937b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        buildCursor("1", "2", "3", "3", "3");
1947b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.changeCursor(mCursor);
1957b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.toggleGroup(2);
1967b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
1977b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertEquals(6, mAdapter.getCount());
1987b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
1997b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(1, ITEM_TYPE_STANDALONE, false, 1);
2007b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(2, ITEM_TYPE_GROUP_HEADER, true, 2);
2017b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(3, ITEM_TYPE_IN_GROUP, false, 2);
2027b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(4, ITEM_TYPE_IN_GROUP, false, 3);
2037b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(5, ITEM_TYPE_IN_GROUP, false, 4);
2047b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    }
2057b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
2067b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    public void testGroupingWithMultipleCollapsedGroups() {
2077b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        buildCursor("1", "2", "2", "3", "4", "4", "5", "5", "6");
2087b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.changeCursor(mCursor);
2097b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
2107b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertEquals(6, mAdapter.getCount());
2117b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
2127b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, false, 1);
2137b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(2, ITEM_TYPE_STANDALONE, false, 3);
2147b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(3, ITEM_TYPE_GROUP_HEADER, false, 4);
2157b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(4, ITEM_TYPE_GROUP_HEADER, false, 6);
2167b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(5, ITEM_TYPE_STANDALONE, false, 8);
2177b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    }
2187b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
2197b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    public void testGroupingWithMultipleExpandedGroups() {
2207b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        buildCursor("1", "2", "2", "3", "4", "4", "5", "5", "6");
2217b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.changeCursor(mCursor);
2227b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.toggleGroup(1);
2237b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
2247b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        // Note that expanding the group of 2's shifted the group of 5's down from the
2257b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        // 4th to the 6th position
2267b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.toggleGroup(6);
2277b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
2287b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertEquals(10, mAdapter.getCount());
2297b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
2307b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, true, 1);
2317b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(2, ITEM_TYPE_IN_GROUP, false, 1);
2327b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(3, ITEM_TYPE_IN_GROUP, false, 2);
2337b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(4, ITEM_TYPE_STANDALONE, false, 3);
2347b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(5, ITEM_TYPE_GROUP_HEADER, false, 4);
2357b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(6, ITEM_TYPE_GROUP_HEADER, true, 6);
2367b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(7, ITEM_TYPE_IN_GROUP, false, 6);
2377b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(8, ITEM_TYPE_IN_GROUP, false, 7);
2387b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(9, ITEM_TYPE_STANDALONE, false, 8);
2397b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    }
2407b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
2417b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    public void testPositionCache() {
2427b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        buildCursor("1", "2", "2", "3", "4", "4", "5", "5", "6");
2437b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.changeCursor(mCursor);
2447b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
2457b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        // First pass - building up cache
2467b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertEquals(6, mAdapter.getCount());
2477b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
2487b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, false, 1);
2497b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(2, ITEM_TYPE_STANDALONE, false, 3);
2507b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(3, ITEM_TYPE_GROUP_HEADER, false, 4);
2517b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(4, ITEM_TYPE_GROUP_HEADER, false, 6);
2527b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(5, ITEM_TYPE_STANDALONE, false, 8);
2537b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
2547b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        // Second pass - using cache
2557b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertEquals(6, mAdapter.getCount());
2567b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
2577b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, false, 1);
2587b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(2, ITEM_TYPE_STANDALONE, false, 3);
2597b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(3, ITEM_TYPE_GROUP_HEADER, false, 4);
2607b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(4, ITEM_TYPE_GROUP_HEADER, false, 6);
2617b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(5, ITEM_TYPE_STANDALONE, false, 8);
2627b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
2637b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        // Invalidate cache by expanding a group
2647b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.toggleGroup(1);
2657b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
2667b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        // First pass - building up cache
2677b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
2687b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, true, 1);
2697b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(2, ITEM_TYPE_IN_GROUP, false, 1);
2707b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(3, ITEM_TYPE_IN_GROUP, false, 2);
2717b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(4, ITEM_TYPE_STANDALONE, false, 3);
2727b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(5, ITEM_TYPE_GROUP_HEADER, false, 4);
2737b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(6, ITEM_TYPE_GROUP_HEADER, false, 6);
2747b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(7, ITEM_TYPE_STANDALONE, false, 8);
2757b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
2767b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        // Second pass - using cache
2777b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(0, ITEM_TYPE_STANDALONE, false, 0);
2787b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(1, ITEM_TYPE_GROUP_HEADER, true, 1);
2797b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(2, ITEM_TYPE_IN_GROUP, false, 1);
2807b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(3, ITEM_TYPE_IN_GROUP, false, 2);
2817b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(4, ITEM_TYPE_STANDALONE, false, 3);
2827b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(5, ITEM_TYPE_GROUP_HEADER, false, 4);
2837b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(6, ITEM_TYPE_GROUP_HEADER, false, 6);
2847b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertPositionMetadata(7, ITEM_TYPE_STANDALONE, false, 8);
2857b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    }
2867b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
2877b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    public void testGroupDescriptorArrayGrowth() {
2887b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        String[] numbers = new String[500];
2897b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        for (int i = 0; i < numbers.length; i++) {
2907b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
2917b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            // Make groups of 2
2927b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            numbers[i] = String.valueOf((i / 2) * 2);
2937b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        }
2947b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
2957b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        buildCursor(numbers);
2967b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.changeCursor(mCursor);
2977b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
2987b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertEquals(250, mAdapter.getCount());
2997b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    }
3007b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov
3017b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    private void assertPositionMetadata(int position, int itemType, boolean isExpanded,
3027b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            int cursorPosition) {
3037b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        GroupingListAdapter.PositionMetadata metadata = new GroupingListAdapter.PositionMetadata();
3047b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        mAdapter.obtainPositionMetadata(metadata, position);
3057b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertEquals(itemType, metadata.itemType);
3067b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        if (metadata.itemType == ITEM_TYPE_GROUP_HEADER) {
3077b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov            assertEquals(isExpanded, metadata.isExpanded);
3087b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        }
3097b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov        assertEquals(cursorPosition, metadata.cursorPosition);
3107b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov    }
3117b8b23f9c04fa33b79a8949752a90a134a11df8aDmitri Plotnikov}
312