Merge "Remove support for auto-paging of cursors." into oc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
7f0d8c8076
@@ -11781,15 +11781,6 @@ package android.database {
|
||||
field protected final java.util.ArrayList<T> mObservers;
|
||||
}
|
||||
|
||||
public final class PageViewCursor extends android.database.CursorWrapper implements android.database.CrossProcessCursor {
|
||||
ctor public PageViewCursor(android.database.Cursor, android.os.Bundle);
|
||||
method public void fillWindow(int, android.database.CursorWindow);
|
||||
method public android.database.CursorWindow getWindow();
|
||||
method public boolean onMove(int, int);
|
||||
method public static android.database.Cursor wrap(android.database.Cursor, android.os.Bundle);
|
||||
field public static final java.lang.String EXTRA_AUTO_PAGED = "android.content.extra.AUTO_PAGED";
|
||||
}
|
||||
|
||||
public class SQLException extends java.lang.RuntimeException {
|
||||
ctor public SQLException();
|
||||
ctor public SQLException(java.lang.String);
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.database.Cursor;
|
||||
import android.database.CursorToBulkCursorAdaptor;
|
||||
import android.database.DatabaseUtils;
|
||||
import android.database.IContentObserver;
|
||||
import android.database.PageViewCursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
@@ -104,7 +103,6 @@ abstract public class ContentProviderNative extends Binder implements IContentPr
|
||||
if (cursor != null) {
|
||||
CursorToBulkCursorAdaptor adaptor = null;
|
||||
|
||||
cursor = PageViewCursor.wrap(cursor, queryArgs);
|
||||
try {
|
||||
adaptor = new CursorToBulkCursorAdaptor(cursor, observer,
|
||||
getProviderName());
|
||||
|
||||
@@ -1,308 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 android.database;
|
||||
|
||||
import static com.android.internal.util.ArrayUtils.contains;
|
||||
import static com.android.internal.util.Preconditions.checkArgument;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.TestApi;
|
||||
import android.content.ContentResolver;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.util.MathUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Cursor wrapper that provides visibility into a subset of a wrapped cursor.
|
||||
*
|
||||
* The window is specified by offset and limit.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
public final class PageViewCursor extends CursorWrapper implements CrossProcessCursor {
|
||||
|
||||
/** An extra added to results that are auto-paged using the wrapper. */
|
||||
public static final String EXTRA_AUTO_PAGED = "android.content.extra.AUTO_PAGED";
|
||||
|
||||
private static final String[] EMPTY_ARGS = new String[0];
|
||||
private static final String TAG = "PageViewCursor";
|
||||
private static final boolean DEBUG = Build.IS_DEBUGGABLE;
|
||||
private static final boolean VERBOSE = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
|
||||
|
||||
private final int mOffset; // aka first index
|
||||
private final int mCount;
|
||||
private final Bundle mExtras;
|
||||
|
||||
private @Nullable CursorWindow mWindow;
|
||||
private int mPos = -1;
|
||||
private int mWindowFillCount = 0;
|
||||
|
||||
/**
|
||||
* @see PageViewCursor#wrap(Cursor, Bundle)
|
||||
*/
|
||||
public PageViewCursor(Cursor cursor, Bundle queryArgs) {
|
||||
super(cursor);
|
||||
|
||||
int offset = queryArgs.getInt(ContentResolver.QUERY_ARG_OFFSET, 0);
|
||||
int limit = queryArgs.getInt(ContentResolver.QUERY_ARG_LIMIT, Integer.MAX_VALUE);
|
||||
|
||||
checkArgument(offset > -1);
|
||||
checkArgument(limit > -1);
|
||||
|
||||
int count = mCursor.getCount();
|
||||
|
||||
mOffset = offset;
|
||||
|
||||
mExtras = new Bundle();
|
||||
Bundle extras = cursor.getExtras();
|
||||
if (extras != null) {
|
||||
mExtras.putAll(extras);
|
||||
}
|
||||
|
||||
// When we're wrapping another cursor, it should not already be "paged".
|
||||
checkArgument(!hasPagedResponseDetails(mExtras));
|
||||
|
||||
mExtras.putBoolean(EXTRA_AUTO_PAGED, true);
|
||||
mExtras.putInt(ContentResolver.EXTRA_TOTAL_SIZE, count);
|
||||
|
||||
// Ensure we retain any extra args supplied in cursor extras, and add
|
||||
// offset and/or limit.
|
||||
String[] existingArgs = mExtras.getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
|
||||
existingArgs = existingArgs != null ? existingArgs : EMPTY_ARGS;
|
||||
|
||||
int size = existingArgs.length;
|
||||
|
||||
// copy the array with space for the extra query args we'll be adding.
|
||||
String[] newArgs = Arrays.copyOf(existingArgs, size + 2);
|
||||
|
||||
if (queryArgs.containsKey(ContentResolver.QUERY_ARG_OFFSET)) {
|
||||
newArgs[size++] = ContentResolver.QUERY_ARG_OFFSET;
|
||||
}
|
||||
if (queryArgs.containsKey(ContentResolver.QUERY_ARG_LIMIT)) {
|
||||
newArgs[size++] = ContentResolver.QUERY_ARG_LIMIT;
|
||||
}
|
||||
|
||||
assert(size > existingArgs.length); // must add at least one arg.
|
||||
|
||||
// At this point there may be a null element at the end of
|
||||
// the array because our pre-sizing didn't match the actualy
|
||||
// number of args we added. So we trim.
|
||||
if (size == newArgs.length - 1) {
|
||||
newArgs = Arrays.copyOf(newArgs, size);
|
||||
}
|
||||
mExtras.putStringArray(ContentResolver.EXTRA_HONORED_ARGS, newArgs);
|
||||
|
||||
mCount = MathUtils.constrain(count - offset, 0, limit);
|
||||
|
||||
if (DEBUG) Log.d(TAG, "Wrapped cursor"
|
||||
+ " offset: " + mOffset
|
||||
+ ", limit: " + limit
|
||||
+ ", delegate_size: " + count
|
||||
+ ", paged_count: " + mCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle getExtras() {
|
||||
return mExtras;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPosition() {
|
||||
return mPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBeforeFirst() {
|
||||
if (mCount == 0) {
|
||||
return true;
|
||||
}
|
||||
return mPos == -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAfterLast() {
|
||||
if (mCount == 0) {
|
||||
return true;
|
||||
}
|
||||
return mPos == mCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFirst() {
|
||||
return mPos == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLast() {
|
||||
return mPos == mCount - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToFirst() {
|
||||
return moveToPosition(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToLast() {
|
||||
return moveToPosition(mCount - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToNext() {
|
||||
return move(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToPrevious() {
|
||||
return move(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean move(int offset) {
|
||||
return moveToPosition(mPos + offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToPosition(int position) {
|
||||
if (position >= mCount) {
|
||||
if (VERBOSE) Log.v(TAG, "Invalid Positon: " + position + " >= count: " + mCount
|
||||
+ ". Moving to last record.");
|
||||
mPos = mCount;
|
||||
super.moveToPosition(mOffset + mPos); // move into "after last" state.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure position isn't before the beginning of the cursor
|
||||
if (position < 0) {
|
||||
if (VERBOSE) Log.v(TAG, "Ignoring invalid move to position: " + position);
|
||||
mPos = -1;
|
||||
super.moveToPosition(mPos);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (position == mPos) {
|
||||
if (VERBOSE) Log.v(TAG, "Ignoring no-op move to position: " + position);
|
||||
return true;
|
||||
}
|
||||
|
||||
int delegatePosition = position + mOffset;
|
||||
if (VERBOSE) Log.v(TAG, "Moving delegate cursor to position: " + delegatePosition);
|
||||
if (super.moveToPosition(delegatePosition)) {
|
||||
mPos = position;
|
||||
return true;
|
||||
} else {
|
||||
mPos = -1;
|
||||
super.moveToPosition(-1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMove(int oldPosition, int newPosition) {
|
||||
throw new UnsupportedOperationException("Not supported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getWantsAllOnMoveCalls() {
|
||||
return false; // we want bulk cursor adapter to lift data into a CursorWindow.
|
||||
}
|
||||
|
||||
@Override
|
||||
public CursorWindow getWindow() {
|
||||
assert(mPos == -1 || mPos == 0);
|
||||
if (mWindow == null) {
|
||||
mWindow = new CursorWindow("PageViewCursorWindow");
|
||||
fillWindow(0, mWindow);
|
||||
}
|
||||
|
||||
return mWindow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillWindow(int position, CursorWindow window) {
|
||||
assert(window == mWindow);
|
||||
|
||||
if (mWindowFillCount++ > 0) {
|
||||
Log.w(TAG, "Re-filling window on paged cursor! Reduce ContentResolver.QUERY_ARG_LIMIT");
|
||||
}
|
||||
|
||||
DatabaseUtils.cursorFillWindow(this, position, window);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the cursor such that it will honor paging args (if present), AND if the cursor does
|
||||
* not report paging size.
|
||||
* <p>
|
||||
* No-op if cursor already contains paging or is less than specified page size.
|
||||
*/
|
||||
public static Cursor wrap(Cursor cursor, @Nullable Bundle queryArgs) {
|
||||
|
||||
boolean hasPagingArgs = queryArgs != null
|
||||
&& (queryArgs.containsKey(ContentResolver.QUERY_ARG_OFFSET)
|
||||
|| queryArgs.containsKey(ContentResolver.QUERY_ARG_LIMIT));
|
||||
|
||||
if (!hasPagingArgs) {
|
||||
if (VERBOSE) Log.v(TAG, "No-wrap: No paging args in request.");
|
||||
return cursor;
|
||||
}
|
||||
|
||||
if (hasPagedResponseDetails(cursor.getExtras())) {
|
||||
if (VERBOSE) Log.v(TAG, "No-wrap. Cursor has paging details.");
|
||||
return cursor;
|
||||
}
|
||||
|
||||
// Cursors that want all calls aren't compatible with our way
|
||||
// of doing business. TODO: Cover this case in CTS.
|
||||
if (cursor.getWantsAllOnMoveCalls()) {
|
||||
Log.w(TAG, "Unable to wrap cursor that wants to hear about move calls.");
|
||||
return cursor;
|
||||
}
|
||||
|
||||
return new PageViewCursor(cursor, queryArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the extras contains information indicating the associated cursor is
|
||||
* paged.
|
||||
*/
|
||||
private static boolean hasPagedResponseDetails(@Nullable Bundle extras) {
|
||||
if (extras == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (extras.containsKey(ContentResolver.EXTRA_TOTAL_SIZE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String[] honoredArgs = extras.getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
|
||||
if (honoredArgs != null
|
||||
&& (contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET)
|
||||
|| contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,387 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 android.database;
|
||||
|
||||
import static com.android.internal.util.ArrayUtils.contains;
|
||||
import static com.android.internal.util.Preconditions.checkArgument;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.ContentResolver;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.util.Log;
|
||||
import android.util.MathUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class PageViewCursorTest {
|
||||
|
||||
private static final int ITEM_COUNT = 20;
|
||||
|
||||
private static final String NAME_COLUMN = "name";
|
||||
private static final String NUM_COLUMN = "num";
|
||||
|
||||
private static final String[] COLUMNS = new String[] {
|
||||
NAME_COLUMN,
|
||||
NUM_COLUMN
|
||||
};
|
||||
|
||||
private static final String[] NAMES = new String[] {
|
||||
"000",
|
||||
"111",
|
||||
"222",
|
||||
"333",
|
||||
"444",
|
||||
"555",
|
||||
"666",
|
||||
"777",
|
||||
"888",
|
||||
"999",
|
||||
"aaa",
|
||||
"bbb",
|
||||
"ccc",
|
||||
"ddd",
|
||||
"eee",
|
||||
"fff",
|
||||
"ggg",
|
||||
"hhh",
|
||||
"iii",
|
||||
"jjj"
|
||||
};
|
||||
|
||||
private MatrixCursor mDelegate;
|
||||
private PageViewCursor mCursor;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Random rand = new Random();
|
||||
|
||||
mDelegate = new MatrixCursor(COLUMNS);
|
||||
for (int i = 0; i < ITEM_COUNT; i++) {
|
||||
MatrixCursor.RowBuilder row = mDelegate.newRow();
|
||||
row.add(NAME_COLUMN, NAMES[i]);
|
||||
row.add(NUM_COLUMN, rand.nextInt());
|
||||
}
|
||||
|
||||
mCursor = new PageViewCursor(mDelegate, createArgs(10, 5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPage_Size() {
|
||||
assertEquals(5, mCursor.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPage_TotalSize() {
|
||||
assertEquals(ITEM_COUNT, mCursor.getExtras().getInt(ContentResolver.EXTRA_TOTAL_SIZE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPage_OffsetExceedsCursorCount_EffectivelyEmptyCursor() {
|
||||
mCursor = new PageViewCursor(mDelegate, createArgs(ITEM_COUNT * 2, 5));
|
||||
assertEquals(0, mCursor.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveToPosition() {
|
||||
assertTrue(mCursor.moveToPosition(0));
|
||||
assertEquals(NAMES[10], mCursor.getString(0));
|
||||
assertTrue(mCursor.moveToPosition(1));
|
||||
assertEquals(NAMES[11], mCursor.getString(0));
|
||||
assertTrue(mCursor.moveToPosition(4));
|
||||
assertEquals(NAMES[14], mCursor.getString(0));
|
||||
|
||||
// and then back down again for good measure.
|
||||
assertTrue(mCursor.moveToPosition(1));
|
||||
assertEquals(NAMES[11], mCursor.getString(0));
|
||||
assertTrue(mCursor.moveToPosition(0));
|
||||
assertEquals(NAMES[10], mCursor.getString(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveToPosition_MoveToSamePosition_NoOp() {
|
||||
assertTrue(mCursor.moveToPosition(1));
|
||||
assertEquals(NAMES[11], mCursor.getString(0));
|
||||
assertTrue(mCursor.moveToPosition(1));
|
||||
assertEquals(NAMES[11], mCursor.getString(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveToPosition_PositionOutOfBounds_MovesToBeforeFirst() {
|
||||
assertTrue(mCursor.moveToPosition(0));
|
||||
assertEquals(NAMES[10], mCursor.getString(0));
|
||||
|
||||
// move before
|
||||
assertFalse(mCursor.moveToPosition(-12));
|
||||
assertTrue(mCursor.isBeforeFirst());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveToPosition_PositionOutOfBounds_MovesToAfterLast() {
|
||||
assertTrue(mCursor.moveToPosition(0));
|
||||
assertEquals(NAMES[10], mCursor.getString(0));
|
||||
|
||||
assertFalse(mCursor.moveToPosition(222));
|
||||
assertTrue(mCursor.isAfterLast());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPosition() {
|
||||
assertEquals(-1, mCursor.getPosition());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsBeforeFirst() {
|
||||
assertTrue(mCursor.isBeforeFirst());
|
||||
mCursor.moveToFirst();
|
||||
assertFalse(mCursor.isBeforeFirst());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCount_ZeroForEmptyCursor() {
|
||||
mCursor = new PageViewCursor(mDelegate, createArgs(0, 0));
|
||||
assertEquals(0, mCursor.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsBeforeFirst_TrueForEmptyCursor() {
|
||||
mCursor = new PageViewCursor(mDelegate, createArgs(0, 0));
|
||||
assertTrue(mCursor.isBeforeFirst());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAfterLast() {
|
||||
assertFalse(mCursor.isAfterLast());
|
||||
mCursor.moveToLast();
|
||||
mCursor.moveToNext();
|
||||
assertTrue(mCursor.isAfterLast());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAfterLast_TrueForEmptyCursor() {
|
||||
mCursor = new PageViewCursor(mDelegate, createArgs(0, 0));
|
||||
assertTrue(mCursor.isAfterLast());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsFirst() {
|
||||
assertFalse(mCursor.isFirst());
|
||||
mCursor.moveToFirst();
|
||||
assertTrue(mCursor.isFirst());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsLast() {
|
||||
assertFalse(mCursor.isLast());
|
||||
mCursor.moveToLast();
|
||||
assertTrue(mCursor.isLast());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMove() {
|
||||
// note that initial position is -1, so moving
|
||||
// 2 will only put as at 1.
|
||||
mCursor.move(2);
|
||||
assertEquals(NAMES[11], mCursor.getString(0));
|
||||
mCursor.move(-1);
|
||||
assertEquals(NAMES[10], mCursor.getString(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveToFist() {
|
||||
mCursor.moveToPosition(3);
|
||||
mCursor.moveToFirst();
|
||||
assertEquals(NAMES[10], mCursor.getString(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveToLast() {
|
||||
mCursor.moveToLast();
|
||||
assertEquals(NAMES[14], mCursor.getString(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveToNext() {
|
||||
// default position is -1, so next is 0.
|
||||
mCursor.moveToNext();
|
||||
assertEquals(NAMES[10], mCursor.getString(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveToNext_AfterLastReturnsFalse() {
|
||||
mCursor.moveToLast();
|
||||
assertFalse(mCursor.moveToNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveToPrevious() {
|
||||
mCursor.moveToPosition(3);
|
||||
mCursor.moveToPrevious();
|
||||
assertEquals(NAMES[12], mCursor.getString(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMoveToPrevious_BeforeFirstReturnsFalse() {
|
||||
assertFalse(mCursor.moveToPrevious());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWindow_ReadPastEnd() {
|
||||
assertFalse(mCursor.moveToPosition(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLimitOutOfBounds() {
|
||||
mCursor = new PageViewCursor(mDelegate, createArgs(5, 100));
|
||||
assertEquals(15, mCursor.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOffsetOutOfBounds_EmptyResult() {
|
||||
mCursor = new PageViewCursor(mDelegate, createArgs(100000, 100));
|
||||
assertEquals(0, mCursor.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddsExtras() {
|
||||
mCursor = new PageViewCursor(mDelegate, createArgs(5, 100));
|
||||
assertTrue(mCursor.getExtras().getBoolean(PageViewCursor.EXTRA_AUTO_PAGED));
|
||||
String[] honoredArgs = mCursor.getExtras()
|
||||
.getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
|
||||
assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET));
|
||||
assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddsExtras_OnlyOffset() {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ContentResolver.QUERY_ARG_OFFSET, 5);
|
||||
mCursor = new PageViewCursor(mDelegate, args);
|
||||
String[] honoredArgs = mCursor.getExtras()
|
||||
.getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
|
||||
assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET));
|
||||
assertFalse(contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddsExtras_OnlyLimit() {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ContentResolver.QUERY_ARG_LIMIT, 5);
|
||||
mCursor = new PageViewCursor(mDelegate, args);
|
||||
String[] honoredArgs = mCursor.getExtras()
|
||||
.getStringArray(ContentResolver.EXTRA_HONORED_ARGS);
|
||||
assertFalse(contains(honoredArgs, ContentResolver.QUERY_ARG_OFFSET));
|
||||
assertTrue(contains(honoredArgs, ContentResolver.QUERY_ARG_LIMIT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetWindow() {
|
||||
mCursor = new PageViewCursor(mDelegate, createArgs(5, 5));
|
||||
CursorWindow window = mCursor.getWindow();
|
||||
assertEquals(5, window.getNumRows());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWraps() {
|
||||
Bundle args = createArgs(5, 5);
|
||||
Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
|
||||
assertTrue(wrapped instanceof PageViewCursor);
|
||||
assertEquals(5, wrapped.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWraps_NullExtras() {
|
||||
Bundle args = createArgs(5, 5);
|
||||
mDelegate.setExtras(null);
|
||||
Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
|
||||
assertTrue(wrapped instanceof PageViewCursor);
|
||||
assertEquals(5, wrapped.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWraps_WithJustOffset() {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ContentResolver.QUERY_ARG_OFFSET, 5);
|
||||
Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
|
||||
assertTrue(wrapped instanceof PageViewCursor);
|
||||
assertEquals(15, wrapped.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWraps_WithJustLimit() {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ContentResolver.QUERY_ARG_LIMIT, 5);
|
||||
Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
|
||||
assertTrue(wrapped instanceof PageViewCursor);
|
||||
assertEquals(5, wrapped.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoWrap_WithoutPagingArgs() {
|
||||
Cursor wrapped = PageViewCursor.wrap(mDelegate, Bundle.EMPTY);
|
||||
assertTrue(mDelegate == wrapped);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoWrap_CursorsHasExistingPaging_ByTotalSize() {
|
||||
Bundle extras = new Bundle();
|
||||
extras.putInt(ContentResolver.EXTRA_TOTAL_SIZE, 5);
|
||||
mDelegate.setExtras(extras);
|
||||
|
||||
Bundle args = createArgs(5, 5);
|
||||
Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
|
||||
assertTrue(mDelegate == wrapped);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoWrap_CursorsHasExistingPaging_ByHonoredArgs() {
|
||||
Bundle extras = new Bundle();
|
||||
extras.putStringArray(
|
||||
ContentResolver.EXTRA_HONORED_ARGS,
|
||||
new String[] {
|
||||
ContentResolver.QUERY_ARG_OFFSET,
|
||||
ContentResolver.QUERY_ARG_LIMIT
|
||||
});
|
||||
mDelegate.setExtras(extras);
|
||||
|
||||
Bundle args = createArgs(5, 5);
|
||||
Cursor wrapped = PageViewCursor.wrap(mDelegate, args);
|
||||
assertTrue(mDelegate == wrapped);
|
||||
}
|
||||
|
||||
private static Bundle createArgs(int offset, int limit) {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ContentResolver.QUERY_ARG_OFFSET, offset);
|
||||
args.putInt(ContentResolver.QUERY_ARG_LIMIT, limit);
|
||||
return args;
|
||||
}
|
||||
|
||||
private void assertStringAt(int row, int column, String expected) {
|
||||
mCursor.moveToPosition(row);
|
||||
assertEquals(expected, mCursor.getString(column));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user