upload android base code part7
This commit is contained in:
parent
4e516ec6ed
commit
841ae54672
25229 changed files with 1709508 additions and 0 deletions
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!--
|
||||
To run this test package, install it and the NotesList application to a device or emulator and
|
||||
then run
|
||||
adb shell am instrument -w com.example.android.notepad.tests/android.test.InstrumentationTestRunner
|
||||
-->
|
||||
<!--
|
||||
The Android package name differs from the package ID of the code. The code package ID
|
||||
'com.example.android.notepad' allows the test code to use declarations from the application
|
||||
under test, while the Android package name identifies this as a separate test package.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.android.notepad.tests"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
<!--
|
||||
The application element indicates that this package must be linked against the library
|
||||
android.test.runner, which is not part of the normal link path. The library contains
|
||||
code for test cases.
|
||||
-->
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner" />
|
||||
</application>
|
||||
<!--
|
||||
The instrumentation element tells Android to use instrumentation to run this package.
|
||||
The target Android package 'com.example.android.notepad' is loaded along with the
|
||||
test package 'com.example.android.notepad.tests'. Android then starts the class
|
||||
'android.test.InstrumentationTestRunner', which loads the test case classes in the package.
|
||||
-->
|
||||
<instrumentation android:name="android.test.InstrumentationTestRunner"
|
||||
android:targetPackage="com.example.android.notepad"
|
||||
android:label="Tests for com.example.android.notepad"/>
|
||||
<uses-sdk android:minSdkVersion="10"></uses-sdk>
|
||||
</manifest>
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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 com.example.android.notepad;
|
||||
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import com.example.android.notepad.NotesList;
|
||||
|
||||
/**
|
||||
* Make sure that the main launcher activity opens up properly, which will be
|
||||
* verified by {@link #testActivityTestCaseSetUpProperly}.
|
||||
*/
|
||||
public class NotePadActivityTest extends ActivityInstrumentationTestCase2<NotesList> {
|
||||
|
||||
/**
|
||||
* Creates an {@link ActivityInstrumentationTestCase2} for the {@link NotesList} activity.
|
||||
*/
|
||||
public NotePadActivityTest() {
|
||||
super(NotesList.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the activity under test can be launched.
|
||||
*/
|
||||
public void testActivityTestCaseSetUpProperly() {
|
||||
assertNotNull("activity should be launched successfully", getActivity());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,839 @@
|
|||
/*
|
||||
* Copyright (C) 2010 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.example.android.notepad;
|
||||
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.test.ProviderTestCase2;
|
||||
import android.test.mock.MockContentResolver;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
/*
|
||||
*/
|
||||
/**
|
||||
* This class tests the content provider for the Note Pad sample application.
|
||||
*
|
||||
* To learn how to run an entire test package or one of its classes, please see
|
||||
* "Testing in Eclipse, with ADT" or "Testing in Other IDEs" in the Developer Guide.
|
||||
*/
|
||||
public class NotePadProviderTest extends ProviderTestCase2<NotePadProvider> {
|
||||
|
||||
// A URI that the provider does not offer, for testing error handling.
|
||||
private static final Uri INVALID_URI =
|
||||
Uri.withAppendedPath(NotePad.Notes.CONTENT_URI, "invalid");
|
||||
|
||||
// Contains a reference to the mocked content resolver for the provider under test.
|
||||
private MockContentResolver mMockResolver;
|
||||
|
||||
// Contains an SQLite database, used as test data
|
||||
private SQLiteDatabase mDb;
|
||||
|
||||
// Contains the test data, as an array of NoteInfo instances.
|
||||
private final NoteInfo[] TEST_NOTES = {
|
||||
new NoteInfo("Note0", "This is note 0"),
|
||||
new NoteInfo("Note1", "This is note 1"),
|
||||
new NoteInfo("Note2", "This is note 2"),
|
||||
new NoteInfo("Note3", "This is note 3"),
|
||||
new NoteInfo("Note4", "This is note 4"),
|
||||
new NoteInfo("Note5", "This is note 5"),
|
||||
new NoteInfo("Note6", "This is note 6"),
|
||||
new NoteInfo("Note7", "This is note 7"),
|
||||
new NoteInfo("Note8", "This is note 8"),
|
||||
new NoteInfo("Note9", "This is note 9") };
|
||||
|
||||
// Number of milliseconds in one day (milliseconds * seconds * minutes * hours)
|
||||
private static final long ONE_DAY_MILLIS = 1000 * 60 * 60 * 24;
|
||||
|
||||
// Number of milliseconds in one week
|
||||
private static final long ONE_WEEK_MILLIS = ONE_DAY_MILLIS * 7;
|
||||
|
||||
// Creates a calendar object equal to January 1, 2010 at 12 midnight
|
||||
private static final GregorianCalendar TEST_CALENDAR =
|
||||
new GregorianCalendar(2010, Calendar.JANUARY, 1, 0, 0, 0);
|
||||
|
||||
// Stores a timestamp value, set to an arbitrary starting point
|
||||
private final static long START_DATE = TEST_CALENDAR.getTimeInMillis();
|
||||
|
||||
// Sets a MIME type filter, used to test provider methods that return more than one MIME type
|
||||
// for a particular note. The filter will retrieve any MIME types supported for the content URI.
|
||||
private final static String MIME_TYPES_ALL = "*/*";
|
||||
|
||||
// Sets a MIME type filter, used to test provider methods that return more than one MIME type
|
||||
// for a particular note. The filter is nonsense, so it will not retrieve any MIME types.
|
||||
private final static String MIME_TYPES_NONE = "qwer/qwer";
|
||||
|
||||
// Sets a MIME type filter for plain text, used to the provider's methods that only handle
|
||||
// plain text
|
||||
private final static String MIME_TYPE_TEXT = "text/plain";
|
||||
|
||||
/*
|
||||
* Constructor for the test case class.
|
||||
* Calls the super constructor with the class name of the provider under test and the
|
||||
* authority name of the provider.
|
||||
*/
|
||||
public NotePadProviderTest() {
|
||||
super(NotePadProvider.class, NotePad.AUTHORITY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets up the test environment before each test method. Creates a mock content resolver,
|
||||
* gets the provider under test, and creates a new database for the provider.
|
||||
*/
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
// Calls the base class implementation of this method.
|
||||
super.setUp();
|
||||
|
||||
// Gets the resolver for this test.
|
||||
mMockResolver = getMockContentResolver();
|
||||
|
||||
/*
|
||||
* Gets a handle to the database underlying the provider. Gets the provider instance
|
||||
* created in super.setUp(), gets the DatabaseOpenHelper for the provider, and gets
|
||||
* a database object from the helper.
|
||||
*/
|
||||
mDb = getProvider().getOpenHelperForTest().getWritableDatabase();
|
||||
}
|
||||
|
||||
/*
|
||||
* This method is called after each test method, to clean up the current fixture. Since
|
||||
* this sample test case runs in an isolated context, no cleanup is necessary.
|
||||
*/
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets up test data.
|
||||
* The test data is in an SQL database. It is created in setUp() without any data,
|
||||
* and populated in insertData if necessary.
|
||||
*/
|
||||
private void insertData() {
|
||||
// Creates an instance of the ContentValues map type expected by database insertions
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
// Sets up test data
|
||||
for (int index = 0; index < TEST_NOTES.length; index++) {
|
||||
|
||||
// Set the creation and modification date for the note
|
||||
TEST_NOTES[index].setCreationDate(START_DATE + (index * ONE_DAY_MILLIS));
|
||||
TEST_NOTES[index].setModificationDate(START_DATE + (index * ONE_WEEK_MILLIS));
|
||||
|
||||
// Adds a record to the database.
|
||||
mDb.insertOrThrow(
|
||||
NotePad.Notes.TABLE_NAME, // the table name for the insert
|
||||
NotePad.Notes.COLUMN_NAME_TITLE, // column set to null if empty values map
|
||||
TEST_NOTES[index].getContentValues() // the values map to insert
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests the provider's publicly available URIs. If the URI is not one that the provider
|
||||
* understands, the provider should throw an exception. It also tests the provider's getType()
|
||||
* method for each URI, which should return the MIME type associated with the URI.
|
||||
*/
|
||||
public void testUriAndGetType() {
|
||||
// Tests the MIME type for the notes table URI.
|
||||
String mimeType = mMockResolver.getType(NotePad.Notes.CONTENT_URI);
|
||||
assertEquals(NotePad.Notes.CONTENT_TYPE, mimeType);
|
||||
|
||||
// Tests the MIME type for the live folder URI.
|
||||
mimeType = mMockResolver.getType(NotePad.Notes.LIVE_FOLDER_URI);
|
||||
assertEquals(NotePad.Notes.CONTENT_TYPE, mimeType);
|
||||
|
||||
// Creates a URI with a pattern for note ids. The id doesn't have to exist.
|
||||
Uri noteIdUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE, 1);
|
||||
|
||||
// Gets the note ID URI MIME type.
|
||||
mimeType = mMockResolver.getType(noteIdUri);
|
||||
assertEquals(NotePad.Notes.CONTENT_ITEM_TYPE, mimeType);
|
||||
|
||||
// Tests an invalid URI. This should throw an IllegalArgumentException.
|
||||
mimeType = mMockResolver.getType(INVALID_URI);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests the provider's stream MIME types returned by getStreamTypes(). If the provider supports
|
||||
* stream data for the URI, the MIME type is returned. Otherwise, the provider returns null.
|
||||
*/
|
||||
public void testGetStreamTypes() {
|
||||
|
||||
// Tests the notes table URI. This should return null, since the content provider does
|
||||
// not provide a stream MIME type for multiple notes.
|
||||
assertNull(mMockResolver.getStreamTypes(NotePad.Notes.CONTENT_URI, MIME_TYPES_ALL));
|
||||
|
||||
// Tests the live folders URI. This should return null, since the content provider does not
|
||||
// provide a stream MIME type for multiple notes.
|
||||
assertNull(mMockResolver.getStreamTypes(NotePad.Notes.LIVE_FOLDER_URI, MIME_TYPES_ALL));
|
||||
|
||||
/*
|
||||
* Tests the note id URI for a single note, using _ID value "1" which is a valid ID. Uses a
|
||||
* valid MIME type filter that will return all the supported MIME types for a content URI.
|
||||
* The result should be "text/plain".
|
||||
*/
|
||||
|
||||
// Constructs the note id URI
|
||||
Uri testUri = Uri.withAppendedPath(NotePad.Notes.CONTENT_ID_URI_BASE, "1");
|
||||
|
||||
// Gets the MIME types for the URI, with the filter that selects all MIME types.
|
||||
String mimeType[] = mMockResolver.getStreamTypes(testUri, MIME_TYPES_ALL);
|
||||
|
||||
// Tests that the result is not null and is equal to the expected value. Also tests that
|
||||
// only one MIME type is returned.
|
||||
assertNotNull(mimeType);
|
||||
assertEquals(mimeType[0],"text/plain");
|
||||
assertEquals(mimeType.length,1);
|
||||
|
||||
/*
|
||||
* Tests with the same URI but with a filter that should not return any URIs.
|
||||
*/
|
||||
mimeType = mMockResolver.getStreamTypes(testUri, MIME_TYPES_NONE);
|
||||
assertNull(mimeType);
|
||||
|
||||
/*
|
||||
* Tests with a URI that should not have any associated stream MIME types, but with a
|
||||
* filter that returns all types. The result should still be null.
|
||||
*/
|
||||
mimeType = mMockResolver.getStreamTypes(NotePad.Notes.CONTENT_URI, MIME_TYPES_ALL);
|
||||
assertNull(mimeType);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests the provider's public API for opening a read-only pipe of data for a note ID URI
|
||||
* and MIME type filter matching "text/plain".
|
||||
* This method throws a FileNotFoundException if the URI isn't for a note ID or the MIME type
|
||||
* filter isn't "text/plain". It throws an IOException if it can't close a file descriptor.
|
||||
*/
|
||||
public void testOpenTypedAssetFile() throws FileNotFoundException, IOException {
|
||||
|
||||
// A URI to contain a note ID content URI.
|
||||
Uri testNoteIdUri;
|
||||
|
||||
// A handle for the file descriptor returned by openTypedAssetFile().
|
||||
AssetFileDescriptor testAssetDescriptor;
|
||||
|
||||
// Inserts data into the provider, so that the note ID URI will be recognized.
|
||||
insertData();
|
||||
|
||||
// Constructs a URI with a note ID of 1. This matches the note ID URI pattern that
|
||||
// openTypedAssetFile can handle.
|
||||
testNoteIdUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE, 1);
|
||||
|
||||
// Opens the pipe. The opts argument is for passing options from a caller to the provider,
|
||||
// but the NotePadProvider does not use it.
|
||||
testAssetDescriptor = mMockResolver.openTypedAssetFileDescriptor(
|
||||
testNoteIdUri, // the URI for a single note. The pipe points to this
|
||||
// note's data
|
||||
MIME_TYPE_TEXT, // a MIME type of "text/plain"
|
||||
null // the "opts" argument
|
||||
);
|
||||
|
||||
// Gets the parcel file handle from the asset file handle.
|
||||
ParcelFileDescriptor testParcelDescriptor = testAssetDescriptor.getParcelFileDescriptor();
|
||||
|
||||
// Gets the file handle from the asset file handle.
|
||||
FileDescriptor testDescriptor = testAssetDescriptor.getFileDescriptor();
|
||||
|
||||
// Tests that the asset file handle is not null.
|
||||
assertNotNull(testAssetDescriptor);
|
||||
|
||||
// Tests that the parcel file handle is not null.
|
||||
assertNotNull(testParcelDescriptor);
|
||||
|
||||
// Tests that the file handle is not null.
|
||||
assertNotNull(testDescriptor);
|
||||
|
||||
// Tests that the file handle is valid.
|
||||
assertTrue(testDescriptor.valid());
|
||||
|
||||
// Closes the file handles.
|
||||
testParcelDescriptor.close();
|
||||
testAssetDescriptor.close();
|
||||
|
||||
/*
|
||||
* Changes the URI to a notes URI for multiple notes, and re-test. This should fail, since
|
||||
* the provider does not support this type of URI. A FileNotFound exception is expected,
|
||||
* so call fail() if it does *not* occur.
|
||||
*/
|
||||
try {
|
||||
testAssetDescriptor = mMockResolver.openTypedAssetFileDescriptor(
|
||||
NotePad.Notes.CONTENT_URI,
|
||||
MIME_TYPE_TEXT,
|
||||
null
|
||||
);
|
||||
fail();
|
||||
} catch (FileNotFoundException e) {
|
||||
// continue
|
||||
}
|
||||
|
||||
/*
|
||||
* Changes back to the note ID URI, but changes the MIME type filter to one that is not
|
||||
* supported by the provider. This should also fail, since the provider will only open a
|
||||
* pipe for MIME type "text/plain". A FileNotFound exception is expected, so calls
|
||||
* fail() if it does *not* occur.
|
||||
*/
|
||||
|
||||
try {
|
||||
testAssetDescriptor = mMockResolver.openTypedAssetFileDescriptor(
|
||||
testNoteIdUri,
|
||||
MIME_TYPES_NONE,
|
||||
null
|
||||
);
|
||||
fail();
|
||||
} catch (FileNotFoundException e) {
|
||||
// continue
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests the provider's method for actually returning writing data into a pipe. The method is
|
||||
* writeDataToPipe, but this method is not called directly. Instead, a caller invokes
|
||||
* openTypedAssetFile(). That method uses ContentProvider.openPipeHelper(), which has as one of
|
||||
* its arguments a ContentProvider.PipeDataWriter object that must actually put the data into
|
||||
* the pipe. PipeDataWriter is an interface, not a class, so it must be implemented.
|
||||
*
|
||||
* The NotePadProvider class itself implements the "ContentProvider.PipeDataWriter, which means
|
||||
* that it supplies the interface's only method, writeDataToPipe(). In effect, a call to
|
||||
* openTypedAssetFile() calls writeDataToPipe().
|
||||
*
|
||||
* The test of writeDataToPipe() is separate from other tests of openTypedAssetFile() for the
|
||||
* sake of clarity.
|
||||
*/
|
||||
public void testWriteDataToPipe() throws FileNotFoundException {
|
||||
|
||||
// A string array to hold the incoming data
|
||||
String[] inputData = {"","",""};
|
||||
|
||||
// A URI for a note ID.
|
||||
Uri noteIdUri;
|
||||
|
||||
// A Cursor to contain the retrieved note.
|
||||
Cursor noteIdCursor;
|
||||
|
||||
// An AssetFileDescriptor for the pipe.
|
||||
AssetFileDescriptor noteIdAssetDescriptor;
|
||||
|
||||
// The ParcelFileDescriptor in the AssetFileDescriptor
|
||||
ParcelFileDescriptor noteIdParcelDescriptor;
|
||||
|
||||
// Inserts test data into the provider.
|
||||
insertData();
|
||||
|
||||
// Creates note ID URI for a note that should now be in the provider.
|
||||
noteIdUri = ContentUris.withAppendedId(
|
||||
NotePad.Notes.CONTENT_ID_URI_BASE, // The base pattern for a note ID URI
|
||||
1 // Sets the URI to point to record ID 1 in the
|
||||
// provider
|
||||
);
|
||||
|
||||
// Gets a Cursor for the note.
|
||||
noteIdCursor = mMockResolver.query(
|
||||
noteIdUri, // the URI for the note ID we want to retrieve
|
||||
null, // no projection, retrieve all the columns
|
||||
null, // no WHERE clause
|
||||
null, // no WHERE arguments
|
||||
null // default sort order
|
||||
);
|
||||
|
||||
// Checks that the call worked.
|
||||
// a) Checks that the cursor is not null
|
||||
// b) Checks that it contains a single record
|
||||
assertNotNull(noteIdCursor);
|
||||
assertEquals(1,noteIdCursor.getCount());
|
||||
|
||||
// Opens the pipe that will contain the data.
|
||||
noteIdAssetDescriptor = mMockResolver.openTypedAssetFileDescriptor(
|
||||
noteIdUri, // the URI of the note that will provide the data
|
||||
MIME_TYPE_TEXT, // the "text/plain" MIME type
|
||||
null // no other options
|
||||
);
|
||||
|
||||
// Checks that the call worked.
|
||||
// a) checks that the AssetFileDescriptor is not null
|
||||
// b) gets its ParcelFileDescriptor
|
||||
// c) checks that the ParcelFileDescriptor is not null
|
||||
assertNotNull(noteIdAssetDescriptor);
|
||||
noteIdParcelDescriptor = noteIdAssetDescriptor.getParcelFileDescriptor();
|
||||
assertNotNull(noteIdParcelDescriptor);
|
||||
|
||||
// Gets a File Reader that can read the pipe.
|
||||
FileReader fIn = new FileReader(noteIdParcelDescriptor.getFileDescriptor());
|
||||
|
||||
// Gets a buffered reader wrapper for the File Reader. This allows reading line by line.
|
||||
BufferedReader bIn = new BufferedReader(fIn);
|
||||
|
||||
/*
|
||||
* The pipe should contain three lines: The note's title, an empty line, and the note's
|
||||
* contents. The following code reads and stores these three lines.
|
||||
*/
|
||||
for (int index = 0; index < inputData.length; index++) {
|
||||
try {
|
||||
inputData[index] = bIn.readLine();
|
||||
} catch (IOException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
// Asserts that the first record in the provider (written from TEST_NOTES[0]) has the same
|
||||
// note title as the first line retrieved from the pipe.
|
||||
assertEquals(TEST_NOTES[0].title, inputData[0]);
|
||||
|
||||
// Asserts that the first record in the provider (written from TEST_NOTES[0]) has the same
|
||||
// note contents as the third line retrieved from the pipe.
|
||||
assertEquals(TEST_NOTES[0].note, inputData[2]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests the provider's public API for querying data in the table, using the URI for
|
||||
* a dataset of records.
|
||||
*/
|
||||
public void testQueriesOnNotesUri() {
|
||||
// Defines a projection of column names to return for a query
|
||||
final String[] TEST_PROJECTION = {
|
||||
NotePad.Notes.COLUMN_NAME_TITLE,
|
||||
NotePad.Notes.COLUMN_NAME_NOTE,
|
||||
NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE
|
||||
};
|
||||
|
||||
// Defines a selection column for the query. When the selection columns are passed
|
||||
// to the query, the selection arguments replace the placeholders.
|
||||
final String TITLE_SELECTION = NotePad.Notes.COLUMN_NAME_TITLE + " = " + "?";
|
||||
|
||||
// Defines the selection columns for a query.
|
||||
final String SELECTION_COLUMNS =
|
||||
TITLE_SELECTION + " OR " + TITLE_SELECTION + " OR " + TITLE_SELECTION;
|
||||
|
||||
// Defines the arguments for the selection columns.
|
||||
final String[] SELECTION_ARGS = { "Note0", "Note1", "Note5" };
|
||||
|
||||
// Defines a query sort order
|
||||
final String SORT_ORDER = NotePad.Notes.COLUMN_NAME_TITLE + " ASC";
|
||||
|
||||
// Query subtest 1.
|
||||
// If there are no records in the table, the returned cursor from a query should be empty.
|
||||
Cursor cursor = mMockResolver.query(
|
||||
NotePad.Notes.CONTENT_URI, // the URI for the main data table
|
||||
null, // no projection, get all columns
|
||||
null, // no selection criteria, get all records
|
||||
null, // no selection arguments
|
||||
null // use default sort order
|
||||
);
|
||||
|
||||
// Asserts that the returned cursor contains no records
|
||||
assertEquals(0, cursor.getCount());
|
||||
|
||||
// Query subtest 2.
|
||||
// If the table contains records, the returned cursor from a query should contain records.
|
||||
|
||||
// Inserts the test data into the provider's underlying data source
|
||||
insertData();
|
||||
|
||||
// Gets all the columns for all the rows in the table
|
||||
cursor = mMockResolver.query(
|
||||
NotePad.Notes.CONTENT_URI, // the URI for the main data table
|
||||
null, // no projection, get all columns
|
||||
null, // no selection criteria, get all records
|
||||
null, // no selection arguments
|
||||
null // use default sort order
|
||||
);
|
||||
|
||||
// Asserts that the returned cursor contains the same number of rows as the size of the
|
||||
// test data array.
|
||||
assertEquals(TEST_NOTES.length, cursor.getCount());
|
||||
|
||||
// Query subtest 3.
|
||||
// A query that uses a projection should return a cursor with the same number of columns
|
||||
// as the projection, with the same names, in the same order.
|
||||
Cursor projectionCursor = mMockResolver.query(
|
||||
NotePad.Notes.CONTENT_URI, // the URI for the main data table
|
||||
TEST_PROJECTION, // get the title, note, and mod date columns
|
||||
null, // no selection columns, get all the records
|
||||
null, // no selection criteria
|
||||
null // use default the sort order
|
||||
);
|
||||
|
||||
// Asserts that the number of columns in the cursor is the same as in the projection
|
||||
assertEquals(TEST_PROJECTION.length, projectionCursor.getColumnCount());
|
||||
|
||||
// Asserts that the names of the columns in the cursor and in the projection are the same.
|
||||
// This also verifies that the names are in the same order.
|
||||
assertEquals(TEST_PROJECTION[0], projectionCursor.getColumnName(0));
|
||||
assertEquals(TEST_PROJECTION[1], projectionCursor.getColumnName(1));
|
||||
assertEquals(TEST_PROJECTION[2], projectionCursor.getColumnName(2));
|
||||
|
||||
// Query subtest 4
|
||||
// A query that uses selection criteria should return only those rows that match the
|
||||
// criteria. Use a projection so that it's easy to get the data in a particular column.
|
||||
projectionCursor = mMockResolver.query(
|
||||
NotePad.Notes.CONTENT_URI, // the URI for the main data table
|
||||
TEST_PROJECTION, // get the title, note, and mod date columns
|
||||
SELECTION_COLUMNS, // select on the title column
|
||||
SELECTION_ARGS, // select titles "Note0", "Note1", or "Note5"
|
||||
SORT_ORDER // sort ascending on the title column
|
||||
);
|
||||
|
||||
// Asserts that the cursor has the same number of rows as the number of selection arguments
|
||||
assertEquals(SELECTION_ARGS.length, projectionCursor.getCount());
|
||||
|
||||
int index = 0;
|
||||
|
||||
while (projectionCursor.moveToNext()) {
|
||||
|
||||
// Asserts that the selection argument at the current index matches the value of
|
||||
// the title column (column 0) in the current record of the cursor
|
||||
assertEquals(SELECTION_ARGS[index], projectionCursor.getString(0));
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
// Asserts that the index pointer is now the same as the number of selection arguments, so
|
||||
// that the number of arguments tested is exactly the same as the number of rows returned.
|
||||
assertEquals(SELECTION_ARGS.length, index);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests queries against the provider, using the note id URI. This URI encodes a single
|
||||
* record ID. The provider should only return 0 or 1 record.
|
||||
*/
|
||||
public void testQueriesOnNoteIdUri() {
|
||||
// Defines the selection column for a query. The "?" is replaced by entries in the
|
||||
// selection argument array
|
||||
final String SELECTION_COLUMNS = NotePad.Notes.COLUMN_NAME_TITLE + " = " + "?";
|
||||
|
||||
// Defines the argument for the selection column.
|
||||
final String[] SELECTION_ARGS = { "Note1" };
|
||||
|
||||
// A sort order for the query.
|
||||
final String SORT_ORDER = NotePad.Notes.COLUMN_NAME_TITLE + " ASC";
|
||||
|
||||
// Creates a projection includes the note id column, so that note id can be retrieved.
|
||||
final String[] NOTE_ID_PROJECTION = {
|
||||
NotePad.Notes._ID, // The Notes class extends BaseColumns,
|
||||
// which includes _ID as the column name for the
|
||||
// record's id in the data model
|
||||
NotePad.Notes.COLUMN_NAME_TITLE}; // The note's title
|
||||
|
||||
// Query subtest 1.
|
||||
// Tests that a query against an empty table returns null.
|
||||
|
||||
// Constructs a URI that matches the provider's notes id URI pattern, using an arbitrary
|
||||
// value of 1 as the note ID.
|
||||
Uri noteIdUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE, 1);
|
||||
|
||||
// Queries the table with the notes ID URI. This should return an empty cursor.
|
||||
Cursor cursor = mMockResolver.query(
|
||||
noteIdUri, // URI pointing to a single record
|
||||
null, // no projection, get all the columns for each record
|
||||
null, // no selection criteria, get all the records in the table
|
||||
null, // no need for selection arguments
|
||||
null // default sort, by ascending title
|
||||
);
|
||||
|
||||
// Asserts that the cursor is null.
|
||||
assertEquals(0,cursor.getCount());
|
||||
|
||||
// Query subtest 2.
|
||||
// Tests that a query against a table containing records returns a single record whose ID
|
||||
// is the one requested in the URI provided.
|
||||
|
||||
// Inserts the test data into the provider's underlying data source.
|
||||
insertData();
|
||||
|
||||
// Queries the table using the URI for the full table.
|
||||
cursor = mMockResolver.query(
|
||||
NotePad.Notes.CONTENT_URI, // the base URI for the table
|
||||
NOTE_ID_PROJECTION, // returns the ID and title columns of rows
|
||||
SELECTION_COLUMNS, // select based on the title column
|
||||
SELECTION_ARGS, // select title of "Note1"
|
||||
SORT_ORDER // sort order returned is by title, ascending
|
||||
);
|
||||
|
||||
// Asserts that the cursor contains only one row.
|
||||
assertEquals(1, cursor.getCount());
|
||||
|
||||
// Moves to the cursor's first row, and asserts that this did not fail.
|
||||
assertTrue(cursor.moveToFirst());
|
||||
|
||||
// Saves the record's note ID.
|
||||
int inputNoteId = cursor.getInt(0);
|
||||
|
||||
// Builds a URI based on the provider's content ID URI base and the saved note ID.
|
||||
noteIdUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE, inputNoteId);
|
||||
|
||||
// Queries the table using the content ID URI, which returns a single record with the
|
||||
// specified note ID, matching the selection criteria provided.
|
||||
cursor = mMockResolver.query(noteIdUri, // the URI for a single note
|
||||
NOTE_ID_PROJECTION, // same projection, get ID and title columns
|
||||
SELECTION_COLUMNS, // same selection, based on title column
|
||||
SELECTION_ARGS, // same selection arguments, title = "Note1"
|
||||
SORT_ORDER // same sort order returned, by title, ascending
|
||||
);
|
||||
|
||||
// Asserts that the cursor contains only one row.
|
||||
assertEquals(1, cursor.getCount());
|
||||
|
||||
// Moves to the cursor's first row, and asserts that this did not fail.
|
||||
assertTrue(cursor.moveToFirst());
|
||||
|
||||
// Asserts that the note ID passed to the provider is the same as the note ID returned.
|
||||
assertEquals(inputNoteId, cursor.getInt(0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests inserts into the data model.
|
||||
*/
|
||||
public void testInserts() {
|
||||
// Creates a new note instance with ID of 30.
|
||||
NoteInfo note = new NoteInfo(
|
||||
"Note30", // the note's title
|
||||
"Test inserting a note" // the note's content
|
||||
);
|
||||
|
||||
// Sets the note's creation and modification times
|
||||
note.setCreationDate(START_DATE + (10 * ONE_DAY_MILLIS));
|
||||
note.setModificationDate(START_DATE + (2 * ONE_WEEK_MILLIS));
|
||||
|
||||
// Insert subtest 1.
|
||||
// Inserts a row using the new note instance.
|
||||
// No assertion will be done. The insert() method either works or throws an Exception
|
||||
Uri rowUri = mMockResolver.insert(
|
||||
NotePad.Notes.CONTENT_URI, // the main table URI
|
||||
note.getContentValues() // the map of values to insert as a new record
|
||||
);
|
||||
|
||||
// Parses the returned URI to get the note ID of the new note. The ID is used in subtest 2.
|
||||
long noteId = ContentUris.parseId(rowUri);
|
||||
|
||||
// Does a full query on the table. Since insertData() hasn't yet been called, the
|
||||
// table should only contain the record just inserted.
|
||||
Cursor cursor = mMockResolver.query(
|
||||
NotePad.Notes.CONTENT_URI, // the main table URI
|
||||
null, // no projection, return all the columns
|
||||
null, // no selection criteria, return all the rows in the model
|
||||
null, // no selection arguments
|
||||
null // default sort order
|
||||
);
|
||||
|
||||
// Asserts that there should be only 1 record.
|
||||
assertEquals(1, cursor.getCount());
|
||||
|
||||
// Moves to the first (and only) record in the cursor and asserts that this worked.
|
||||
assertTrue(cursor.moveToFirst());
|
||||
|
||||
// Since no projection was used, get the column indexes of the returned columns
|
||||
int titleIndex = cursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_TITLE);
|
||||
int noteIndex = cursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_NOTE);
|
||||
int crdateIndex = cursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_CREATE_DATE);
|
||||
int moddateIndex = cursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE);
|
||||
|
||||
// Tests each column in the returned cursor against the data that was inserted, comparing
|
||||
// the field in the NoteInfo object to the data at the column index in the cursor.
|
||||
assertEquals(note.title, cursor.getString(titleIndex));
|
||||
assertEquals(note.note, cursor.getString(noteIndex));
|
||||
assertEquals(note.createDate, cursor.getLong(crdateIndex));
|
||||
assertEquals(note.modDate, cursor.getLong(moddateIndex));
|
||||
|
||||
// Insert subtest 2.
|
||||
// Tests that we can't insert a record whose id value already exists.
|
||||
|
||||
// Defines a ContentValues object so that the test can add a note ID to it.
|
||||
ContentValues values = note.getContentValues();
|
||||
|
||||
// Adds the note ID retrieved in subtest 1 to the ContentValues object.
|
||||
values.put(NotePad.Notes._ID, (int) noteId);
|
||||
|
||||
// Tries to insert this record into the table. This should fail and drop into the
|
||||
// catch block. If it succeeds, issue a failure message.
|
||||
try {
|
||||
rowUri = mMockResolver.insert(NotePad.Notes.CONTENT_URI, values);
|
||||
fail("Expected insert failure for existing record but insert succeeded.");
|
||||
} catch (Exception e) {
|
||||
// succeeded, so do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests deletions from the data model.
|
||||
*/
|
||||
public void testDeletes() {
|
||||
// Subtest 1.
|
||||
// Tries to delete a record from a data model that is empty.
|
||||
|
||||
// Sets the selection column to "title"
|
||||
final String SELECTION_COLUMNS = NotePad.Notes.COLUMN_NAME_TITLE + " = " + "?";
|
||||
|
||||
// Sets the selection argument "Note0"
|
||||
final String[] SELECTION_ARGS = { "Note0" };
|
||||
|
||||
// Tries to delete rows matching the selection criteria from the data model.
|
||||
int rowsDeleted = mMockResolver.delete(
|
||||
NotePad.Notes.CONTENT_URI, // the base URI of the table
|
||||
SELECTION_COLUMNS, // select based on the title column
|
||||
SELECTION_ARGS // select title = "Note0"
|
||||
);
|
||||
|
||||
// Assert that the deletion did not work. The number of deleted rows should be zero.
|
||||
assertEquals(0, rowsDeleted);
|
||||
|
||||
// Subtest 2.
|
||||
// Tries to delete an existing record. Repeats the previous subtest, but inserts data first.
|
||||
|
||||
// Inserts data into the model.
|
||||
insertData();
|
||||
|
||||
// Uses the same parameters to try to delete the row with title "Note0"
|
||||
rowsDeleted = mMockResolver.delete(
|
||||
NotePad.Notes.CONTENT_URI, // the base URI of the table
|
||||
SELECTION_COLUMNS, // same selection column, "title"
|
||||
SELECTION_ARGS // same selection arguments, title = "Note0"
|
||||
);
|
||||
|
||||
// The number of deleted rows should be 1.
|
||||
assertEquals(1, rowsDeleted);
|
||||
|
||||
// Tests that the record no longer exists. Tries to get it from the table, and
|
||||
// asserts that nothing was returned.
|
||||
|
||||
// Queries the table with the same selection column and argument used to delete the row.
|
||||
Cursor cursor = mMockResolver.query(
|
||||
NotePad.Notes.CONTENT_URI, // the base URI of the table
|
||||
null, // no projection, return all columns
|
||||
SELECTION_COLUMNS, // select based on the title column
|
||||
SELECTION_ARGS, // select title = "Note0"
|
||||
null // use the default sort order
|
||||
);
|
||||
|
||||
// Asserts that the cursor is empty since the record had already been deleted.
|
||||
assertEquals(0, cursor.getCount());
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests updates to the data model.
|
||||
*/
|
||||
public void testUpdates() {
|
||||
// Selection column for identifying a record in the data model.
|
||||
final String SELECTION_COLUMNS = NotePad.Notes.COLUMN_NAME_TITLE + " = " + "?";
|
||||
|
||||
// Selection argument for the selection column.
|
||||
final String[] selectionArgs = { "Note1" };
|
||||
|
||||
// Defines a map of column names and values
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
// Subtest 1.
|
||||
// Tries to update a record in an empty table.
|
||||
|
||||
// Sets up the update by putting the "note" column and a value into the values map.
|
||||
values.put(NotePad.Notes.COLUMN_NAME_NOTE, "Testing an update with this string");
|
||||
|
||||
// Tries to update the table
|
||||
int rowsUpdated = mMockResolver.update(
|
||||
NotePad.Notes.CONTENT_URI, // the URI of the data table
|
||||
values, // a map of the updates to do (column title and value)
|
||||
SELECTION_COLUMNS, // select based on the title column
|
||||
selectionArgs // select "title = Note1"
|
||||
);
|
||||
|
||||
// Asserts that no rows were updated.
|
||||
assertEquals(0, rowsUpdated);
|
||||
|
||||
// Subtest 2.
|
||||
// Builds the table, and then tries the update again using the same arguments.
|
||||
|
||||
// Inserts data into the model.
|
||||
insertData();
|
||||
|
||||
// Does the update again, using the same arguments as in subtest 1.
|
||||
rowsUpdated = mMockResolver.update(
|
||||
NotePad.Notes.CONTENT_URI, // The URI of the data table
|
||||
values, // the same map of updates
|
||||
SELECTION_COLUMNS, // same selection, based on the title column
|
||||
selectionArgs // same selection argument, to select "title = Note1"
|
||||
);
|
||||
|
||||
// Asserts that only one row was updated. The selection criteria evaluated to
|
||||
// "title = Note1", and the test data should only contain one row that matches that.
|
||||
assertEquals(1, rowsUpdated);
|
||||
|
||||
}
|
||||
|
||||
// A utility for converting note data to a ContentValues map.
|
||||
private static class NoteInfo {
|
||||
String title;
|
||||
String note;
|
||||
long createDate;
|
||||
long modDate;
|
||||
|
||||
/*
|
||||
* Constructor for a NoteInfo instance. This class helps create a note and
|
||||
* return its values in a ContentValues map expected by data model methods.
|
||||
* The note's id is created automatically when it is inserted into the data model.
|
||||
*/
|
||||
public NoteInfo(String t, String n) {
|
||||
title = t;
|
||||
note = n;
|
||||
createDate = 0;
|
||||
modDate = 0;
|
||||
}
|
||||
|
||||
// Sets the creation date for a test note
|
||||
public void setCreationDate(long c) {
|
||||
createDate = c;
|
||||
}
|
||||
|
||||
// Sets the modification date for a test note
|
||||
public void setModificationDate(long m) {
|
||||
modDate = m;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a ContentValues instance (a map) for this NoteInfo instance. This is useful for
|
||||
* inserting a NoteInfo into a database.
|
||||
*/
|
||||
public ContentValues getContentValues() {
|
||||
// Gets a new ContentValues object
|
||||
ContentValues v = new ContentValues();
|
||||
|
||||
// Adds map entries for the user-controlled fields in the map
|
||||
v.put(NotePad.Notes.COLUMN_NAME_TITLE, title);
|
||||
v.put(NotePad.Notes.COLUMN_NAME_NOTE, note);
|
||||
v.put(NotePad.Notes.COLUMN_NAME_CREATE_DATE, createDate);
|
||||
v.put(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE, modDate);
|
||||
return v;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue