summaryrefslogtreecommitdiffstats
path: root/tests/src
diff options
context:
space:
mode:
authorMichael Chan <mchan@android.com>2010-04-27 10:56:53 -0700
committerMichael Chan <mchan@android.com>2010-06-21 11:15:04 -0700
commitbed0275111ecc6c4a3a638f90a9bac13bee594f4 (patch)
treec140d4eaa0eece9f541c09e2e9668cfe429b546b /tests/src
parenteca82e9468c002590045338f98588ad3ce1a0bb3 (diff)
downloadandroid_packages_apps_Calendar-bed0275111ecc6c4a3a638f90a9bac13bee594f4.tar.gz
android_packages_apps_Calendar-bed0275111ecc6c4a3a638f90a9bac13bee594f4.tar.bz2
android_packages_apps_Calendar-bed0275111ecc6c4a3a638f90a9bac13bee594f4.zip
AsyncQueryService
Helper class that performs ContentProvider operations in a Service Features: - Executes the operation in a background Sservice which minimizes the chance of the operation getting lost because the caller (Activity) is killed. - Designed for easy migration from AsyncQueryHandler. - In additional to query/insert/update/delete, it also supports batch mode i.e. ContentProviderOperation - Undo support in the form for delayed operation with cancel Todo: - Add wake lock Change-Id: Id3b24a34e5af11da448bace585911bcd7d4553c5
Diffstat (limited to 'tests/src')
-rw-r--r--tests/src/com/android/calendar/AsyncQueryServiceTest.java628
1 files changed, 628 insertions, 0 deletions
diff --git a/tests/src/com/android/calendar/AsyncQueryServiceTest.java b/tests/src/com/android/calendar/AsyncQueryServiceTest.java
new file mode 100644
index 00000000..1757efd5
--- /dev/null
+++ b/tests/src/com/android/calendar/AsyncQueryServiceTest.java
@@ -0,0 +1,628 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.calendar;
+
+import com.android.calendar.AsyncQueryService.Operation;
+import com.android.calendar.AsyncQueryServiceHelper.OperationInfo;
+
+import android.content.ComponentName;
+import android.content.ContentProvider;
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
+import android.test.ServiceTestCase;
+import android.test.mock.MockContentResolver;
+import android.test.mock.MockContext;
+import android.test.mock.MockCursor;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Unit tests for {@link android.text.format.DateUtils#formatDateRange}.
+ */
+public class AsyncQueryServiceTest extends ServiceTestCase<AsyncQueryServiceHelper> {
+ private static final String TAG = "AsyncQueryServiceTest";
+
+ private static final String AUTHORITY_URI = "content://AsyncQueryAuthority/";
+
+ private static final String AUTHORITY = "AsyncQueryAuthority";
+
+ private static final int MIN_DELAY = 50;
+
+ private static final int BASE_TEST_WAIT_TIME = MIN_DELAY * 5;
+
+ private static int mId = 0;
+
+ private static final String[] TEST_PROJECTION = new String[] {
+ "col1", "col2", "col3"
+ };
+
+ private static final String TEST_SELECTION = "selection";
+
+ private static final String[] TEST_SELECTION_ARGS = new String[] {
+ "arg1", "arg2", "arg3"
+ };
+
+ public AsyncQueryServiceTest() {
+ super(AsyncQueryServiceHelper.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @SmallTest
+ public void testQuery() throws Exception {
+ int index = 0;
+ final OperationInfo[] work = new OperationInfo[1];
+ work[index] = new OperationInfo();
+ work[index].op = Operation.EVENT_ARG_QUERY;
+
+ work[index].token = ++mId;
+ work[index].cookie = ++mId;
+ work[index].uri = Uri.parse(AUTHORITY_URI + "blah");
+ work[index].projection = TEST_PROJECTION;
+ work[index].selection = TEST_SELECTION;
+ work[index].selectionArgs = TEST_SELECTION_ARGS;
+ work[index].orderBy = "order";
+
+ work[index].delayMillis = 0;
+ work[index].result = new TestCursor();
+
+ TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(work), work);
+ aqs.startQuery(work[index].token, work[index].cookie, work[index].uri,
+ work[index].projection, work[index].selection, work[index].selectionArgs,
+ work[index].orderBy);
+
+ Log.d(TAG, "testQuery Waiting >>>>>>>>>>>");
+ assertEquals("Not all operations were executed.", work.length, aqs
+ .waitForCompletion(BASE_TEST_WAIT_TIME));
+ Log.d(TAG, "testQuery Done <<<<<<<<<<<<<<");
+ }
+
+ @SmallTest
+ public void testInsert() throws Exception {
+ int index = 0;
+ final OperationInfo[] work = new OperationInfo[1];
+ work[index] = new OperationInfo();
+ work[index].op = Operation.EVENT_ARG_INSERT;
+
+ work[index].token = ++mId;
+ work[index].cookie = ++mId;
+ work[index].uri = Uri.parse(AUTHORITY_URI + "blah");
+ work[index].values = new ContentValues();
+ work[index].values.put("key", ++mId);
+
+ work[index].delayMillis = 0;
+ work[index].result = Uri.parse(AUTHORITY_URI + "Result=" + ++mId);
+
+ TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(work), work);
+ aqs.startInsert(work[index].token, work[index].cookie, work[index].uri, work[index].values,
+ work[index].delayMillis);
+
+ Log.d(TAG, "testInsert Waiting >>>>>>>>>>>");
+ assertEquals("Not all operations were executed.", work.length, aqs
+ .waitForCompletion(BASE_TEST_WAIT_TIME));
+ Log.d(TAG, "testInsert Done <<<<<<<<<<<<<<");
+ }
+
+ @SmallTest
+ public void testUpdate() throws Exception {
+ int index = 0;
+ final OperationInfo[] work = new OperationInfo[1];
+ work[index] = new OperationInfo();
+ work[index].op = Operation.EVENT_ARG_UPDATE;
+
+ work[index].token = ++mId;
+ work[index].cookie = ++mId;
+ work[index].uri = Uri.parse(AUTHORITY_URI + ++mId);
+ work[index].values = new ContentValues();
+ work[index].values.put("key", ++mId);
+ work[index].selection = TEST_SELECTION;
+ work[index].selectionArgs = TEST_SELECTION_ARGS;
+
+ work[index].delayMillis = 0;
+ work[index].result = ++mId;
+
+ TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(work), work);
+ aqs.startUpdate(work[index].token, work[index].cookie, work[index].uri, work[index].values,
+ work[index].selection, work[index].selectionArgs, work[index].delayMillis);
+
+ Log.d(TAG, "testUpdate Waiting >>>>>>>>>>>");
+ assertEquals("Not all operations were executed.", work.length, aqs
+ .waitForCompletion(BASE_TEST_WAIT_TIME));
+ Log.d(TAG, "testUpdate Done <<<<<<<<<<<<<<");
+ }
+
+ @SmallTest
+ public void testDelete() throws Exception {
+ int index = 0;
+ final OperationInfo[] work = new OperationInfo[1];
+ work[index] = new OperationInfo();
+ work[index].op = Operation.EVENT_ARG_DELETE;
+
+ work[index].token = ++mId;
+ work[index].cookie = ++mId;
+ work[index].uri = Uri.parse(AUTHORITY_URI + "blah");
+ work[index].selection = TEST_SELECTION;
+ work[index].selectionArgs = TEST_SELECTION_ARGS;
+
+ work[index].delayMillis = 0;
+ work[index].result = ++mId;
+
+ TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(work), work);
+ aqs.startDelete(work[index].token,
+ work[index].cookie,
+ work[index].uri,
+ work[index].selection,
+ work[index].selectionArgs,
+ work[index].delayMillis);
+
+ Log.d(TAG, "testDelete Waiting >>>>>>>>>>>");
+ assertEquals("Not all operations were executed.", work.length, aqs
+ .waitForCompletion(BASE_TEST_WAIT_TIME));
+ Log.d(TAG, "testDelete Done <<<<<<<<<<<<<<");
+ }
+
+ @SmallTest
+ public void testBatch() throws Exception {
+ int index = 0;
+ final OperationInfo[] work = new OperationInfo[1];
+ work[index] = new OperationInfo();
+ work[index].op = Operation.EVENT_ARG_BATCH;
+
+ work[index].token = ++mId;
+ work[index].cookie = ++mId;
+ work[index].authority = AUTHORITY;
+ work[index].cpo = new ArrayList<ContentProviderOperation>();
+ work[index].cpo.add(ContentProviderOperation.newInsert(Uri.parse(AUTHORITY_URI + ++mId))
+ .build());
+
+ work[index].delayMillis = 0;
+ ContentProviderResult[] resultArray = new ContentProviderResult[1];
+ resultArray[0] = new ContentProviderResult(++mId);
+ work[index].result = resultArray;
+
+ TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(work), work);
+ aqs.startBatch(work[index].token,
+ work[index].cookie,
+ work[index].authority,
+ work[index].cpo,
+ work[index].delayMillis);
+
+ Log.d(TAG, "testBatch Waiting >>>>>>>>>>>");
+ assertEquals("Not all operations were executed.", work.length, aqs
+ .waitForCompletion(BASE_TEST_WAIT_TIME));
+ Log.d(TAG, "testBatch Done <<<<<<<<<<<<<<");
+ }
+
+ @LargeTest
+ public void testDelay() throws Exception {
+ // Tests the ordering of the workqueue
+ int index = 0;
+ OperationInfo[] work = new OperationInfo[5];
+ work[index++] = generateWork(MIN_DELAY * 2);
+ work[index++] = generateWork(0);
+ work[index++] = generateWork(MIN_DELAY * 1);
+ work[index++] = generateWork(0);
+ work[index++] = generateWork(MIN_DELAY * 3);
+
+ OperationInfo[] sorted = generateSortedWork(work, work.length);
+
+ TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(sorted), sorted);
+ startWork(aqs, work);
+
+ Log.d(TAG, "testDelay Waiting >>>>>>>>>>>");
+ assertEquals("Not all operations were executed.", work.length, aqs
+ .waitForCompletion(BASE_TEST_WAIT_TIME));
+ Log.d(TAG, "testDelay Done <<<<<<<<<<<<<<");
+ }
+
+ @LargeTest
+ public void testCancel_simpleCancelLastTest() throws Exception {
+ int index = 0;
+ OperationInfo[] work = new OperationInfo[5];
+ work[index++] = generateWork(MIN_DELAY * 2);
+ work[index++] = generateWork(0);
+ work[index++] = generateWork(MIN_DELAY);
+ work[index++] = generateWork(0);
+ work[index] = generateWork(MIN_DELAY * 3);
+
+ // Not part of the expected as it will be canceled
+ OperationInfo toBeCancelled1 = work[index];
+ OperationInfo[] expected = generateSortedWork(work, work.length - 1);
+
+ TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(expected), expected);
+ startWork(aqs, work);
+ Operation lastOne = aqs.getLastCancelableOperation();
+ // Log.d(TAG, "lastOne = " + lastOne.toString());
+ // Log.d(TAG, "toBeCancelled1 = " + toBeCancelled1.toString());
+ assertTrue("1) delay=3 is not last", toBeCancelled1.equivalent(lastOne));
+ assertEquals("Can't cancel delay 3", 1, aqs.cancelOperation(lastOne.token));
+
+ Log.d(TAG, "testCancel_simpleCancelLastTest Waiting >>>>>>>>>>>");
+ assertEquals("Not all operations were executed.", expected.length, aqs
+ .waitForCompletion(BASE_TEST_WAIT_TIME));
+ Log.d(TAG, "testCancel_simpleCancelLastTest Done <<<<<<<<<<<<<<");
+ }
+
+ @LargeTest
+ public void testCancel_cancelSecondToLast() throws Exception {
+ int index = 0;
+ OperationInfo[] work = new OperationInfo[5];
+ work[index++] = generateWork(MIN_DELAY * 2);
+ work[index++] = generateWork(0);
+ work[index++] = generateWork(MIN_DELAY);
+ work[index++] = generateWork(0);
+ work[index] = generateWork(MIN_DELAY * 3);
+
+ // Not part of the expected as it will be canceled
+ OperationInfo toBeCancelled1 = work[index];
+ OperationInfo[] expected = new OperationInfo[4];
+ expected[0] = work[1]; // delay = 0
+ expected[1] = work[3]; // delay = 0
+ expected[2] = work[2]; // delay = MIN_DELAY
+ expected[3] = work[4]; // delay = MIN_DELAY * 3
+
+ TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(expected), expected);
+ startWork(aqs, work);
+
+ Operation lastOne = aqs.getLastCancelableOperation(); // delay = 3
+ assertTrue("2) delay=3 is not last", toBeCancelled1.equivalent(lastOne));
+ assertEquals("Can't cancel delay 2", 1, aqs.cancelOperation(work[0].token));
+ assertEquals("Delay 2 should be gone", 0, aqs.cancelOperation(work[0].token));
+
+ Log.d(TAG, "testCancel_cancelSecondToLast Waiting >>>>>>>>>>>");
+ assertEquals("Not all operations were executed.", expected.length, aqs
+ .waitForCompletion(BASE_TEST_WAIT_TIME));
+ Log.d(TAG, "testCancel_cancelSecondToLast Done <<<<<<<<<<<<<<");
+ }
+
+ @LargeTest
+ public void testCancel_multipleCancels() throws Exception {
+ int index = 0;
+ OperationInfo[] work = new OperationInfo[5];
+ work[index++] = generateWork(MIN_DELAY * 2);
+ work[index++] = generateWork(0);
+ work[index++] = generateWork(MIN_DELAY);
+ work[index++] = generateWork(0);
+ work[index] = generateWork(MIN_DELAY * 3);
+
+ // Not part of the expected as it will be canceled
+ OperationInfo[] expected = new OperationInfo[3];
+ expected[0] = work[1]; // delay = 0
+ expected[1] = work[3]; // delay = 0
+ expected[2] = work[2]; // delay = MIN_DELAY
+
+ TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(expected), expected);
+ startWork(aqs, work);
+
+ Operation lastOne = aqs.getLastCancelableOperation(); // delay = 3
+ assertTrue("3) delay=3 is not last", work[4].equivalent(lastOne));
+ assertEquals("Can't cancel delay 2", 1, aqs.cancelOperation(work[0].token));
+ assertEquals("Delay 2 should be gone", 0, aqs.cancelOperation(work[0].token));
+ assertEquals("Can't cancel delay 3", 1, aqs.cancelOperation(work[4].token));
+ assertEquals("Delay 3 should be gone", 0, aqs.cancelOperation(work[4].token));
+
+ Log.d(TAG, "testCancel_multipleCancels Waiting >>>>>>>>>>>");
+ assertEquals("Not all operations were executed.", expected.length, aqs
+ .waitForCompletion(BASE_TEST_WAIT_TIME));
+ Log.d(TAG, "testCancel_multipleCancels Done <<<<<<<<<<<<<<");
+ }
+
+ private OperationInfo generateWork(long delayMillis) {
+ OperationInfo work = new OperationInfo();
+ work.op = Operation.EVENT_ARG_DELETE;
+
+ work.token = ++mId;
+ work.cookie = 100 + work.token;
+ work.uri = Uri.parse(AUTHORITY_URI + "blah");
+ work.selection = TEST_SELECTION;
+ work.selectionArgs = TEST_SELECTION_ARGS;
+
+ work.delayMillis = delayMillis;
+ work.result = 1000 + work.token;
+ return work;
+ }
+
+ private void startWork(TestAsyncQueryService aqs, OperationInfo[] work) {
+ for (OperationInfo w : work) {
+ if (w != null) {
+ aqs.startDelete(w.token, w.cookie, w.uri, w.selection, w.selectionArgs,
+ w.delayMillis);
+ }
+ }
+ }
+
+ OperationInfo[] generateSortedWork(OperationInfo[] work, int length) {
+ OperationInfo[] sorted = new OperationInfo[length];
+ System.arraycopy(work, 0, sorted, 0, length);
+
+ // Set the scheduled time so they get sorted properly
+ for (OperationInfo w : sorted) {
+ if (w != null) {
+ w.calculateScheduledTime();
+ }
+ }
+
+ // Stable sort by scheduled time
+ Arrays.sort(sorted);
+
+ Log.d(TAG, "Unsorted work: " + work.length);
+ for (OperationInfo w : work) {
+ if (w != null) {
+ Log.d(TAG, "Token#" + w.token + " delay=" + w.delayMillis);
+ }
+ }
+ Log.d(TAG, "Sorted work: " + sorted.length);
+ for (OperationInfo w : sorted) {
+ if (w != null) {
+ Log.d(TAG, "Token#" + w.token + " delay=" + w.delayMillis);
+ }
+ }
+
+ return sorted;
+ }
+
+ private Context buildTestContext(final OperationInfo[] work) {
+ MockContext context = new MockContext() {
+ MockContentResolver mResolver;
+
+ @Override
+ public ContentResolver getContentResolver() {
+ if (mResolver == null) {
+ ContentProvider provider = new TestProvider(work);
+ mResolver = new MockContentResolver();
+ mResolver.addProvider(AUTHORITY, provider);
+ }
+ return mResolver;
+ }
+
+ @Override
+ public String getPackageName() {
+ return AsyncQueryServiceTest.class.getPackage().getName();
+ }
+
+ public ComponentName startService(Intent service) {
+ AsyncQueryServiceTest.this.startService(service);
+ return service.getComponent();
+ }
+ };
+
+ return context;
+ }
+
+ private final class TestCursor extends MockCursor {
+ int mUnique = ++mId;
+
+ @Override
+ public int getCount() {
+ return mUnique;
+ }
+ }
+
+ /**
+ * TestAsyncQueryService takes the expected results in the constructor. They
+ * are used to verify the data passed to the callbacks.
+ */
+ class TestAsyncQueryService extends AsyncQueryService {
+ int mIndex = 0;
+
+ private OperationInfo[] mWork;
+
+ private Semaphore mCountingSemaphore;
+
+ public TestAsyncQueryService(Context context, OperationInfo[] work) {
+ super(context);
+ mCountingSemaphore = new Semaphore(0);
+
+ // run in a separate thread but call the same code
+ HandlerThread thread = new HandlerThread("TestAsyncQueryService");
+ thread.start();
+ super.setTestHandler(new Handler(thread.getLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ TestAsyncQueryService.this.handleMessage(msg);
+ }
+ });
+
+ mWork = work;
+ }
+
+ @Override
+ protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
+ Log.d(TAG, "onQueryComplete tid=" + Thread.currentThread().getId());
+ Log.d(TAG, "mWork.length=" + mWork.length + " mIndex=" + mIndex);
+
+ assertEquals(mWork[mIndex].op, Operation.EVENT_ARG_QUERY);
+ assertEquals(mWork[mIndex].token, token);
+ /*
+ * Even though our TestProvider returned mWork[mIndex].result, it is
+ * wrapped with new'ed CursorWrapperInner and there's no equal() in
+ * CursorWrapperInner. assertEquals the two cursor will always fail.
+ * So just compare the count which will be unique in our TestCursor;
+ */
+ assertEquals(((Cursor) mWork[mIndex].result).getCount(), cursor.getCount());
+
+ mIndex++;
+ mCountingSemaphore.release();
+ }
+
+ @Override
+ protected void onInsertComplete(int token, Object cookie, Uri uri) {
+ Log.d(TAG, "onInsertComplete tid=" + Thread.currentThread().getId());
+ Log.d(TAG, "mWork.length=" + mWork.length + " mIndex=" + mIndex);
+
+ assertEquals(mWork[mIndex].op, Operation.EVENT_ARG_INSERT);
+ assertEquals(mWork[mIndex].token, token);
+ assertEquals(mWork[mIndex].result, uri);
+
+ mIndex++;
+ mCountingSemaphore.release();
+ }
+
+ @Override
+ protected void onUpdateComplete(int token, Object cookie, int result) {
+ Log.d(TAG, "onUpdateComplete tid=" + Thread.currentThread().getId());
+ Log.d(TAG, "mWork.length=" + mWork.length + " mIndex=" + mIndex);
+
+ assertEquals(mWork[mIndex].op, Operation.EVENT_ARG_UPDATE);
+ assertEquals(mWork[mIndex].token, token);
+ assertEquals(mWork[mIndex].result, result);
+
+ mIndex++;
+ mCountingSemaphore.release();
+ }
+
+ @Override
+ protected void onDeleteComplete(int token, Object cookie, int result) {
+ Log.d(TAG, "onDeleteComplete tid=" + Thread.currentThread().getId());
+ Log.d(TAG, "mWork.length=" + mWork.length + " mIndex=" + mIndex);
+
+ assertEquals(mWork[mIndex].op, Operation.EVENT_ARG_DELETE);
+ assertEquals(mWork[mIndex].token, token);
+ assertEquals(mWork[mIndex].result, result);
+
+ mIndex++;
+ mCountingSemaphore.release();
+ }
+
+ @Override
+ protected void onBatchComplete(int token, Object cookie, ContentProviderResult[] results) {
+ Log.d(TAG, "onBatchComplete tid=" + Thread.currentThread().getId());
+ Log.d(TAG, "mWork.length=" + mWork.length + " mIndex=" + mIndex);
+
+ assertEquals(mWork[mIndex].op, Operation.EVENT_ARG_BATCH);
+ assertEquals(mWork[mIndex].token, token);
+
+ ContentProviderResult[] expected = (ContentProviderResult[]) mWork[mIndex].result;
+ assertEquals(expected.length, results.length);
+ for (int i = 0; i < expected.length; ++i) {
+ assertEquals(expected[i].count, results[i].count);
+ assertEquals(expected[i].uri, results[i].uri);
+ }
+
+ mIndex++;
+ mCountingSemaphore.release();
+ }
+
+ public int waitForCompletion(long timeoutMills) {
+ Log.d(TAG, "waitForCompletion tid=" + Thread.currentThread().getId());
+ int count = 0;
+ try {
+ while (count < mWork.length) {
+ if (!mCountingSemaphore.tryAcquire(timeoutMills, TimeUnit.MILLISECONDS)) {
+ break;
+ }
+ count++;
+ }
+ } catch (InterruptedException e) {
+ }
+ return count;
+ }
+ }
+
+ /**
+ * This gets called by AsyncQueryServiceHelper to read or write the data. It
+ * also verifies the data against the data passed in the constructor
+ */
+ class TestProvider extends ContentProvider {
+ OperationInfo[] mWork;
+
+ int index = 0;
+
+ public TestProvider(OperationInfo[] work) {
+ mWork = work;
+ }
+
+ @Override
+ public final Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String orderBy) {
+ Log.d(TAG, "Provider query index=" + index);
+ assertEquals(mWork[index].op, Operation.EVENT_ARG_QUERY);
+ assertEquals(mWork[index].uri, uri);
+ assertEquals(mWork[index].projection, projection);
+ assertEquals(mWork[index].selection, selection);
+ assertEquals(mWork[index].selectionArgs, selectionArgs);
+ assertEquals(mWork[index].orderBy, orderBy);
+ return (Cursor) mWork[index++].result;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ Log.d(TAG, "Provider insert index=" + index);
+ assertEquals(mWork[index].op, Operation.EVENT_ARG_INSERT);
+ assertEquals(mWork[index].uri, uri);
+ assertEquals(mWork[index].values, values);
+ return (Uri) mWork[index++].result;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ Log.d(TAG, "Provider update index=" + index);
+ assertEquals(mWork[index].op, Operation.EVENT_ARG_UPDATE);
+ assertEquals(mWork[index].uri, uri);
+ assertEquals(mWork[index].values, values);
+ assertEquals(mWork[index].selection, selection);
+ assertEquals(mWork[index].selectionArgs, selectionArgs);
+ return (Integer) mWork[index++].result;
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ Log.d(TAG, "Provider delete index=" + index);
+ assertEquals(mWork[index].op, Operation.EVENT_ARG_DELETE);
+ assertEquals(mWork[index].uri, uri);
+ assertEquals(mWork[index].selection, selection);
+ assertEquals(mWork[index].selectionArgs, selectionArgs);
+ return (Integer) mWork[index++].result;
+ }
+
+ @Override
+ public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) {
+ Log.d(TAG, "Provider applyBatch index=" + index);
+ assertEquals(mWork[index].op, Operation.EVENT_ARG_BATCH);
+ assertEquals(mWork[index].cpo, operations);
+ return (ContentProviderResult[]) mWork[index++].result;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return null;
+ }
+
+ @Override
+ public boolean onCreate() {
+ return false;
+ }
+ }
+}