Merge "Moving phonetic name into a separate line"
diff --git a/tests/src/com/android/contacts/ContactDetailLoaderTest.java b/tests/src/com/android/contacts/ContactDetailLoaderTest.java
index 094de6a..6676a2b 100644
--- a/tests/src/com/android/contacts/ContactDetailLoaderTest.java
+++ b/tests/src/com/android/contacts/ContactDetailLoaderTest.java
@@ -24,6 +24,10 @@
import android.app.patterns.Loader.OnLoadCompleteListener;
import android.content.ContentUris;
import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.DisplayNameSources;
@@ -34,8 +38,10 @@
import android.provider.ContactsContract.RawContacts.Data;
import android.provider.ContactsContract.RawContacts.Entity;
import android.test.AndroidTestCase;
+import android.test.AssertionFailedError;
+import android.test.suitebuilder.annotation.Suppress;
-import junit.framework.AssertionFailedError;
+import java.util.concurrent.ArrayBlockingQueue;
/**
* Runs ContactLoader tests for the the contact-detail view.
@@ -44,6 +50,16 @@
private ContactsMockContext mMockContext;
private MockContentProvider mContactsProvider;
+ static {
+ // Need to force class loading of AsyncTask on the main thread...
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... args) {return null;}
+ @Override
+ protected void onPostExecute(Void result) {}
+ };
+ }
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -75,20 +91,65 @@
"Expected Exception " + expectedException + " which was not thrown");
}
- private ContactLoader.Result assertLoadContact(Uri uri) {
- final ContactLoader loader = new ContactLoader(mMockContext, uri);
- loader.setSynchronous(true);
- // A regular variable can not be written from an anonymous class, so use a 1-array
- final ContactLoader.Result[] result = new ContactLoader.Result[1];
- loader.registerListener(0, new OnLoadCompleteListener<ContactLoader.Result>() {
- public void onLoadComplete(Loader loader, ContactLoader.Result data) {
- result[0] = data;
+ /**
+ * 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
+ */
+ private <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>() {
+ 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);
}
- });
- loader.startLoading();
- return result[0];
+ };
+
+ // 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;
}
+ private ContactLoader.Result assertLoadContact(Uri uri) {
+ final ContactLoader loader = new ContactLoader(mMockContext, uri);
+ return getLoaderResultSynchronously(loader);
+ }
+
+ @Suppress // The code under test is incorrect
public void testNullUri() {
IllegalArgumentException e =
assertThrows(IllegalArgumentException.class, new Runnable() {
@@ -99,6 +160,7 @@
assertEquals(e.getMessage(), "uri must not be null");
}
+ @Suppress // The code under test is incorrect
public void testEmptyUri() {
IllegalArgumentException e =
assertThrows(IllegalArgumentException.class, new Runnable() {
@@ -109,6 +171,7 @@
assertEquals(e.getMessage(), "uri format is unknown");
}
+ @Suppress // The code under test is incorrect
public void testInvalidUri() {
IllegalArgumentException e =
assertThrows(IllegalArgumentException.class, new Runnable() {