12fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng/*
22fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng * Copyright (C) 2010 The Android Open Source Project
32fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng *
42fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng * Licensed under the Apache License, Version 2.0 (the "License");
52fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng * you may not use this file except in compliance with the License.
62fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng * You may obtain a copy of the License at
72fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng *
82fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng *      http://www.apache.org/licenses/LICENSE-2.0
92fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng *
102fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng * Unless required by applicable law or agreed to in writing, software
112fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng * distributed under the License is distributed on an "AS IS" BASIS,
122fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng * See the License for the specific language governing permissions and
142fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng * limitations under the License.
152fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng */
162fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
172fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Chengpackage com.android.contacts.common.test.mocks;
182fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
192fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Chengimport android.content.ContentProvider;
202fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Chengimport android.content.ContentValues;
212fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Chengimport android.database.Cursor;
222fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Chengimport android.database.MatrixCursor;
232fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Chengimport android.net.Uri;
242fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Chengimport android.text.TextUtils;
252fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
262fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Chengimport com.google.common.collect.Lists;
272fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Chengimport com.google.common.collect.Maps;
282fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
292fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Chengimport junit.framework.Assert;
302fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
312fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Chengimport java.util.ArrayList;
322fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Chengimport java.util.Arrays;
332fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Chengimport java.util.HashMap;
342fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Chengimport java.util.Iterator;
352fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
362fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng/**
372fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng * A programmable mock content provider.
382fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng */
392fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Chengpublic class MockContentProvider extends ContentProvider {
402fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    private static final String TAG = "MockContentProvider";
412fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
422fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    public static class Query {
432fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
442fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private final Uri mUri;
452fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private String[] mProjection;
462fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private String[] mDefaultProjection;
472fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private String mSelection;
482fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private String[] mSelectionArgs;
492fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private String mSortOrder;
502fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private ArrayList<Object> mRows = new ArrayList<Object>();
512fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private boolean mAnyProjection;
522fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private boolean mAnySelection;
532fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private boolean mAnySortOrder;
542fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private boolean mAnyNumberOfTimes;
552fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
562fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private boolean mExecuted;
572fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
582fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public Query(Uri uri) {
592fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            mUri = uri;
602fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
612fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
622fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        @Override
632fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public String toString() {
642fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return queryToString(mUri, mProjection, mSelection, mSelectionArgs, mSortOrder);
652fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
662fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
672fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public Query withProjection(String... projection) {
682fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            mProjection = projection;
692fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return this;
702fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
712fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
722fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public Query withDefaultProjection(String... projection) {
732fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            mDefaultProjection = projection;
742fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return this;
752fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
762fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
772fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public Query withAnyProjection() {
782fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            mAnyProjection = true;
792fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return this;
802fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
812fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
822fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public Query withSelection(String selection, String... selectionArgs) {
832fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            mSelection = selection;
842fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            mSelectionArgs = selectionArgs;
852fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return this;
862fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
872fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
882fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public Query withAnySelection() {
892fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            mAnySelection = true;
902fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return this;
912fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
922fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
932fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public Query withSortOrder(String sortOrder) {
942fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            mSortOrder = sortOrder;
952fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return this;
962fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
972fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
982fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public Query withAnySortOrder() {
992fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            mAnySortOrder = true;
1002fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return this;
1012fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
1022fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1032fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public Query returnRow(ContentValues values) {
1042fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            mRows.add(values);
1052fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return this;
1062fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
1072fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1082fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public Query returnRow(Object... row) {
1092fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            mRows.add(row);
1102fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return this;
1112fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
1122fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1132fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public Query returnEmptyCursor() {
1142fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            mRows.clear();
1152fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return this;
1162fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
1172fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1182fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public Query anyNumberOfTimes() {
1192fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            mAnyNumberOfTimes = true;
1202fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return this;
1212fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
1222fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1232fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public boolean equals(Uri uri, String[] projection, String selection,
1242fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                String[] selectionArgs, String sortOrder) {
1252fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            if (!uri.equals(mUri)) {
1262fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                return false;
1272fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
1282fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1292fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            if (!mAnyProjection && !equals(projection, mProjection)) {
1302fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                return false;
1312fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
1322fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1332fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            if (!mAnySelection && !equals(selection, mSelection)) {
1342fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                return false;
1352fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
1362fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1372fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            if (!mAnySelection && !equals(selectionArgs, mSelectionArgs)) {
1382fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                return false;
1392fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
1402fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1412fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            if (!mAnySortOrder && !equals(sortOrder, mSortOrder)) {
1422fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                return false;
1432fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
1442fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1452fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return true;
1462fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
1472fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1482fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private boolean equals(String string1, String string2) {
1492fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            if (TextUtils.isEmpty(string1)) {
1502fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                string1 = null;
1512fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
1522fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            if (TextUtils.isEmpty(string2)) {
1532fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                string2 = null;
1542fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
1552fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return TextUtils.equals(string1, string2);
1562fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
1572fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1582fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private static boolean equals(String[] array1, String[] array2) {
1592fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            boolean empty1 = array1 == null || array1.length == 0;
1602fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            boolean empty2 = array2 == null || array2.length == 0;
1612fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            if (empty1 && empty2) {
1622fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                return true;
1632fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
1642fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            if (empty1 != empty2 && (empty1 || empty2)) {
1652fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                return false;
1662fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
1672fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1682fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            if (array1.length != array2.length) return false;
1692fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1702fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            for (int i = 0; i < array1.length; i++) {
1712fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                if (!array1[i].equals(array2[i])) {
1722fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                    return false;
1732fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                }
1742fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
1752fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return true;
1762fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
1772fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1782fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public Cursor getResult(String[] projection) {
1792fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            String[] columnNames;
1802fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            if (mAnyProjection) {
1812fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                columnNames = projection;
1822fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            } else {
1832fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                columnNames = mProjection != null ? mProjection : mDefaultProjection;
1842fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
1852fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
1862fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            MatrixCursor cursor = new MatrixCursor(columnNames);
1872fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            for (Object row : mRows) {
1882fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                if (row instanceof Object[]) {
1892fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                    cursor.addRow((Object[]) row);
1902fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                } else {
1912fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                    ContentValues values = (ContentValues) row;
1922fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                    Object[] columns = new Object[projection.length];
1932fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                    for (int i = 0; i < projection.length; i++) {
1942fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                        columns[i] = values.get(projection[i]);
1952fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                    }
1962fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                    cursor.addRow(columns);
1972fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                }
1982fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
1992fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return cursor;
2002fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
2012fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    }
2022fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2032fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    public static class TypeQuery {
2042fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private final Uri mUri;
2052fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        private final String mType;
2062fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2072fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public TypeQuery(Uri uri, String type) {
2082fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            mUri = uri;
2092fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            mType = type;
2102fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
2112fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2122fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public Uri getUri() {
2132fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return mUri;
2142fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
2152fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2162fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public String getType() {
2172fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return mType;
2182fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
2192fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2202fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        @Override
2212fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public String toString() {
2222fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return mUri + " --> " + mType;
2232fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
2242fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2252fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        public boolean equals(Uri uri) {
2262fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return getUri().equals(uri);
2272fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
2282fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    }
2292fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2302fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    private ArrayList<Query> mExpectedQueries = new ArrayList<Query>();
2312fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    private HashMap<Uri, String> mExpectedTypeQueries = Maps.newHashMap();
2322fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2332fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    @Override
2342fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    public boolean onCreate() {
2352fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        return true;
2362fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    }
2372fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2382fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    public Query expectQuery(Uri contentUri) {
2392fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        Query query = new Query(contentUri);
2402fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        mExpectedQueries.add(query);
2412fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        return query;
2422fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    }
2432fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2442fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    public void expectTypeQuery(Uri uri, String type) {
2452fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        mExpectedTypeQueries.put(uri, type);
2462fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    }
2472fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2482fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    @Override
2492fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
2502fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            String sortOrder) {
2512fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2522fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        for (Iterator<Query> iterator = mExpectedQueries.iterator(); iterator.hasNext();) {
2532fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            Query query = iterator.next();
2542fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            if (query.equals(uri, projection, selection, selectionArgs, sortOrder)) {
2552fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                query.mExecuted = true;
2562fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                if (!query.mAnyNumberOfTimes) {
2572fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                    iterator.remove();
2582fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                }
2592fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                return query.getResult(projection);
2602fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
2612fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
2622fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2632fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        if (mExpectedQueries.isEmpty()) {
2642fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            Assert.fail("Unexpected query: "
2652fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                    + queryToString(uri, projection, selection, selectionArgs, sortOrder));
2662fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        } else {
2672fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            StringBuilder sb = new StringBuilder();
2682fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            sb.append(mExpectedQueries.get(0));
2692fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            for (int i = 1; i < mExpectedQueries.size(); i++) {
2702fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                sb.append("\n              ").append(mExpectedQueries.get(i));
2712fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
2722fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            Assert.fail("Incorrect query.\n    Expected: " + sb + "\n      Actual: " +
2732fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                    queryToString(uri, projection, selection, selectionArgs, sortOrder));
2742fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
2752fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        return null;
2762fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    }
2772fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2782fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    @Override
2792fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    public int delete(Uri uri, String selection, String[] selectionArgs) {
2802fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        throw new UnsupportedOperationException();
2812fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    }
2822fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2832fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    @Override
2842fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    public String getType(Uri uri) {
2852fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        if (mExpectedTypeQueries.isEmpty()) {
2862fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            Assert.fail("Unexpected getType query: " + uri);
2872fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
2882fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2892fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        String mimeType = mExpectedTypeQueries.get(uri);
2902fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        if (mimeType != null) {
2912fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            return mimeType;
2922fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
2932fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2942fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        Assert.fail("Unknown mime type for: " + uri);
2952fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        return null;
2962fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    }
2972fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
2982fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    @Override
2992fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    public Uri insert(Uri uri, ContentValues values) {
3002fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        throw new UnsupportedOperationException();
3012fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    }
3022fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
3032fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    @Override
3042fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
3052fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        throw new UnsupportedOperationException();
3062fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    }
3072fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
3082fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    private static String queryToString(Uri uri, String[] projection, String selection,
3092fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            String[] selectionArgs, String sortOrder) {
3102fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        StringBuilder sb = new StringBuilder();
3112fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        sb.append(uri).append(" ");
3122fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        if (projection != null) {
3132fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            sb.append(Arrays.toString(projection));
3142fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        } else {
3152fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            sb.append("[]");
3162fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
3172fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        if (selection != null) {
3182fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            sb.append(" selection: '").append(selection).append("'");
3192fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            if (selectionArgs != null) {
3202fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                sb.append(Arrays.toString(selectionArgs));
3212fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            } else {
3222fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                sb.append("[]");
3232fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
3242fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
3252fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        if (sortOrder != null) {
3262fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            sb.append(" sort: '").append(sortOrder).append("'");
3272fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
3282fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        return sb.toString();
3292fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    }
3302fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng
3312fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    public void verify() {
3322fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        ArrayList<Query> mMissedQueries = Lists.newArrayList();
3332fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        for (Query query : mExpectedQueries) {
3342fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            if (!query.mExecuted) {
3352fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                mMissedQueries.add(query);
3362fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng            }
3372fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        }
3382fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng        Assert.assertTrue("Not all expected queries have been called: " +
3392fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng                mMissedQueries, mMissedQueries.isEmpty());
3402fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng    }
3412fe1a8f66f98c6b1b17681b64dbbafde1ab5e07dChiao Cheng}
342