diff options
Diffstat (limited to 'test-runner')
13 files changed, 323 insertions, 68 deletions
diff --git a/test-runner/src/android/test/LoaderTestCase.java b/test-runner/src/android/test/LoaderTestCase.java new file mode 100644 index 0000000..8be6590 --- /dev/null +++ b/test-runner/src/android/test/LoaderTestCase.java @@ -0,0 +1,101 @@ +/* + * 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 android.test; + +import android.content.Loader; +import android.content.Loader.OnLoadCompleteListener; +import android.os.AsyncTask; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; + +import java.util.concurrent.ArrayBlockingQueue; + +/** + * A convenience class for testing {@link Loader}s. This test case + * provides a simple way to synchronously get the result from a Loader making + * it easy to assert that the Loader returns the expected result. + */ +public class LoaderTestCase extends AndroidTestCase { + static { + // Force class loading of AsyncTask on the main thread so that it's handlers are tied to + // the main thread and responses from the worker thread get delivered on the main thread. + // The tests are run on another thread, allowing them to block waiting on a response from + // the code running on the main thread. The main thread can't block since the AysncTask + // results come in via the event loop. + new AsyncTask<Void, Void, Void>() { + @Override + protected Void doInBackground(Void... args) {return null;} + @Override + protected void onPostExecute(Void result) {} + }; + } + + /** + * Runs a Loader synchronously and returns the result of the load. The loader will + * be started, stopped, and destroyed by this method so it cannot be reused. + * + * @param loader The loader to run synchronously + * @return The result from the loader + */ + public <T> T getLoaderResultSynchronously(final Loader<T> loader) { + // The test thread blocks on this queue until the loader puts it's result in + final ArrayBlockingQueue<T> queue = new ArrayBlockingQueue<T>(1); + + // This callback runs on the "main" thread and unblocks the test thread + // when it puts the result into the blocking queue + final OnLoadCompleteListener<T> listener = new OnLoadCompleteListener<T>() { + @Override + public void onLoadComplete(Loader<T> completedLoader, T data) { + // Shut the loader down + completedLoader.unregisterListener(this); + completedLoader.stopLoading(); + completedLoader.destroy(); + + // Store the result, unblocking the test thread + queue.add(data); + } + }; + + // This handler runs on the "main" thread of the process since AsyncTask + // is documented as needing to run on the main thread and many Loaders use + // AsyncTask + final Handler mainThreadHandler = new Handler(Looper.getMainLooper()) { + @Override + public void handleMessage(Message msg) { + loader.registerListener(0, listener); + loader.startLoading(); + } + }; + + // Ask the main thread to start the loading process + mainThreadHandler.sendEmptyMessage(0); + + // Block on the queue waiting for the result of the load to be inserted + T result; + while (true) { + try { + result = queue.take(); + break; + } catch (InterruptedException e) { + throw new RuntimeException("waiting thread interrupted", e); + } + } + + return result; + } +} diff --git a/test-runner/src/android/test/ProviderTestCase.java b/test-runner/src/android/test/ProviderTestCase.java index e1172cf..74cebee 100644 --- a/test-runner/src/android/test/ProviderTestCase.java +++ b/test-runner/src/android/test/ProviderTestCase.java @@ -73,6 +73,18 @@ public abstract class ProviderTestCase<T extends ContentProvider> mResolver.addProvider(mProviderAuthority, getProvider()); } + /** + * Tears down the environment for the test fixture. + * <p> + * Calls {@link android.content.ContentProvider#shutdown()} on the + * {@link android.content.ContentProvider} represented by mProvider. + */ + @Override + protected void tearDown() throws Exception { + mProvider.shutdown(); + super.tearDown(); + } + public MockContentResolver getMockContentResolver() { return mResolver; } diff --git a/test-runner/src/android/test/ProviderTestCase2.java b/test-runner/src/android/test/ProviderTestCase2.java index 1fb5538..64d11c5 100644 --- a/test-runner/src/android/test/ProviderTestCase2.java +++ b/test-runner/src/android/test/ProviderTestCase2.java @@ -141,6 +141,18 @@ public abstract class ProviderTestCase2<T extends ContentProvider> extends Andro } /** + * Tears down the environment for the test fixture. + * <p> + * Calls {@link android.content.ContentProvider#shutdown()} on the + * {@link android.content.ContentProvider} represented by mProvider. + */ + @Override + protected void tearDown() throws Exception { + mProvider.shutdown(); + super.tearDown(); + } + + /** * Gets the {@link MockContentResolver} created by this class during initialization. You * must use the methods of this resolver to access the provider under test. * diff --git a/test-runner/src/android/test/RenamingDelegatingContext.java b/test-runner/src/android/test/RenamingDelegatingContext.java index 973b9f2..eee3ad7 100644 --- a/test-runner/src/android/test/RenamingDelegatingContext.java +++ b/test-runner/src/android/test/RenamingDelegatingContext.java @@ -21,6 +21,7 @@ import com.google.android.collect.Sets; import android.content.Context; import android.content.ContextWrapper; import android.content.ContentProvider; +import android.database.DatabaseErrorHandler; import android.database.sqlite.SQLiteDatabase; import android.os.FileUtils; import android.util.Log; @@ -148,6 +149,17 @@ public class RenamingDelegatingContext extends ContextWrapper { } @Override + public SQLiteDatabase openOrCreateDatabase(String name, + int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) { + final String internalName = renamedFileName(name); + if (!mDatabaseNames.contains(name)) { + mDatabaseNames.add(name); + mFileContext.deleteDatabase(internalName); + } + return mFileContext.openOrCreateDatabase(internalName, mode, factory, errorHandler); + } + + @Override public boolean deleteDatabase(String name) { if (mDatabaseNames.contains(name)) { mDatabaseNames.remove(name); diff --git a/test-runner/src/android/test/mock/MockContentProvider.java b/test-runner/src/android/test/mock/MockContentProvider.java index 3fd71c8..b63ff3d 100644 --- a/test-runner/src/android/test/mock/MockContentProvider.java +++ b/test-runner/src/android/test/mock/MockContentProvider.java @@ -127,6 +127,16 @@ public class MockContentProvider extends ContentProvider { throw new UnsupportedOperationException(); } + @SuppressWarnings("unused") + public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException { + return MockContentProvider.this.getStreamTypes(url, mimeTypeFilter); + } + + @SuppressWarnings("unused") + public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts) + throws RemoteException, FileNotFoundException { + return MockContentProvider.this.openTypedAssetFile(url, mimeType, opts); + } } private final InversionIContentProvider mIContentProvider = new InversionIContentProvider(); @@ -222,6 +232,14 @@ public class MockContentProvider extends ContentProvider { throw new UnsupportedOperationException("unimplemented mock method call"); } + public String[] getStreamTypes(Uri url, String mimeTypeFilter) { + throw new UnsupportedOperationException("unimplemented mock method call"); + } + + public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts) { + throw new UnsupportedOperationException("unimplemented mock method call"); + } + /** * Returns IContentProvider which calls back same methods in this class. * By overriding this class, we avoid the mechanism hidden behind ContentProvider diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java index ffd757c..c31c9cc 100644 --- a/test-runner/src/android/test/mock/MockContext.java +++ b/test-runner/src/android/test/mock/MockContext.java @@ -29,6 +29,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.AssetManager; import android.content.res.Resources; +import android.database.DatabaseErrorHandler; import android.database.sqlite.SQLiteDatabase; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; @@ -184,6 +185,12 @@ public class MockContext extends Context { } @Override + public SQLiteDatabase openOrCreateDatabase(String file, int mode, + SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) { + throw new UnsupportedOperationException(); + } + + @Override public File getDatabasePath(String name) { throw new UnsupportedOperationException(); } diff --git a/test-runner/src/android/test/mock/MockCursor.java b/test-runner/src/android/test/mock/MockCursor.java index 9b1c0ef..baa150a 100644 --- a/test-runner/src/android/test/mock/MockCursor.java +++ b/test-runner/src/android/test/mock/MockCursor.java @@ -178,36 +178,11 @@ public class MockCursor implements Cursor { } @SuppressWarnings("deprecation") - public boolean commitUpdates() { - throw new UnsupportedOperationException("unimplemented mock method"); - } - - @SuppressWarnings("deprecation") - public boolean commitUpdates(Map<? extends Long, ? extends Map<String, Object>> values) { - throw new UnsupportedOperationException("unimplemented mock method"); - } - - @SuppressWarnings("deprecation") - public boolean hasUpdates() { - throw new UnsupportedOperationException("unimplemented mock method"); - } - - @SuppressWarnings("deprecation") public void setNotificationUri(ContentResolver cr, Uri uri) { throw new UnsupportedOperationException("unimplemented mock method"); } @SuppressWarnings("deprecation") - public boolean supportsUpdates() { - throw new UnsupportedOperationException("unimplemented mock method"); - } - - @SuppressWarnings("deprecation") - public boolean deleteRow() { - throw new UnsupportedOperationException("unimplemented mock method"); - } - - @SuppressWarnings("deprecation") public void unregisterContentObserver(ContentObserver observer) { throw new UnsupportedOperationException("unimplemented mock method"); } @@ -217,48 +192,7 @@ public class MockCursor implements Cursor { throw new UnsupportedOperationException("unimplemented mock method"); } - @SuppressWarnings("deprecation") - public boolean updateBlob(int columnIndex, byte[] value) { - throw new UnsupportedOperationException("unimplemented mock method"); - } - - @SuppressWarnings("deprecation") - public boolean updateDouble(int columnIndex, double value) { - throw new UnsupportedOperationException("unimplemented mock method"); - } - - @SuppressWarnings("deprecation") - public boolean updateFloat(int columnIndex, float value) { - throw new UnsupportedOperationException("unimplemented mock method"); - } - - @SuppressWarnings("deprecation") - public boolean updateInt(int columnIndex, int value) { - throw new UnsupportedOperationException("unimplemented mock method"); - } - - @SuppressWarnings("deprecation") - public boolean updateLong(int columnIndex, long value) { - throw new UnsupportedOperationException("unimplemented mock method"); - } - - @SuppressWarnings("deprecation") - public boolean updateShort(int columnIndex, short value) { - throw new UnsupportedOperationException("unimplemented mock method"); - } - - @SuppressWarnings("deprecation") - public boolean updateString(int columnIndex, String value) { - throw new UnsupportedOperationException("unimplemented mock method"); - } - - @SuppressWarnings("deprecation") - public boolean updateToNull(int columnIndex) { - throw new UnsupportedOperationException("unimplemented mock method"); - } - - @SuppressWarnings("deprecation") - public void abortUpdates() { + public int getType(int columnIndex) { throw new UnsupportedOperationException("unimplemented mock method"); } }
\ No newline at end of file diff --git a/test-runner/src/android/test/mock/MockIContentProvider.java b/test-runner/src/android/test/mock/MockIContentProvider.java index 0be5bea..183be41 100644 --- a/test-runner/src/android/test/mock/MockIContentProvider.java +++ b/test-runner/src/android/test/mock/MockIContentProvider.java @@ -32,6 +32,7 @@ import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; +import java.io.FileNotFoundException; import java.util.ArrayList; /** @@ -102,4 +103,13 @@ public class MockIContentProvider implements IContentProvider { public IBinder asBinder() { throw new UnsupportedOperationException("unimplemented mock method"); } + + public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException { + throw new UnsupportedOperationException("unimplemented mock method"); + } + + public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts) + throws RemoteException, FileNotFoundException { + throw new UnsupportedOperationException("unimplemented mock method"); + } } diff --git a/test-runner/src/android/test/suitebuilder/TestGrouping.java b/test-runner/src/android/test/suitebuilder/TestGrouping.java index df6da70..a2b94ff 100644 --- a/test-runner/src/android/test/suitebuilder/TestGrouping.java +++ b/test-runner/src/android/test/suitebuilder/TestGrouping.java @@ -46,6 +46,8 @@ import java.util.TreeSet; */ public class TestGrouping { + private static final String LOG_TAG = "TestGrouping"; + SortedSet<Class<? extends TestCase>> testCaseClasses; public static final Comparator<Class<? extends TestCase>> SORT_BY_SIMPLE_NAME @@ -114,7 +116,7 @@ public class TestGrouping { for (String packageName : packageNames) { List<Class<? extends TestCase>> addedClasses = testCaseClassesInPackage(packageName); if (addedClasses.isEmpty()) { - Log.w("TestGrouping", "Invalid Package: '" + packageName + Log.w(LOG_TAG, "Invalid Package: '" + packageName + "' could not be found or has no tests"); } testCaseClasses.addAll(addedClasses); @@ -234,6 +236,10 @@ public class TestGrouping { } } } + Log.i(LOG_TAG, String.format( + "TestCase class %s is missing a public constructor with no parameters " + + "or a single String parameter - skipping", + aClass.getName())); return false; } } diff --git a/test-runner/tests/src/android/test/suitebuilder/TestGroupingTest.java b/test-runner/tests/src/android/test/suitebuilder/TestGroupingTest.java new file mode 100644 index 0000000..f4477d1 --- /dev/null +++ b/test-runner/tests/src/android/test/suitebuilder/TestGroupingTest.java @@ -0,0 +1,47 @@ +/* + * 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 android.test.suitebuilder; + +import java.util.List; + +import junit.framework.TestCase; + +/** + * Unit tests for {@link TestGrouping} + */ +public class TestGroupingTest extends TestCase { + + private TestGrouping mGrouping; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mGrouping = new TestGrouping(TestGrouping.SORT_BY_SIMPLE_NAME); + } + + /** + * Verifies that TestCases with no public constructor are not loaded. + * Relies on fixture classes in android.test.suitebuilder.examples.constructor + */ + public void testGetTests_noPublicConstructor() { + mGrouping.addPackagesRecursive("android.test.suitebuilder.examples.constructor"); + List<TestMethod> tests = mGrouping.getTests(); + // only the PublicConstructorTest's test method should be present + assertEquals(1, tests.size()); + assertEquals("testPublicConstructor", tests.get(0).getName()); + } +} diff --git a/test-runner/tests/src/android/test/suitebuilder/examples/constructor/NoPublicConstructorTest.java b/test-runner/tests/src/android/test/suitebuilder/examples/constructor/NoPublicConstructorTest.java new file mode 100644 index 0000000..d7909a1 --- /dev/null +++ b/test-runner/tests/src/android/test/suitebuilder/examples/constructor/NoPublicConstructorTest.java @@ -0,0 +1,35 @@ +/* + * 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 android.test.suitebuilder.examples.constructor; + +import junit.framework.TestCase; + +/** + * A {@link TestCase} which should not be loaded since it has non-public constructors with no args. + */ +public class NoPublicConstructorTest extends TestCase { + + NoPublicConstructorTest() { + } + + public NoPublicConstructorTest(String foo, String foo2) { + } + + public void testNotRun() { + fail("method in NoPublicConstructorTest run unexpectedly"); + } +} diff --git a/test-runner/tests/src/android/test/suitebuilder/examples/constructor/ProtectedConstructorTest.java b/test-runner/tests/src/android/test/suitebuilder/examples/constructor/ProtectedConstructorTest.java new file mode 100644 index 0000000..d2862fd --- /dev/null +++ b/test-runner/tests/src/android/test/suitebuilder/examples/constructor/ProtectedConstructorTest.java @@ -0,0 +1,33 @@ +/* + * 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 android.test.suitebuilder.examples.constructor; + +import junit.framework.TestCase; + +/** + * A protected constructor test case that should not be loaded. + */ +public class ProtectedConstructorTest extends TestCase { + + protected ProtectedConstructorTest() { + } + + public void testNotRun() { + fail("method in ProtectedConstructorTest run unexpectedly"); + } + +} diff --git a/test-runner/tests/src/android/test/suitebuilder/examples/constructor/PublicConstructorTest.java b/test-runner/tests/src/android/test/suitebuilder/examples/constructor/PublicConstructorTest.java new file mode 100644 index 0000000..a11e25d --- /dev/null +++ b/test-runner/tests/src/android/test/suitebuilder/examples/constructor/PublicConstructorTest.java @@ -0,0 +1,28 @@ +/* + * 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 android.test.suitebuilder.examples.constructor; + +import junit.framework.TestCase; + +/** + * A public constructor test case that should be loaded. + */ +public class PublicConstructorTest extends TestCase { + + public void testPublicConstructor() { + } +} |