• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
16 
17 package com.android.contacts.common.test.mocks;
18 
19 import android.content.ContentProvider;
20 import android.content.ContentValues;
21 import android.database.Cursor;
22 import android.database.MatrixCursor;
23 import android.net.Uri;
24 import android.text.TextUtils;
25 
26 import com.google.common.collect.Lists;
27 import com.google.common.collect.Maps;
28 
29 import junit.framework.Assert;
30 
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.HashMap;
34 import java.util.Iterator;
35 
36 /**
37  * A programmable mock content provider.
38  */
39 public class MockContentProvider extends ContentProvider {
40     private static final String TAG = "MockContentProvider";
41 
42     public static class Query {
43 
44         private final Uri mUri;
45         private String[] mProjection;
46         private String[] mDefaultProjection;
47         private String mSelection;
48         private String[] mSelectionArgs;
49         private String mSortOrder;
50         private ArrayList<Object> mRows = new ArrayList<Object>();
51         private boolean mAnyProjection;
52         private boolean mAnySelection;
53         private boolean mAnySortOrder;
54         private boolean mAnyNumberOfTimes;
55 
56         private boolean mExecuted;
57 
Query(Uri uri)58         public Query(Uri uri) {
59             mUri = uri;
60         }
61 
62         @Override
toString()63         public String toString() {
64             return queryToString(mUri, mProjection, mSelection, mSelectionArgs, mSortOrder);
65         }
66 
withProjection(String... projection)67         public Query withProjection(String... projection) {
68             mProjection = projection;
69             return this;
70         }
71 
withDefaultProjection(String... projection)72         public Query withDefaultProjection(String... projection) {
73             mDefaultProjection = projection;
74             return this;
75         }
76 
withAnyProjection()77         public Query withAnyProjection() {
78             mAnyProjection = true;
79             return this;
80         }
81 
withSelection(String selection, String... selectionArgs)82         public Query withSelection(String selection, String... selectionArgs) {
83             mSelection = selection;
84             mSelectionArgs = selectionArgs;
85             return this;
86         }
87 
withAnySelection()88         public Query withAnySelection() {
89             mAnySelection = true;
90             return this;
91         }
92 
withSortOrder(String sortOrder)93         public Query withSortOrder(String sortOrder) {
94             mSortOrder = sortOrder;
95             return this;
96         }
97 
withAnySortOrder()98         public Query withAnySortOrder() {
99             mAnySortOrder = true;
100             return this;
101         }
102 
returnRow(ContentValues values)103         public Query returnRow(ContentValues values) {
104             mRows.add(values);
105             return this;
106         }
107 
returnRow(Object... row)108         public Query returnRow(Object... row) {
109             mRows.add(row);
110             return this;
111         }
112 
returnEmptyCursor()113         public Query returnEmptyCursor() {
114             mRows.clear();
115             return this;
116         }
117 
anyNumberOfTimes()118         public Query anyNumberOfTimes() {
119             mAnyNumberOfTimes = true;
120             return this;
121         }
122 
equals(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)123         public boolean equals(Uri uri, String[] projection, String selection,
124                 String[] selectionArgs, String sortOrder) {
125             if (!uri.equals(mUri)) {
126                 return false;
127             }
128 
129             if (!mAnyProjection && !equals(projection, mProjection)) {
130                 return false;
131             }
132 
133             if (!mAnySelection && !equals(selection, mSelection)) {
134                 return false;
135             }
136 
137             if (!mAnySelection && !equals(selectionArgs, mSelectionArgs)) {
138                 return false;
139             }
140 
141             if (!mAnySortOrder && !equals(sortOrder, mSortOrder)) {
142                 return false;
143             }
144 
145             return true;
146         }
147 
equals(String string1, String string2)148         private boolean equals(String string1, String string2) {
149             if (TextUtils.isEmpty(string1)) {
150                 string1 = null;
151             }
152             if (TextUtils.isEmpty(string2)) {
153                 string2 = null;
154             }
155             return TextUtils.equals(string1, string2);
156         }
157 
equals(String[] array1, String[] array2)158         private static boolean equals(String[] array1, String[] array2) {
159             boolean empty1 = array1 == null || array1.length == 0;
160             boolean empty2 = array2 == null || array2.length == 0;
161             if (empty1 && empty2) {
162                 return true;
163             }
164             if (empty1 != empty2 && (empty1 || empty2)) {
165                 return false;
166             }
167 
168             if (array1.length != array2.length) return false;
169 
170             for (int i = 0; i < array1.length; i++) {
171                 if (!array1[i].equals(array2[i])) {
172                     return false;
173                 }
174             }
175             return true;
176         }
177 
getResult(String[] projection)178         public Cursor getResult(String[] projection) {
179             String[] columnNames;
180             if (mAnyProjection) {
181                 columnNames = projection;
182             } else {
183                 columnNames = mProjection != null ? mProjection : mDefaultProjection;
184             }
185 
186             MatrixCursor cursor = new MatrixCursor(columnNames);
187             for (Object row : mRows) {
188                 if (row instanceof Object[]) {
189                     cursor.addRow((Object[]) row);
190                 } else {
191                     ContentValues values = (ContentValues) row;
192                     Object[] columns = new Object[projection.length];
193                     for (int i = 0; i < projection.length; i++) {
194                         columns[i] = values.get(projection[i]);
195                     }
196                     cursor.addRow(columns);
197                 }
198             }
199             return cursor;
200         }
201     }
202 
203     public static class TypeQuery {
204         private final Uri mUri;
205         private final String mType;
206 
TypeQuery(Uri uri, String type)207         public TypeQuery(Uri uri, String type) {
208             mUri = uri;
209             mType = type;
210         }
211 
getUri()212         public Uri getUri() {
213             return mUri;
214         }
215 
getType()216         public String getType() {
217             return mType;
218         }
219 
220         @Override
toString()221         public String toString() {
222             return mUri + " --> " + mType;
223         }
224 
equals(Uri uri)225         public boolean equals(Uri uri) {
226             return getUri().equals(uri);
227         }
228     }
229 
230     private ArrayList<Query> mExpectedQueries = new ArrayList<Query>();
231     private HashMap<Uri, String> mExpectedTypeQueries = Maps.newHashMap();
232 
233     @Override
onCreate()234     public boolean onCreate() {
235         return true;
236     }
237 
expectQuery(Uri contentUri)238     public Query expectQuery(Uri contentUri) {
239         Query query = new Query(contentUri);
240         mExpectedQueries.add(query);
241         return query;
242     }
243 
expectTypeQuery(Uri uri, String type)244     public void expectTypeQuery(Uri uri, String type) {
245         mExpectedTypeQueries.put(uri, type);
246     }
247 
248     @Override
query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)249     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
250             String sortOrder) {
251 
252         for (Iterator<Query> iterator = mExpectedQueries.iterator(); iterator.hasNext();) {
253             Query query = iterator.next();
254             if (query.equals(uri, projection, selection, selectionArgs, sortOrder)) {
255                 query.mExecuted = true;
256                 if (!query.mAnyNumberOfTimes) {
257                     iterator.remove();
258                 }
259                 return query.getResult(projection);
260             }
261         }
262 
263         if (mExpectedQueries.isEmpty()) {
264             Assert.fail("Unexpected query: "
265                     + queryToString(uri, projection, selection, selectionArgs, sortOrder));
266         } else {
267             StringBuilder sb = new StringBuilder();
268             sb.append(mExpectedQueries.get(0));
269             for (int i = 1; i < mExpectedQueries.size(); i++) {
270                 sb.append("\n              ").append(mExpectedQueries.get(i));
271             }
272             Assert.fail("Incorrect query.\n    Expected: " + sb + "\n      Actual: " +
273                     queryToString(uri, projection, selection, selectionArgs, sortOrder));
274         }
275         return null;
276     }
277 
278     @Override
delete(Uri uri, String selection, String[] selectionArgs)279     public int delete(Uri uri, String selection, String[] selectionArgs) {
280         throw new UnsupportedOperationException();
281     }
282 
283     @Override
getType(Uri uri)284     public String getType(Uri uri) {
285         if (mExpectedTypeQueries.isEmpty()) {
286             Assert.fail("Unexpected getType query: " + uri);
287         }
288 
289         String mimeType = mExpectedTypeQueries.get(uri);
290         if (mimeType != null) {
291             return mimeType;
292         }
293 
294         Assert.fail("Unknown mime type for: " + uri);
295         return null;
296     }
297 
298     @Override
insert(Uri uri, ContentValues values)299     public Uri insert(Uri uri, ContentValues values) {
300         throw new UnsupportedOperationException();
301     }
302 
303     @Override
update(Uri uri, ContentValues values, String selection, String[] selectionArgs)304     public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
305         throw new UnsupportedOperationException();
306     }
307 
queryToString(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)308     private static String queryToString(Uri uri, String[] projection, String selection,
309             String[] selectionArgs, String sortOrder) {
310         StringBuilder sb = new StringBuilder();
311         sb.append(uri).append(" ");
312         if (projection != null) {
313             sb.append(Arrays.toString(projection));
314         } else {
315             sb.append("[]");
316         }
317         if (selection != null) {
318             sb.append(" selection: '").append(selection).append("'");
319             if (selectionArgs != null) {
320                 sb.append(Arrays.toString(selectionArgs));
321             } else {
322                 sb.append("[]");
323             }
324         }
325         if (sortOrder != null) {
326             sb.append(" sort: '").append(sortOrder).append("'");
327         }
328         return sb.toString();
329     }
330 
verify()331     public void verify() {
332         ArrayList<Query> mMissedQueries = Lists.newArrayList();
333         for (Query query : mExpectedQueries) {
334             if (!query.mExecuted) {
335                 mMissedQueries.add(query);
336             }
337         }
338         Assert.assertTrue("Not all expected queries have been called: " +
339                 mMissedQueries, mMissedQueries.isEmpty());
340     }
341 }
342