OSDN Git Service

original
[gb-231r1-is01/GB_2.3_IS01.git] / cts / tests / tests / database / src / android / database / cts / AbstractCursorTest.java
diff --git a/cts/tests/tests/database/src/android/database/cts/AbstractCursorTest.java b/cts/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
new file mode 100644 (file)
index 0000000..47c52ba
--- /dev/null
@@ -0,0 +1,878 @@
+/*
+ * Copyright (C) 2008 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.cts;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.ToBeFixed;
+
+import android.content.Context;
+import android.database.AbstractCursor;
+import android.database.CharArrayBuffer;
+import android.database.ContentObserver;
+import android.database.CursorIndexOutOfBoundsException;
+import android.database.CursorWindow;
+import android.database.DataSetObserver;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.os.Bundle;
+import android.test.InstrumentationTestCase;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Random;
+
+/**
+ * Test {@link AbstractCursor}.
+ */
+@TestTargetClass(AbstractCursor.class)
+public class AbstractCursorTest extends InstrumentationTestCase {
+    private static final int POSITION0 = 0;
+    private static final int POSITION1 = 1;
+    private  static final int ROW_MAX = 10;
+    private static final int DATA_COUNT = 10;
+    private static final String[] COLUMN_NAMES1 = new String[] {
+        "_id",             // 0
+        "number"           // 1
+    };
+    private static final String[] COLUMN_NAMES = new String[] { "name", "number", "profit" };
+    private TestAbstractCursor mTestAbstractCursor;
+    private Object mLockObj = new Object();
+
+    private SQLiteDatabase mDatabase;
+    private File mDatabaseFile;
+    private AbstractCursor mDatabaseCursor;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        setupDatabase();
+        ArrayList<ArrayList> list = createTestList(ROW_MAX, COLUMN_NAMES.length);
+        mTestAbstractCursor = new TestAbstractCursor(COLUMN_NAMES, list);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDatabaseCursor.close();
+        mTestAbstractCursor.close();
+        mDatabase.close();
+        if (mDatabaseFile.exists()) {
+            mDatabaseFile.delete();
+        }
+        super.tearDown();
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "AbstractCursor",
+        args = {}
+    )
+    public void testConstructor() {
+        TestAbstractCursor abstractCursor = new TestAbstractCursor();
+        assertEquals(-1, abstractCursor.getPosition());
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "getBlob",
+        args = {int.class}
+    )
+    public void testGetBlob() {
+        try {
+            mTestAbstractCursor.getBlob(0);
+            fail("getBlob should throws a UnsupportedOperationException here");
+        } catch (UnsupportedOperationException e) {
+            // expected
+        }
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "registerDataSetObserver",
+            args = {android.database.DataSetObserver.class}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "unregisterDataSetObserver",
+            args = {android.database.DataSetObserver.class}
+        )
+    })
+    public void testRegisterDataSetObserver() {
+        MockDataSetObserver datasetObserver = new MockDataSetObserver();
+
+        try {
+            mDatabaseCursor.unregisterDataSetObserver(datasetObserver);
+            fail("Can't unregister DataSetObserver before it is registered.");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+
+        mDatabaseCursor.registerDataSetObserver(datasetObserver);
+
+        try {
+            mDatabaseCursor.registerDataSetObserver(datasetObserver);
+            fail("Can't register DataSetObserver twice before unregister it.");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+
+        mDatabaseCursor.unregisterDataSetObserver(datasetObserver);
+        mDatabaseCursor.registerDataSetObserver(datasetObserver);
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "registerContentObserver",
+            args = {android.database.ContentObserver.class}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "unregisterContentObserver",
+            args = {android.database.ContentObserver.class}
+        )
+    })
+    public void testRegisterContentObserver() {
+        MockContentObserver contentObserver = new MockContentObserver();
+
+        try {
+            mDatabaseCursor.unregisterContentObserver(contentObserver);
+            fail("Can't unregister ContentObserver before it is registered.");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+
+        mDatabaseCursor.registerContentObserver(contentObserver);
+
+        try {
+            mDatabaseCursor.registerContentObserver(contentObserver);
+            fail("Can't register DataSetObserver twice before unregister it.");
+        } catch (IllegalStateException e) {
+            // expected
+        }
+
+        mDatabaseCursor.unregisterContentObserver(contentObserver);
+        mDatabaseCursor.registerContentObserver(contentObserver);
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "setNotificationUri",
+        args = {android.content.ContentResolver.class, android.net.Uri.class}
+    )
+    public void testSetNotificationUri() {
+        String MOCK_URI = "content://abstractrcursortest/testtable";
+        mDatabaseCursor.setNotificationUri(getInstrumentation().getContext().getContentResolver(),
+                Uri.parse(MOCK_URI));
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "respond",
+        args = {android.os.Bundle.class}
+    )
+    public void testRespond() {
+        Bundle b = new Bundle();
+        Bundle bundle = mDatabaseCursor.respond(b);
+        assertSame(Bundle.EMPTY, bundle);
+
+        bundle = mDatabaseCursor.respond(null);
+        assertSame(Bundle.EMPTY, bundle);
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "requery",
+        args = {}
+    )
+    public void testRequery() {
+        MockDataSetObserver mock = new MockDataSetObserver();
+        mDatabaseCursor.registerDataSetObserver(mock);
+        assertFalse(mock.hadCalledOnChanged());
+        mDatabaseCursor.requery();
+        assertTrue(mock.hadCalledOnChanged());
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        notes = "Test onChange().Subclasses must call this method when they finish committing" +
+                " updates to notify all observers.",
+        method = "onChange",
+        args = {boolean.class}
+    )
+    public void testOnChange() throws InterruptedException {
+        MockContentObserver mock = new MockContentObserver();
+        mTestAbstractCursor.registerContentObserver(mock);
+        assertFalse(mock.hadCalledOnChange());
+        mTestAbstractCursor.onChange(true);
+        synchronized(mLockObj) {
+            if ( !mock.hadCalledOnChange() ) {
+                mLockObj.wait(5000);
+            }
+        }
+        assertTrue(mock.hadCalledOnChange());
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "onMove",
+            args = {int.class, int.class}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "moveToFirst",
+            args = {}
+        )
+    })
+    public void testOnMove() {
+        mTestAbstractCursor.resetOnMoveRet();
+        assertFalse(mTestAbstractCursor.getOnMoveRet());
+        mTestAbstractCursor.moveToFirst();
+        mTestAbstractCursor.moveToPosition(5);
+        assertTrue(mTestAbstractCursor.getOnMoveRet());
+        assertEquals(0, mTestAbstractCursor.getOldPos());
+        assertEquals(5, mTestAbstractCursor.getNewPos());
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "moveToPrevious",
+            args = {}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "moveToPosition",
+            args = {int.class}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "getPosition",
+            args = {}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "moveToNext",
+            args = {}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "isFirst",
+            args = {}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "moveToLast",
+            args = {}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "isLast",
+            args = {}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "isBeforeFirst",
+            args = {}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "isAfterLast",
+            args = {}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "moveToFirst",
+            args = {}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "move",
+            args = {int.class}
+        )
+    })
+    public void testMoveToPrevious() {
+        // Test moveToFirst, isFirst, moveToNext, getPosition
+        assertTrue(mDatabaseCursor.moveToFirst());
+        assertTrue(mDatabaseCursor.isFirst());
+        assertEquals(0, mDatabaseCursor.getPosition());
+        assertTrue(mDatabaseCursor.moveToNext());
+        assertEquals(1, mDatabaseCursor.getPosition());
+        assertFalse(mDatabaseCursor.isFirst());
+        assertTrue(mDatabaseCursor.moveToNext());
+        assertEquals(2, mDatabaseCursor.getPosition());
+
+        // invoke moveToPosition with a number larger than row count.
+        assertFalse(mDatabaseCursor.moveToPosition(30000));
+        assertEquals(mDatabaseCursor.getCount(), mDatabaseCursor.getPosition());
+
+        assertFalse(mDatabaseCursor.moveToPosition(-1));
+        assertEquals(-1, mDatabaseCursor.getPosition());
+        assertTrue(mDatabaseCursor.isBeforeFirst());
+
+        mDatabaseCursor.moveToPosition(5);
+        assertEquals(5, mDatabaseCursor.getPosition());
+
+        // Test moveToPrevious
+        assertTrue(mDatabaseCursor.moveToPrevious());
+        assertEquals(4, mDatabaseCursor.getPosition());
+        assertTrue(mDatabaseCursor.moveToPrevious());
+        assertEquals(3, mDatabaseCursor.getPosition());
+        assertTrue(mDatabaseCursor.moveToPrevious());
+        assertEquals(2, mDatabaseCursor.getPosition());
+
+        // Test moveToLast, isLast, moveToPrevius, isAfterLast.
+        assertFalse(mDatabaseCursor.isLast());
+        assertTrue(mDatabaseCursor.moveToLast());
+        assertTrue(mDatabaseCursor.isLast());
+        assertFalse(mDatabaseCursor.isAfterLast());
+
+        assertFalse(mDatabaseCursor.moveToNext());
+        assertTrue(mDatabaseCursor.isAfterLast());
+        assertFalse(mDatabaseCursor.moveToNext());
+        assertTrue(mDatabaseCursor.isAfterLast());
+        assertFalse(mDatabaseCursor.isLast());
+        assertTrue(mDatabaseCursor.moveToPrevious());
+        assertTrue(mDatabaseCursor.isLast());
+        assertTrue(mDatabaseCursor.moveToPrevious());
+        assertFalse(mDatabaseCursor.isLast());
+
+        // Test move(int).
+        mDatabaseCursor.moveToFirst();
+        assertEquals(0, mDatabaseCursor.getPosition());
+        assertFalse(mDatabaseCursor.move(-1));
+        assertEquals(-1, mDatabaseCursor.getPosition());
+        assertTrue(mDatabaseCursor.move(1));
+        assertEquals(0, mDatabaseCursor.getPosition());
+
+        assertTrue(mDatabaseCursor.move(5));
+        assertEquals(5, mDatabaseCursor.getPosition());
+        assertTrue(mDatabaseCursor.move(-1));
+        assertEquals(4, mDatabaseCursor.getPosition());
+
+        mDatabaseCursor.moveToLast();
+        assertTrue(mDatabaseCursor.isLast());
+        assertFalse(mDatabaseCursor.isAfterLast());
+        assertFalse(mDatabaseCursor.move(1));
+        assertFalse(mDatabaseCursor.isLast());
+        assertTrue(mDatabaseCursor.isAfterLast());
+        assertTrue(mDatabaseCursor.move(-1));
+        assertTrue(mDatabaseCursor.isLast());
+        assertFalse(mDatabaseCursor.isAfterLast());
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "isClosed",
+            args = {}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "close",
+            args = {}
+        )
+    })
+    public void testIsClosed() {
+        assertFalse(mDatabaseCursor.isClosed());
+        mDatabaseCursor.close();
+        assertTrue(mDatabaseCursor.isClosed());
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "getWindow",
+            args = {}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "fillWindow",
+            args = {int.class, android.database.CursorWindow.class}
+        )
+    })
+    public void testGetWindow() {
+        CursorWindow window = new CursorWindow(false);
+        assertEquals(0, window.getNumRows());
+        // fill window from position 0
+        mDatabaseCursor.fillWindow(0, window);
+
+        assertNotNull(mDatabaseCursor.getWindow());
+        assertEquals(mDatabaseCursor.getCount(), window.getNumRows());
+
+        while (mDatabaseCursor.moveToNext()) {
+            assertEquals(mDatabaseCursor.getInt(POSITION1),
+                    window.getInt(mDatabaseCursor.getPosition(), POSITION1));
+        }
+        window.clear();
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        notes = "Test getWantsAllOnMoveCalls(), it always returns false.",
+        method = "getWantsAllOnMoveCalls",
+        args = {}
+    )
+    public void testGetWantsAllOnMoveCalls() {
+        assertFalse(mDatabaseCursor.getWantsAllOnMoveCalls());
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "isFieldUpdated",
+        args = {int.class}
+    )
+    @ToBeFixed(bug = "1569265", explanation = "All other updating-related methods are 'hide' and "
+        + "'deprecated.")
+    public void testIsFieldUpdated() {
+        mTestAbstractCursor.moveToFirst();
+        assertFalse(mTestAbstractCursor.isFieldUpdated(0));
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "getUpdatedField",
+        args = {int.class}
+    )
+    @ToBeFixed(bug = "1569265", explanation = "All other updating-related methods are 'hide' and "
+        + "'deprecated.")
+    public void testGetUpdatedField() {
+        mTestAbstractCursor.moveToFirst();
+        try {
+            assertEquals("hello", mTestAbstractCursor.getUpdatedField(0));
+            fail("getUpdatedField should throws a NullPointerException here.");
+        } catch (NullPointerException e) {
+            // expected
+        }
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "getExtras",
+        args = {}
+    )
+    public void testGetExtras() {
+        assertSame(Bundle.EMPTY, mDatabaseCursor.getExtras());
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "getCount",
+        args = {}
+    )
+    public void testGetCount() {
+        assertEquals(DATA_COUNT, mDatabaseCursor.getCount());
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "getColumnNames",
+        args = {}
+    )
+    public void testGetColumnNames() {
+        String[] names = mDatabaseCursor.getColumnNames();
+        assertEquals(COLUMN_NAMES1.length, names.length);
+
+        for (int i = 0; i < COLUMN_NAMES1.length; i++) {
+            assertEquals(COLUMN_NAMES1[i], names[i]);
+        }
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "getColumnName",
+        args = {int.class}
+    )
+    public void testGetColumnName() {
+        assertEquals(COLUMN_NAMES1[0], mDatabaseCursor.getColumnName(0));
+        assertEquals(COLUMN_NAMES1[1], mDatabaseCursor.getColumnName(1));
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "getColumnIndexOrThrow",
+            args = {java.lang.String.class}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "getColumnIndex",
+            args = {java.lang.String.class}
+        )
+    })
+    public void testGetColumnIndexOrThrow() {
+        final String COLUMN_FAKE = "fake_name";
+        assertEquals(POSITION0, mDatabaseCursor.getColumnIndex(COLUMN_NAMES1[POSITION0]));
+        assertEquals(POSITION1, mDatabaseCursor.getColumnIndex(COLUMN_NAMES1[POSITION1]));
+        assertEquals(POSITION0, mDatabaseCursor.getColumnIndexOrThrow(COLUMN_NAMES1[POSITION0]));
+        assertEquals(POSITION1, mDatabaseCursor.getColumnIndexOrThrow(COLUMN_NAMES1[POSITION1]));
+
+        try {
+            mDatabaseCursor.getColumnIndexOrThrow(COLUMN_FAKE);
+            fail("IllegalArgumentException expected, but not thrown");
+        } catch (IllegalArgumentException expected) {
+            // expected
+        }
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "getColumnIndex.",
+        args = {java.lang.String.class}
+    )
+    public void testGetColumnIndex() {
+        assertEquals(POSITION0, mDatabaseCursor.getColumnIndex(COLUMN_NAMES1[POSITION0]));
+        assertEquals(POSITION1, mDatabaseCursor.getColumnIndex(COLUMN_NAMES1[POSITION1]));
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "getColumnCount",
+        args = {}
+    )
+    public void testGetColumnCount() {
+        assertEquals(COLUMN_NAMES1.length, mDatabaseCursor.getColumnCount());
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "deactivateInternal",
+        args = {}
+    )
+    public void testDeactivateInternal() {
+        MockDataSetObserver mock = new MockDataSetObserver();
+        mDatabaseCursor.registerDataSetObserver(mock);
+        assertFalse(mock.hadCalledOnInvalid());
+        mDatabaseCursor.deactivateInternal();
+        assertTrue(mock.hadCalledOnInvalid());
+    }
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "deactivate",
+            args = {}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "registerDataSetObserver",
+            args = {android.database.DataSetObserver.class}
+        )
+    })
+    public void testDeactivate() {
+        MockDataSetObserver mock = new MockDataSetObserver();
+        mDatabaseCursor.registerDataSetObserver(mock);
+        assertFalse(mock.hadCalledOnInvalid());
+        mDatabaseCursor.deactivate();
+        assertTrue(mock.hadCalledOnInvalid());
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "copyStringToBuffer",
+        args = {int.class, android.database.CharArrayBuffer.class}
+    )
+    public void testCopyStringToBuffer() {
+        CharArrayBuffer ca = new CharArrayBuffer(1000);
+        mTestAbstractCursor.moveToFirst();
+        mTestAbstractCursor.copyStringToBuffer(0, ca);
+        CursorWindow window = new CursorWindow(false);
+        mTestAbstractCursor.fillWindow(0, window);
+
+        StringBuffer sb = new StringBuffer();
+        sb.append(window.getString(0, 0));
+        String str = mTestAbstractCursor.getString(0);
+        assertEquals(str.length(), ca.sizeCopied);
+        assertEquals(sb.toString(), new String(ca.data, 0, ca.sizeCopied));
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "checkPosition",
+        args = {}
+    )
+    public void testCheckPosition() {
+        // Test with position = -1.
+        try {
+            mTestAbstractCursor.checkPosition();
+            fail("copyStringToBuffer() should throws CursorIndexOutOfBoundsException here.");
+        } catch (CursorIndexOutOfBoundsException e) {
+            // expected
+        }
+
+        // Test with position = count.
+        assertTrue(mTestAbstractCursor.moveToPosition(mTestAbstractCursor.getCount() - 1));
+        mTestAbstractCursor.checkPosition();
+
+        try {
+            assertFalse(mTestAbstractCursor.moveToPosition(mTestAbstractCursor.getCount()));
+            assertEquals(mTestAbstractCursor.getCount(), mTestAbstractCursor.getPosition());
+            mTestAbstractCursor.checkPosition();
+            fail("copyStringToBuffer() should throws CursorIndexOutOfBoundsException here.");
+        } catch (CursorIndexOutOfBoundsException e) {
+            // expected
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static ArrayList<ArrayList> createTestList(int rows, int cols) {
+        ArrayList<ArrayList> list = new ArrayList<ArrayList>();
+        Random ran = new Random();
+
+        for (int i = 0; i < rows; i++) {
+            ArrayList<Integer> col = new ArrayList<Integer>();
+            list.add(col);
+
+            for (int j = 0; j < cols; j++) {
+                // generate random number
+                Integer r = ran.nextInt();
+                col.add(r);
+            }
+        }
+
+        return list;
+    }
+
+    private void setupDatabase() {
+        File dbDir = getInstrumentation().getTargetContext().getDir("tests",
+                Context.MODE_WORLD_WRITEABLE);
+        mDatabaseFile = new File(dbDir, "database_test.db");
+        if (mDatabaseFile.exists()) {
+            mDatabaseFile.delete();
+        }
+        mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
+        assertNotNull(mDatabaseFile);
+        mDatabase.execSQL("CREATE TABLE test1 (_id INTEGER PRIMARY KEY, number TEXT);");
+        generateData();
+        mDatabaseCursor = (AbstractCursor) mDatabase.query("test1", null, null, null, null, null,
+                null);
+    }
+
+    private void generateData() {
+        for ( int i = 0; i < DATA_COUNT; i++) {
+            mDatabase.execSQL("INSERT INTO test1 (number) VALUES ('" + i + "');");
+        }
+    }
+
+    private class TestAbstractCursor extends AbstractCursor {
+        private boolean mOnMoveReturnValue;
+        private int mOldPosition;
+        private int mNewPosition;
+        private String[] mColumnNames;
+        private ArrayList<Object>[] mRows;
+        private boolean mHadCalledOnChange = false;
+
+        public TestAbstractCursor() {
+            super();
+        }
+        @SuppressWarnings("unchecked")
+        public TestAbstractCursor(String[] columnNames, ArrayList<ArrayList> rows) {
+            int colCount = columnNames.length;
+            boolean foundID = false;
+            mRowIdColumnIndex = 0;
+
+            // Add an _id column if not in columnNames
+            for (int i = 0; i < colCount; ++i) {
+                if (columnNames[i].compareToIgnoreCase("_id") == 0) {
+                    mColumnNames = columnNames;
+                    foundID = true;
+                    break;
+                }
+            }
+
+            if (!foundID) {
+                mColumnNames = new String[colCount + 1];
+                System.arraycopy(columnNames, 0, mColumnNames, 0, columnNames.length);
+                mColumnNames[colCount] = "_id";
+            }
+
+            int rowCount = rows.size();
+            mRows = new ArrayList[rowCount];
+
+            for (int i = 0; i < rowCount; ++i) {
+                mRows[i] = rows.get(i);
+
+                if (!foundID) {
+                    mRows[i].add(Long.valueOf(i));
+                }
+            }
+        }
+
+        public boolean getOnMoveRet() {
+            return mOnMoveReturnValue;
+        }
+
+        public void resetOnMoveRet() {
+            mOnMoveReturnValue = false;
+        }
+
+        public int getOldPos() {
+            return mOldPosition;
+        }
+
+        public int getNewPos() {
+            return mNewPosition;
+        }
+
+        @Override
+        public boolean onMove(int oldPosition, int newPosition) {
+            mOnMoveReturnValue = super.onMove(oldPosition, newPosition);
+            mOldPosition = oldPosition;
+            mNewPosition = newPosition;
+            return mOnMoveReturnValue;
+        }
+
+        @Override
+        public int getCount() {
+            return mRows.length;
+        }
+
+        @Deprecated
+        @Override
+        public boolean deleteRow() {
+            return false;
+        }
+
+        @Override
+        public String[] getColumnNames() {
+            return mColumnNames;
+        }
+
+        @Override
+        public String getString(int columnIndex) {
+            Object cell = mRows[mPos].get(columnIndex);
+            return (cell == null) ? null : cell.toString();
+        }
+
+        @Override
+        public short getShort(int columnIndex) {
+            Number num = (Number) mRows[mPos].get(columnIndex);
+            return num.shortValue();
+        }
+
+        @Override
+        public int getInt(int columnIndex) {
+            Number num = (Number) mRows[mPos].get(columnIndex);
+            return num.intValue();
+        }
+
+        @Override
+        public long getLong(int columnIndex) {
+            Number num = (Number) mRows[mPos].get(columnIndex);
+            return num.longValue();
+        }
+
+        @Override
+        public float getFloat(int columnIndex) {
+            Number num = (Number) mRows[mPos].get(columnIndex);
+            return num.floatValue();
+        }
+
+        @Override
+        public double getDouble(int columnIndex) {
+            Number num = (Number) mRows[mPos].get(columnIndex);
+            return num.doubleValue();
+        }
+
+        @Override
+        public boolean isNull(int column) {
+            return false;
+        }
+
+        public boolean hadCalledOnChange() {
+            return mHadCalledOnChange;
+        }
+
+        // the following are protected methods
+        @Override
+        protected void checkPosition() {
+            super.checkPosition();
+        }
+
+        @Override
+        protected Object getUpdatedField(int columnIndex) {
+            return super.getUpdatedField(columnIndex);
+        }
+
+        @Override
+        protected boolean isFieldUpdated(int columnIndex) {
+            return super.isFieldUpdated(columnIndex);
+        }
+
+        @Override
+        protected void onChange(boolean selfChange) {
+            super.onChange(selfChange);
+            mHadCalledOnChange = true;
+        }
+    }
+
+    private class MockContentObserver extends ContentObserver {
+        public boolean mHadCalledOnChange;
+
+        public MockContentObserver() {
+            super(null);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            super.onChange(selfChange);
+            mHadCalledOnChange = true;
+            synchronized(mLockObj) {
+                mLockObj.notify();
+            }
+        }
+
+        @Override
+        public boolean deliverSelfNotifications() {
+            return true;
+        }
+
+        public boolean hadCalledOnChange() {
+            return mHadCalledOnChange;
+        }
+    }
+
+    private class MockDataSetObserver extends DataSetObserver {
+        private boolean mHadCalledOnChanged;
+        private boolean mHadCalledOnInvalid;
+
+        @Override
+        public void onChanged() {
+            super.onChanged();
+            mHadCalledOnChanged = true;
+        }
+
+        @Override
+        public void onInvalidated() {
+            super.onInvalidated();
+            mHadCalledOnInvalid = true;
+        }
+
+        public boolean hadCalledOnChanged() {
+            return mHadCalledOnChanged;
+        }
+
+        public boolean hadCalledOnInvalid() {
+            return mHadCalledOnInvalid;
+        }
+    }
+}