Move some useful logic to VCardTestsBase.java
Internal issue number: 2195990
This commit is contained in:
@@ -16,32 +16,9 @@
|
|||||||
|
|
||||||
package com.android.unit_tests.vcard;
|
package com.android.unit_tests.vcard;
|
||||||
|
|
||||||
import android.content.ContentProvider;
|
|
||||||
import android.content.ContentProviderOperation;
|
|
||||||
import android.content.ContentProviderResult;
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Entity;
|
|
||||||
import android.content.EntityIterator;
|
|
||||||
import android.content.res.AssetFileDescriptor;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.CursorWindow;
|
|
||||||
import android.database.IBulkCursor;
|
|
||||||
import android.database.IContentObserver;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.IBinder;
|
|
||||||
import android.os.ParcelFileDescriptor;
|
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.pim.vcard.VCardComposer;
|
import android.pim.vcard.VCardComposer;
|
||||||
import android.pim.vcard.VCardConfig;
|
import android.pim.vcard.VCardConfig;
|
||||||
import android.pim.vcard.VCardParser;
|
|
||||||
import android.pim.vcard.VCardParser_V21;
|
|
||||||
import android.pim.vcard.VCardParser_V30;
|
|
||||||
import android.pim.vcard.exception.VCardException;
|
|
||||||
import android.provider.ContactsContract.Contacts;
|
|
||||||
import android.provider.ContactsContract.Data;
|
|
||||||
import android.provider.ContactsContract.RawContacts;
|
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Email;
|
import android.provider.ContactsContract.CommonDataKinds.Email;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Event;
|
import android.provider.ContactsContract.CommonDataKinds.Event;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Im;
|
import android.provider.ContactsContract.CommonDataKinds.Im;
|
||||||
@@ -53,102 +30,10 @@ import android.provider.ContactsContract.CommonDataKinds.Photo;
|
|||||||
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
|
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Website;
|
import android.provider.ContactsContract.CommonDataKinds.Website;
|
||||||
import android.test.mock.MockContentResolver;
|
|
||||||
import android.test.mock.MockContext;
|
|
||||||
import android.test.mock.MockCursor;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.android.unit_tests.vcard.PropertyNodesVerifier.TypeSet;
|
import com.android.unit_tests.vcard.PropertyNodesVerifier.TypeSet;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Almost a dead copy of android.test.mock.MockContentProvider, but different in that this
|
|
||||||
* class extends ContentProvider, not implementing IContentProvider,
|
|
||||||
* so that MockContentResolver is able to accept this class :(
|
|
||||||
*/
|
|
||||||
class MockContentProvider extends ContentProvider {
|
|
||||||
@Override
|
|
||||||
public boolean onCreate() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int bulkInsert(Uri url, ContentValues[] initialValues) {
|
|
||||||
throw new UnsupportedOperationException("unimplemented mock method");
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public IBulkCursor bulkQuery(Uri url, String[] projection, String selection,
|
|
||||||
String[] selectionArgs, String sortOrder, IContentObserver observer,
|
|
||||||
CursorWindow window) throws RemoteException {
|
|
||||||
throw new UnsupportedOperationException("unimplemented mock method");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public int delete(Uri url, String selection, String[] selectionArgs) {
|
|
||||||
throw new UnsupportedOperationException("unimplemented mock method");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType(Uri url) {
|
|
||||||
throw new UnsupportedOperationException("unimplemented mock method");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Uri insert(Uri url, ContentValues initialValues) {
|
|
||||||
throw new UnsupportedOperationException("unimplemented mock method");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ParcelFileDescriptor openFile(Uri url, String mode) {
|
|
||||||
throw new UnsupportedOperationException("unimplemented mock method");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AssetFileDescriptor openAssetFile(Uri uri, String mode) {
|
|
||||||
throw new UnsupportedOperationException("unimplemented mock method");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) {
|
|
||||||
throw new UnsupportedOperationException("unimplemented mock method");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
|
|
||||||
String sortOrder) {
|
|
||||||
throw new UnsupportedOperationException("unimplemented mock method");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public EntityIterator queryEntities(Uri url, String selection, String[] selectionArgs,
|
|
||||||
String sortOrder) {
|
|
||||||
throw new UnsupportedOperationException("unimplemented mock method");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int update(Uri url, ContentValues values, String selection, String[] selectionArgs) {
|
|
||||||
throw new UnsupportedOperationException("unimplemented mock method");
|
|
||||||
}
|
|
||||||
|
|
||||||
public IBinder asBinder() {
|
|
||||||
throw new UnsupportedOperationException("unimplemented mock method");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for the code related to vCard exporter, inculding vCard composer.
|
* Tests for the code related to vCard exporter, inculding vCard composer.
|
||||||
@@ -156,274 +41,9 @@ class MockContentProvider extends ContentProvider {
|
|||||||
* the result of this class will not be reliable.
|
* the result of this class will not be reliable.
|
||||||
*/
|
*/
|
||||||
public class VCardExporterTests extends VCardTestsBase {
|
public class VCardExporterTests extends VCardTestsBase {
|
||||||
private static final int V21 = 0;
|
|
||||||
private static final int V30 = 1;
|
|
||||||
|
|
||||||
private static final byte[] sPhotoByteArray =
|
private static final byte[] sPhotoByteArray =
|
||||||
VCardImporterTests.sPhotoByteArrayForComplicatedCase;
|
VCardImporterTests.sPhotoByteArrayForComplicatedCase;
|
||||||
|
|
||||||
public class ExportTestResolver extends MockContentResolver {
|
|
||||||
ExportTestProvider mProvider = new ExportTestProvider();
|
|
||||||
public ExportTestResolver() {
|
|
||||||
addProvider(VCardComposer.VCARD_TEST_AUTHORITY, mProvider);
|
|
||||||
addProvider(RawContacts.CONTENT_URI.getAuthority(), mProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContentValues buildData(String mimeType) {
|
|
||||||
return mProvider.buildData(mimeType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class MockEntityIterator implements EntityIterator {
|
|
||||||
Collection<Entity> mEntityCollection;
|
|
||||||
Iterator<Entity> mIterator;
|
|
||||||
|
|
||||||
// TODO: Support multiple vCard entries.
|
|
||||||
public MockEntityIterator(Collection<ContentValues> contentValuesCollection) {
|
|
||||||
mEntityCollection = new ArrayList<Entity>();
|
|
||||||
Entity entity = new Entity(new ContentValues());
|
|
||||||
for (ContentValues contentValues : contentValuesCollection) {
|
|
||||||
entity.addSubValue(Data.CONTENT_URI, contentValues);
|
|
||||||
}
|
|
||||||
mEntityCollection.add(entity);
|
|
||||||
mIterator = mEntityCollection.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasNext() {
|
|
||||||
return mIterator.hasNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Entity next() {
|
|
||||||
return mIterator.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset() {
|
|
||||||
mIterator = mEntityCollection.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ExportTestProvider extends MockContentProvider {
|
|
||||||
List<ContentValues> mContentValuesList = new ArrayList<ContentValues>();
|
|
||||||
public ContentValues buildData(String mimeType) {
|
|
||||||
ContentValues contentValues = new ContentValues();
|
|
||||||
contentValues.put(Data.MIMETYPE, mimeType);
|
|
||||||
mContentValuesList.add(contentValues);
|
|
||||||
return contentValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EntityIterator queryEntities(Uri uri, String selection, String[] selectionArgs,
|
|
||||||
String sortOrder) {
|
|
||||||
assert(uri != null);
|
|
||||||
assert(ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()));
|
|
||||||
final String authority = uri.getAuthority();
|
|
||||||
assert(RawContacts.CONTENT_URI.getAuthority().equals(authority));
|
|
||||||
|
|
||||||
return new MockEntityIterator(mContentValuesList);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
|
|
||||||
String sortOrder) {
|
|
||||||
assert(VCardComposer.CONTACTS_TEST_CONTENT_URI.equals(uri));
|
|
||||||
// Support multiple rows.
|
|
||||||
return new MockCursor() {
|
|
||||||
int mCurrentPosition = -1;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean moveToFirst() {
|
|
||||||
mCurrentPosition = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean moveToNext() {
|
|
||||||
if (mCurrentPosition == 0 || mCurrentPosition == -1) {
|
|
||||||
mCurrentPosition++;
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isBeforeFirst() {
|
|
||||||
return mCurrentPosition < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAfterLast() {
|
|
||||||
return mCurrentPosition > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getColumnIndex(String columnName) {
|
|
||||||
assertEquals(Contacts._ID, columnName);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInt(int columnIndex) {
|
|
||||||
assertEquals(0, columnIndex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getString(int columnIndex) {
|
|
||||||
return String.valueOf(getInt(columnIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class VCardVerificationHandler implements VCardComposer.OneEntryHandler {
|
|
||||||
final private TestCase mTestCase;
|
|
||||||
final private List<PropertyNodesVerifier> mPropertyNodesVerifierList;
|
|
||||||
final private boolean mIsV30;
|
|
||||||
// To allow duplication, use list instead of set.
|
|
||||||
// TODO: support multiple vCard entries.
|
|
||||||
final private List<String> mExpectedLineList;
|
|
||||||
final private ContactStructVerifier mContactStructVerifier;
|
|
||||||
final private int mVCardType;
|
|
||||||
int mCount;
|
|
||||||
|
|
||||||
public VCardVerificationHandler(final TestCase testCase, final int version) {
|
|
||||||
this(testCase, null, version);
|
|
||||||
}
|
|
||||||
|
|
||||||
public VCardVerificationHandler(final TestCase testCase,
|
|
||||||
ContactStructVerifier contactStructVerifier, final int version) {
|
|
||||||
mTestCase = testCase;
|
|
||||||
mPropertyNodesVerifierList = new ArrayList<PropertyNodesVerifier>();
|
|
||||||
mIsV30 = (version == V30);
|
|
||||||
mExpectedLineList = new ArrayList<String>();
|
|
||||||
mContactStructVerifier = contactStructVerifier;
|
|
||||||
mVCardType = (version == V30 ? VCardConfig.VCARD_TYPE_V30_GENERIC_UTF8
|
|
||||||
: VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
|
|
||||||
mCount = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyNodesVerifier addNewVerifier() {
|
|
||||||
PropertyNodesVerifier verifier = new PropertyNodesVerifier(mTestCase);
|
|
||||||
mPropertyNodesVerifierList.add(verifier);
|
|
||||||
verifier.addNodeWithOrder("VERSION", mIsV30 ? "3.0" : "2.1");
|
|
||||||
return verifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PropertyNodesVerifier addNewVerifierWithEmptyName() {
|
|
||||||
PropertyNodesVerifier verifier = addNewVerifier();
|
|
||||||
if (mIsV30) {
|
|
||||||
verifier.addNodeWithOrder("N", "").addNodeWithOrder("FN", "");
|
|
||||||
}
|
|
||||||
return verifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VCardVerificationHandler addExpectedLine(String line) {
|
|
||||||
mExpectedLineList.add(line);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean onInit(final Context context) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean onEntryCreated(final String vcard) {
|
|
||||||
if (!mExpectedLineList.isEmpty()) {
|
|
||||||
verifyLines(vcard);
|
|
||||||
}
|
|
||||||
verifyNodes(vcard);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyLines(final String vcard) {
|
|
||||||
final String[] lineArray = vcard.split("\\r?\\n");
|
|
||||||
final int length = lineArray.length;
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
final String line = lineArray[i];
|
|
||||||
// TODO: support multiple vcard entries.
|
|
||||||
if ("BEGIN:VCARD".equals(line) || "END:VCARD".equals(line) ||
|
|
||||||
(mIsV30 ? "VERSION:3.0" : "VERSION:2.1").equals(line)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final int index = mExpectedLineList.indexOf(line);
|
|
||||||
if (index >= 0) {
|
|
||||||
mExpectedLineList.remove(index);
|
|
||||||
} else {
|
|
||||||
mTestCase.fail("Unexpected line: " + line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!mExpectedLineList.isEmpty()) {
|
|
||||||
StringBuffer buffer = new StringBuffer();
|
|
||||||
for (String expectedLine : mExpectedLineList) {
|
|
||||||
buffer.append(expectedLine);
|
|
||||||
buffer.append("\n");
|
|
||||||
}
|
|
||||||
mTestCase.fail("Expected line(s) not found:" + buffer.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyNodes(final String vcard) {
|
|
||||||
if (mPropertyNodesVerifierList.size() == 0) {
|
|
||||||
mTestCase.fail("Too many vCard entries seems to be inserted(No."
|
|
||||||
+ mCount + " of the entries (No.1 is the first entry))");
|
|
||||||
}
|
|
||||||
PropertyNodesVerifier propertyNodesVerifier =
|
|
||||||
mPropertyNodesVerifierList.get(0);
|
|
||||||
mPropertyNodesVerifierList.remove(0);
|
|
||||||
VCardParser parser = (mIsV30 ? new VCardParser_V30(true) : new VCardParser_V21());
|
|
||||||
VNodeBuilder builder = new VNodeBuilder();
|
|
||||||
InputStream is;
|
|
||||||
try {
|
|
||||||
is = new ByteArrayInputStream(vcard.getBytes("UTF-8"));
|
|
||||||
mTestCase.assertEquals(true, parser.parse(is, null, builder));
|
|
||||||
is.close();
|
|
||||||
mTestCase.assertEquals(1, builder.vNodeList.size());
|
|
||||||
propertyNodesVerifier.verify(builder.vNodeList.get(0));
|
|
||||||
if (mContactStructVerifier != null) {
|
|
||||||
Log.d("@@@", vcard);
|
|
||||||
is = new ByteArrayInputStream(vcard.getBytes("UTF-8"));
|
|
||||||
mContactStructVerifier.verify(is, mVCardType);
|
|
||||||
is.close();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
mTestCase.fail("Unexpected IOException: " + e.getMessage());
|
|
||||||
} catch (VCardException e) {
|
|
||||||
mTestCase.fail("Unexpected VCardException: " + e.getMessage());
|
|
||||||
} finally {
|
|
||||||
mCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTerminate() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class CustomMockContext extends MockContext {
|
|
||||||
final ContentResolver mResolver;
|
|
||||||
public CustomMockContext(ContentResolver resolver) {
|
|
||||||
mResolver = resolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContentResolver getContentResolver() {
|
|
||||||
return mResolver;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//// Followings are actual tests ////
|
|
||||||
|
|
||||||
private void verifyOneComposition(ExportTestResolver resolver,
|
private void verifyOneComposition(ExportTestResolver resolver,
|
||||||
VCardVerificationHandler handler, int version) {
|
VCardVerificationHandler handler, int version) {
|
||||||
final boolean isV30 = (version == V30);
|
final boolean isV30 = (version == V30);
|
||||||
|
|||||||
@@ -16,17 +16,32 @@
|
|||||||
|
|
||||||
package com.android.unit_tests.vcard;
|
package com.android.unit_tests.vcard;
|
||||||
|
|
||||||
|
import android.content.ContentProvider;
|
||||||
import android.content.ContentProviderOperation;
|
import android.content.ContentProviderOperation;
|
||||||
import android.content.ContentProviderResult;
|
import android.content.ContentProviderResult;
|
||||||
|
import android.content.ContentResolver;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Entity;
|
||||||
|
import android.content.EntityIterator;
|
||||||
|
import android.content.res.AssetFileDescriptor;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.CursorWindow;
|
||||||
|
import android.database.IBulkCursor;
|
||||||
|
import android.database.IContentObserver;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.ParcelFileDescriptor;
|
||||||
|
import android.os.RemoteException;
|
||||||
import android.pim.vcard.EntryCommitter;
|
import android.pim.vcard.EntryCommitter;
|
||||||
|
import android.pim.vcard.VCardComposer;
|
||||||
import android.pim.vcard.VCardConfig;
|
import android.pim.vcard.VCardConfig;
|
||||||
import android.pim.vcard.VCardDataBuilder;
|
import android.pim.vcard.VCardDataBuilder;
|
||||||
import android.pim.vcard.VCardParser;
|
import android.pim.vcard.VCardParser;
|
||||||
import android.pim.vcard.VCardParser_V21;
|
import android.pim.vcard.VCardParser_V21;
|
||||||
import android.pim.vcard.VCardParser_V30;
|
import android.pim.vcard.VCardParser_V30;
|
||||||
import android.pim.vcard.exception.VCardException;
|
import android.pim.vcard.exception.VCardException;
|
||||||
|
import android.provider.ContactsContract.Contacts;
|
||||||
import android.provider.ContactsContract.Data;
|
import android.provider.ContactsContract.Data;
|
||||||
import android.provider.ContactsContract.RawContacts;
|
import android.provider.ContactsContract.RawContacts;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Email;
|
import android.provider.ContactsContract.CommonDataKinds.Email;
|
||||||
@@ -43,11 +58,15 @@ import android.provider.ContactsContract.CommonDataKinds.StructuredName;
|
|||||||
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
|
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Website;
|
import android.provider.ContactsContract.CommonDataKinds.Website;
|
||||||
import android.test.AndroidTestCase;
|
import android.test.AndroidTestCase;
|
||||||
import android.test.mock.MockContentProvider;
|
|
||||||
import android.test.mock.MockContentResolver;
|
import android.test.mock.MockContentResolver;
|
||||||
|
import android.test.mock.MockContext;
|
||||||
|
import android.test.mock.MockCursor;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -55,17 +74,112 @@ import java.util.Arrays;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Almost a dead copy of android.test.mock.MockContentProvider, but different in that this
|
||||||
|
* class extends ContentProvider, not implementing IContentProvider,
|
||||||
|
* so that MockContentResolver is able to accept this class :(
|
||||||
|
*/
|
||||||
|
class MockContentProvider extends ContentProvider {
|
||||||
|
@Override
|
||||||
|
public boolean onCreate() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int bulkInsert(Uri url, ContentValues[] initialValues) {
|
||||||
|
throw new UnsupportedOperationException("unimplemented mock method");
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public IBulkCursor bulkQuery(Uri url, String[] projection, String selection,
|
||||||
|
String[] selectionArgs, String sortOrder, IContentObserver observer,
|
||||||
|
CursorWindow window) throws RemoteException {
|
||||||
|
throw new UnsupportedOperationException("unimplemented mock method");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public int delete(Uri url, String selection, String[] selectionArgs) {
|
||||||
|
throw new UnsupportedOperationException("unimplemented mock method");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType(Uri url) {
|
||||||
|
throw new UnsupportedOperationException("unimplemented mock method");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Uri insert(Uri url, ContentValues initialValues) {
|
||||||
|
throw new UnsupportedOperationException("unimplemented mock method");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParcelFileDescriptor openFile(Uri url, String mode) {
|
||||||
|
throw new UnsupportedOperationException("unimplemented mock method");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AssetFileDescriptor openAssetFile(Uri uri, String mode) {
|
||||||
|
throw new UnsupportedOperationException("unimplemented mock method");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) {
|
||||||
|
throw new UnsupportedOperationException("unimplemented mock method");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
|
||||||
|
String sortOrder) {
|
||||||
|
throw new UnsupportedOperationException("unimplemented mock method");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public EntityIterator queryEntities(Uri url, String selection, String[] selectionArgs,
|
||||||
|
String sortOrder) {
|
||||||
|
throw new UnsupportedOperationException("unimplemented mock method");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int update(Uri url, ContentValues values, String selection, String[] selectionArgs) {
|
||||||
|
throw new UnsupportedOperationException("unimplemented mock method");
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBinder asBinder() {
|
||||||
|
throw new UnsupportedOperationException("unimplemented mock method");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomMockContext extends MockContext {
|
||||||
|
final ContentResolver mResolver;
|
||||||
|
public CustomMockContext(ContentResolver resolver) {
|
||||||
|
mResolver = resolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContentResolver getContentResolver() {
|
||||||
|
return mResolver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseClass for vCard unit tests with utility classes.
|
* BaseClass for vCard unit tests with utility classes.
|
||||||
* Please do not add each unit test here.
|
* Please do not add each unit test here.
|
||||||
*/
|
*/
|
||||||
/* package */ class VCardTestsBase extends AndroidTestCase {
|
/* package */ class VCardTestsBase extends AndroidTestCase {
|
||||||
|
public static final int V21 = 0;
|
||||||
|
public static final int V30 = 1;
|
||||||
|
|
||||||
public class ImportVerificationResolver extends MockContentResolver {
|
public class ImportVerificationResolver extends MockContentResolver {
|
||||||
ImportVerificationProvider mVerificationProvider = new ImportVerificationProvider();
|
ImportVerificationProvider mVerificationProvider = new ImportVerificationProvider();
|
||||||
@@ -137,12 +251,10 @@ import java.util.Map.Entry;
|
|||||||
fakeResultArray[i] = new ContentProviderResult(uri);
|
fakeResultArray[i] = new ContentProviderResult(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d("@@@", "size: " + size);
|
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
ContentProviderOperation operation = operations.get(i);
|
ContentProviderOperation operation = operations.get(i);
|
||||||
ContentValues contentValues = operation.resolveValueBackReferences(
|
ContentValues contentValues = operation.resolveValueBackReferences(
|
||||||
fakeResultArray, i);
|
fakeResultArray, i);
|
||||||
Log.d("@@@", convertToEasilyReadableString(contentValues));
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
ContentProviderOperation operation = operations.get(i);
|
ContentProviderOperation operation = operations.get(i);
|
||||||
@@ -175,9 +287,10 @@ import java.util.Map.Entry;
|
|||||||
for (String key: keyToBeRemoved) {
|
for (String key: keyToBeRemoved) {
|
||||||
actualContentValues.remove(key);
|
actualContentValues.remove(key);
|
||||||
}
|
}
|
||||||
|
/* for testing
|
||||||
Log.d("@@@",
|
Log.d("@@@",
|
||||||
String.format("MimeType: %s, data: %s",
|
String.format("MimeType: %s, data: %s",
|
||||||
mimeType, actualContentValues.toString()));
|
mimeType, actualContentValues.toString())); */
|
||||||
// Remove RAW_CONTACT_ID entry just for safety, since we do not care
|
// Remove RAW_CONTACT_ID entry just for safety, since we do not care
|
||||||
// how resolver-related code handles the entry in this unit test,
|
// how resolver-related code handles the entry in this unit test,
|
||||||
if (actualContentValues.containsKey(Data.RAW_CONTACT_ID)) {
|
if (actualContentValues.containsKey(Data.RAW_CONTACT_ID)) {
|
||||||
@@ -191,10 +304,11 @@ import java.util.Map.Entry;
|
|||||||
}
|
}
|
||||||
boolean checked = false;
|
boolean checked = false;
|
||||||
for (ContentValues expectedContentValues : contentValuesCollection) {
|
for (ContentValues expectedContentValues : contentValuesCollection) {
|
||||||
|
/* for testing
|
||||||
Log.d("@@@", "expected: "
|
Log.d("@@@", "expected: "
|
||||||
+ convertToEasilyReadableString(expectedContentValues));
|
+ convertToEasilyReadableString(expectedContentValues));
|
||||||
Log.d("@@@", "actual : "
|
Log.d("@@@", "actual : "
|
||||||
+ convertToEasilyReadableString(actualContentValues));
|
+ convertToEasilyReadableString(actualContentValues)); */
|
||||||
if (equalsForContentValues(expectedContentValues,
|
if (equalsForContentValues(expectedContentValues,
|
||||||
actualContentValues)) {
|
actualContentValues)) {
|
||||||
assertTrue(contentValuesCollection.remove(expectedContentValues));
|
assertTrue(contentValuesCollection.remove(expectedContentValues));
|
||||||
@@ -278,6 +392,254 @@ import java.util.Map.Entry;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ExportTestResolver extends MockContentResolver {
|
||||||
|
ExportTestProvider mProvider = new ExportTestProvider();
|
||||||
|
public ExportTestResolver() {
|
||||||
|
addProvider(VCardComposer.VCARD_TEST_AUTHORITY, mProvider);
|
||||||
|
addProvider(RawContacts.CONTENT_URI.getAuthority(), mProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContentValues buildData(String mimeType) {
|
||||||
|
return mProvider.buildData(mimeType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MockEntityIterator implements EntityIterator {
|
||||||
|
Collection<Entity> mEntityCollection;
|
||||||
|
Iterator<Entity> mIterator;
|
||||||
|
|
||||||
|
// TODO: Support multiple vCard entries.
|
||||||
|
public MockEntityIterator(Collection<ContentValues> contentValuesCollection) {
|
||||||
|
mEntityCollection = new ArrayList<Entity>();
|
||||||
|
Entity entity = new Entity(new ContentValues());
|
||||||
|
for (ContentValues contentValues : contentValuesCollection) {
|
||||||
|
entity.addSubValue(Data.CONTENT_URI, contentValues);
|
||||||
|
}
|
||||||
|
mEntityCollection.add(entity);
|
||||||
|
mIterator = mEntityCollection.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNext() {
|
||||||
|
return mIterator.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Entity next() {
|
||||||
|
return mIterator.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
mIterator = mEntityCollection.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ExportTestProvider extends MockContentProvider {
|
||||||
|
List<ContentValues> mContentValuesList = new ArrayList<ContentValues>();
|
||||||
|
public ContentValues buildData(String mimeType) {
|
||||||
|
ContentValues contentValues = new ContentValues();
|
||||||
|
contentValues.put(Data.MIMETYPE, mimeType);
|
||||||
|
mContentValuesList.add(contentValues);
|
||||||
|
return contentValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityIterator queryEntities(Uri uri, String selection, String[] selectionArgs,
|
||||||
|
String sortOrder) {
|
||||||
|
assert(uri != null);
|
||||||
|
assert(ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()));
|
||||||
|
final String authority = uri.getAuthority();
|
||||||
|
assert(RawContacts.CONTENT_URI.getAuthority().equals(authority));
|
||||||
|
|
||||||
|
return new MockEntityIterator(mContentValuesList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
|
||||||
|
String sortOrder) {
|
||||||
|
assert(VCardComposer.CONTACTS_TEST_CONTENT_URI.equals(uri));
|
||||||
|
// Support multiple rows.
|
||||||
|
return new MockCursor() {
|
||||||
|
int mCurrentPosition = -1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean moveToFirst() {
|
||||||
|
mCurrentPosition = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean moveToNext() {
|
||||||
|
if (mCurrentPosition == 0 || mCurrentPosition == -1) {
|
||||||
|
mCurrentPosition++;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBeforeFirst() {
|
||||||
|
return mCurrentPosition < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAfterLast() {
|
||||||
|
return mCurrentPosition > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColumnIndex(String columnName) {
|
||||||
|
assertEquals(Contacts._ID, columnName);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInt(int columnIndex) {
|
||||||
|
assertEquals(0, columnIndex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getString(int columnIndex) {
|
||||||
|
return String.valueOf(getInt(columnIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class VCardVerificationHandler implements VCardComposer.OneEntryHandler {
|
||||||
|
final private TestCase mTestCase;
|
||||||
|
final private List<PropertyNodesVerifier> mPropertyNodesVerifierList;
|
||||||
|
final private boolean mIsV30;
|
||||||
|
// To allow duplication, use list instead of set.
|
||||||
|
// TODO: support multiple vCard entries.
|
||||||
|
final private List<String> mExpectedLineList;
|
||||||
|
final private ContactStructVerifier mContactStructVerifier;
|
||||||
|
final private int mVCardType;
|
||||||
|
int mCount;
|
||||||
|
|
||||||
|
public VCardVerificationHandler(final TestCase testCase, final int version) {
|
||||||
|
this(testCase, null, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
public VCardVerificationHandler(final TestCase testCase,
|
||||||
|
ContactStructVerifier contactStructVerifier, final int version) {
|
||||||
|
mTestCase = testCase;
|
||||||
|
mPropertyNodesVerifierList = new ArrayList<PropertyNodesVerifier>();
|
||||||
|
mIsV30 = (version == V30);
|
||||||
|
mExpectedLineList = new ArrayList<String>();
|
||||||
|
mContactStructVerifier = contactStructVerifier;
|
||||||
|
mVCardType = (version == V30 ? VCardConfig.VCARD_TYPE_V30_GENERIC_UTF8
|
||||||
|
: VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
|
||||||
|
mCount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropertyNodesVerifier addNewVerifier() {
|
||||||
|
PropertyNodesVerifier verifier = new PropertyNodesVerifier(mTestCase);
|
||||||
|
mPropertyNodesVerifierList.add(verifier);
|
||||||
|
verifier.addNodeWithOrder("VERSION", mIsV30 ? "3.0" : "2.1");
|
||||||
|
return verifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropertyNodesVerifier addNewVerifierWithEmptyName() {
|
||||||
|
PropertyNodesVerifier verifier = addNewVerifier();
|
||||||
|
if (mIsV30) {
|
||||||
|
verifier.addNodeWithOrder("N", "").addNodeWithOrder("FN", "");
|
||||||
|
}
|
||||||
|
return verifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VCardVerificationHandler addExpectedLine(String line) {
|
||||||
|
mExpectedLineList.add(line);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onInit(final Context context) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onEntryCreated(final String vcard) {
|
||||||
|
if (!mExpectedLineList.isEmpty()) {
|
||||||
|
verifyLines(vcard);
|
||||||
|
}
|
||||||
|
verifyNodes(vcard);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyLines(final String vcard) {
|
||||||
|
final String[] lineArray = vcard.split("\\r?\\n");
|
||||||
|
final int length = lineArray.length;
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
final String line = lineArray[i];
|
||||||
|
// TODO: support multiple vcard entries.
|
||||||
|
if ("BEGIN:VCARD".equals(line) || "END:VCARD".equals(line) ||
|
||||||
|
(mIsV30 ? "VERSION:3.0" : "VERSION:2.1").equals(line)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final int index = mExpectedLineList.indexOf(line);
|
||||||
|
if (index >= 0) {
|
||||||
|
mExpectedLineList.remove(index);
|
||||||
|
} else {
|
||||||
|
mTestCase.fail("Unexpected line: " + line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!mExpectedLineList.isEmpty()) {
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
for (String expectedLine : mExpectedLineList) {
|
||||||
|
buffer.append(expectedLine);
|
||||||
|
buffer.append("\n");
|
||||||
|
}
|
||||||
|
mTestCase.fail("Expected line(s) not found:" + buffer.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyNodes(final String vcard) {
|
||||||
|
if (mPropertyNodesVerifierList.size() == 0) {
|
||||||
|
mTestCase.fail("Too many vCard entries seems to be inserted(No."
|
||||||
|
+ mCount + " of the entries (No.1 is the first entry))");
|
||||||
|
}
|
||||||
|
PropertyNodesVerifier propertyNodesVerifier =
|
||||||
|
mPropertyNodesVerifierList.get(0);
|
||||||
|
mPropertyNodesVerifierList.remove(0);
|
||||||
|
VCardParser parser = (mIsV30 ? new VCardParser_V30(true) : new VCardParser_V21());
|
||||||
|
VNodeBuilder builder = new VNodeBuilder();
|
||||||
|
InputStream is;
|
||||||
|
try {
|
||||||
|
is = new ByteArrayInputStream(vcard.getBytes("UTF-8"));
|
||||||
|
mTestCase.assertEquals(true, parser.parse(is, null, builder));
|
||||||
|
is.close();
|
||||||
|
mTestCase.assertEquals(1, builder.vNodeList.size());
|
||||||
|
propertyNodesVerifier.verify(builder.vNodeList.get(0));
|
||||||
|
if (mContactStructVerifier != null) {
|
||||||
|
Log.d("@@@", vcard);
|
||||||
|
is = new ByteArrayInputStream(vcard.getBytes("UTF-8"));
|
||||||
|
mContactStructVerifier.verify(is, mVCardType);
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
mTestCase.fail("Unexpected IOException: " + e.getMessage());
|
||||||
|
} catch (VCardException e) {
|
||||||
|
mTestCase.fail("Unexpected VCardException: " + e.getMessage());
|
||||||
|
} finally {
|
||||||
|
mCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onTerminate() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to print ContentValues whose content is printed with sorted keys.
|
* Utility method to print ContentValues whose content is printed with sorted keys.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user