Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f16be20 authored by Daisuke Miyakawa's avatar Daisuke Miyakawa
Browse files

Enable vCard tests connect both importer/exporter tests.

Fix a bug in ContactStruct.

Internal issue number: 2195990
parent f2055570
Loading
Loading
Loading
Loading
+25 −6
Original line number Diff line number Diff line
@@ -714,7 +714,7 @@ public class ContactStruct {
            mFullName = propValue;
        } else if (propName.equals(Constants.PROPERTY_N)) {
            handleNProperty(propValueList);
        } else if (propName.equals(Constants.PROPERTY_NICKNAME)) {
        } else if (propName.equals(Constants.PROPERTY_SORT_STRING)) {
            mPhoneticFullName = propValue;
        } else if (propName.equals(Constants.PROPERTY_NICKNAME) ||
                propName.equals(Constants.ImportOnly.PROPERTY_X_NICKNAME)) {
@@ -1067,7 +1067,7 @@ public class ContactStruct {
        }
        operationList.add(builder.build());

        {
        if (!nameFieldsAreEmpty()) {
            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
            builder.withValueBackReference(StructuredName.RAW_CONTACT_ID, 0);
            builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
@@ -1078,9 +1078,15 @@ public class ContactStruct {
            builder.withValue(StructuredName.PREFIX, mPrefix);
            builder.withValue(StructuredName.SUFFIX, mSuffix);

            if (!(TextUtils.isEmpty(mPhoneticGivenName)
                    && TextUtils.isEmpty(mPhoneticFamilyName)
                    && TextUtils.isEmpty(mPhoneticMiddleName))) {
                builder.withValue(StructuredName.PHONETIC_GIVEN_NAME, mPhoneticGivenName);
                builder.withValue(StructuredName.PHONETIC_FAMILY_NAME, mPhoneticFamilyName);
                builder.withValue(StructuredName.PHONETIC_MIDDLE_NAME, mPhoneticMiddleName);
            } else if (!TextUtils.isEmpty(mPhoneticFullName)) {
                builder.withValue(StructuredName.PHONETIC_GIVEN_NAME, mPhoneticFullName);
            }

            builder.withValue(StructuredName.DISPLAY_NAME, getDisplayName());
            operationList.add(builder.build());
@@ -1249,9 +1255,9 @@ public class ContactStruct {
                        }
                    }

                    operationList.add(builder.build());
                    i++;
                }
                operationList.add(builder.build());
            }
        }

@@ -1272,6 +1278,19 @@ public class ContactStruct {
        }
    }

    private boolean nameFieldsAreEmpty() {
        return (TextUtils.isEmpty(mFamilyName)
                && TextUtils.isEmpty(mMiddleName)
                && TextUtils.isEmpty(mGivenName)
                && TextUtils.isEmpty(mPrefix)
                && TextUtils.isEmpty(mSuffix)
                && TextUtils.isEmpty(mFullName)
                && TextUtils.isEmpty(mPhoneticFamilyName)
                && TextUtils.isEmpty(mPhoneticMiddleName)
                && TextUtils.isEmpty(mPhoneticGivenName)
                && TextUtils.isEmpty(mPhoneticFullName));
    }

    public boolean isIgnorable() {
        return getDisplayName().length() == 0;
    }
+26 −7
Original line number Diff line number Diff line
@@ -53,10 +53,10 @@ import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.CommonDataKinds.Website;
import android.test.AndroidTestCase;
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;

@@ -155,7 +155,7 @@ class MockContentProvider extends ContentProvider {
 * This test class depends on vCard importer code, so if tests for vCard importer fail,
 * the result of this class will not be reliable.
 */
public class VCardExporterTests extends AndroidTestCase {
public class VCardExporterTests extends VCardTestsBase {
    private static final int V21 = 0;
    private static final int V30 = 1;

@@ -295,13 +295,23 @@ public class VCardExporterTests extends AndroidTestCase {
        // 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;
        }

@@ -381,6 +391,12 @@ public class VCardExporterTests extends AndroidTestCase {
                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) {
@@ -412,7 +428,7 @@ public class VCardExporterTests extends AndroidTestCase {
            VCardVerificationHandler handler, int version) {
        final boolean isV30 = (version == V30);

        int vcardType = (isV30 ? VCardConfig.VCARD_TYPE_V30_GENERIC_UTF8
        final int vcardType = (isV30 ? VCardConfig.VCARD_TYPE_V30_GENERIC_UTF8
                : VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
        VCardComposer composer = new VCardComposer(new CustomMockContext(resolver), vcardType);
        composer.addHandler(handler);
@@ -1277,11 +1293,14 @@ public class VCardExporterTests extends AndroidTestCase {
        ContentValues contentValues = resolver.buildData(Nickname.CONTENT_ITEM_TYPE);
        contentValues.put(Nickname.NAME, "Nicky");

        VCardVerificationHandler handler = new VCardVerificationHandler(this, V21);
        handler.addNewVerifierWithEmptyName()
            .addNodeWithOrder("X-ANDROID-CUSTOM", Nickname.CONTENT_ITEM_TYPE + ";Nicky;;;;;;;;;;;;;;");
        ContactStructVerifier verifier = new ContactStructVerifier();
        contentValues = verifier.createExpected(Nickname.CONTENT_ITEM_TYPE);
        contentValues.put(Nickname.NAME, "Nicky");

        // TODO: also test import part.
        VCardVerificationHandler handler = new VCardVerificationHandler(this, verifier, V21);
        handler.addNewVerifierWithEmptyName()
            .addNodeWithOrder("X-ANDROID-CUSTOM",
                    Nickname.CONTENT_ITEM_TYPE + ";Nicky;;;;;;;;;;;;;;");

        verifyOneComposition(resolver, handler, V21);
    }
+34 −44
Original line number Diff line number Diff line
@@ -422,19 +422,17 @@ public class VCardImporterTests extends VCardTestsBase {
    }

    public void testV21SimpleCase1_Type_Generic() throws IOException, VCardException {
        ContactStructVerifier verifier = new ContactStructVerifier(
                R.raw.v21_simple_1, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
        ContactStructVerifier verifier = new ContactStructVerifier();
        ContentValues contentValues =
            verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
        contentValues.put(StructuredName.FAMILY_NAME, "Ando");
        contentValues.put(StructuredName.GIVEN_NAME, "Roid");
        contentValues.put(StructuredName.DISPLAY_NAME, "Roid Ando");
        verifier.verify();
        verifier.verify(R.raw.v21_simple_1, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
    }

    public void testV21SimpleCase1_Type_Japanese() throws IOException, VCardException {
        ContactStructVerifier verifier = new ContactStructVerifier(
                R.raw.v21_simple_1, VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS);
        ContactStructVerifier verifier = new ContactStructVerifier();
        ContentValues contentValues =
            verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
        contentValues.put(StructuredName.FAMILY_NAME, "Ando");
@@ -442,21 +440,19 @@ public class VCardImporterTests extends VCardTestsBase {
        // If name-related strings only contains printable Ascii, the order is remained to be US's:
        // "Prefix Given Middle Family Suffix"
        contentValues.put(StructuredName.DISPLAY_NAME, "Roid Ando");
        verifier.verify();
        verifier.verify(R.raw.v21_simple_1, VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS);
    }

    public void testV21SimpleCase2() throws IOException, VCardException {
        ContactStructVerifier verifier = new ContactStructVerifier(
                R.raw.v21_simple_2, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
        ContactStructVerifier verifier = new ContactStructVerifier();
        ContentValues contentValues =
            verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
        contentValues.put(StructuredName.DISPLAY_NAME, "Ando Roid");
        verifier.verify();
        verifier.verify(R.raw.v21_simple_2, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
    }

    public void testV21SimpleCase3() throws IOException, VCardException {
        ContactStructVerifier verifier = new ContactStructVerifier(
                R.raw.v21_simple_3, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
        ContactStructVerifier verifier = new ContactStructVerifier();
        ContentValues contentValues =
            verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
        contentValues.put(StructuredName.FAMILY_NAME, "Ando");
@@ -464,7 +460,7 @@ public class VCardImporterTests extends VCardTestsBase {
        // "FN" field should be prefered since it should contain the original order intended by
        // the author of the file.
        contentValues.put(StructuredName.DISPLAY_NAME, "Ando Roid");
        verifier.verify();
        verifier.verify(R.raw.v21_simple_3, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
    }

    /**
@@ -490,8 +486,7 @@ public class VCardImporterTests extends VCardTestsBase {
     * inserts name related data.
     */
    public void testV21BackslashCase() throws IOException, VCardException {
        ContactStructVerifier verifier = new ContactStructVerifier(
                R.raw.v21_backslash, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
        ContactStructVerifier verifier = new ContactStructVerifier();
        ContentValues contentValues =
            verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
        // FAMILY_NAME is empty and removed in this test...
@@ -500,12 +495,11 @@ public class VCardImporterTests extends VCardTestsBase {
        contentValues.put(StructuredName.PREFIX, "D");
        contentValues.put(StructuredName.SUFFIX, ":E");
        contentValues.put(StructuredName.DISPLAY_NAME, "A;B\\C\\;D:E\\\\");
        verifier.verify();
        verifier.verify(R.raw.v21_backslash, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
    }

    public void testOrgBeforTitle() throws IOException, VCardException {
        ContactStructVerifier verifier = new ContactStructVerifier(
                R.raw.v21_org_before_title, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
        ContactStructVerifier verifier = new ContactStructVerifier();
        ContentValues contentValues =
            verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
        contentValues.put(StructuredName.DISPLAY_NAME, "Normal Guy");
@@ -515,12 +509,11 @@ public class VCardImporterTests extends VCardTestsBase {
        contentValues.put(Organization.DEPARTMENT, "Organization Devision Room Sheet No.");
        contentValues.put(Organization.TITLE, "Excellent Janitor");
        contentValues.put(Organization.TYPE, Organization.TYPE_WORK);
        verifier.verify();
        verifier.verify(R.raw.v21_org_before_title, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
    }

    public void testTitleBeforOrg() throws IOException, VCardException {
        ContactStructVerifier verifier = new ContactStructVerifier(
                R.raw.v21_title_before_org, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
        ContactStructVerifier verifier = new ContactStructVerifier();
        ContentValues contentValues =
            verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
        contentValues.put(StructuredName.DISPLAY_NAME, "Nice Guy");
@@ -530,7 +523,7 @@ public class VCardImporterTests extends VCardTestsBase {
        contentValues.put(Organization.DEPARTMENT, "Perfect Great Good Bad Poor");
        contentValues.put(Organization.TITLE, "Cool Title");
        contentValues.put(Organization.TYPE, Organization.TYPE_WORK);
        verifier.verify();
        verifier.verify(R.raw.v21_title_before_org, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
    }

    /**
@@ -538,8 +531,7 @@ public class VCardImporterTests extends VCardTestsBase {
     * The data contain three cases: one "PREF", no "PREF" and multiple "PREF", in each type.
     */
    public void testV21PrefToIsPrimary() throws IOException, VCardException {
        ContactStructVerifier verifier = new ContactStructVerifier(
                R.raw.v21_pref_handling, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
        ContactStructVerifier verifier = new ContactStructVerifier();
        ContentValues contentValues =
            verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
        contentValues.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
@@ -582,7 +574,7 @@ public class VCardImporterTests extends VCardTestsBase {
        contentValues.put(Organization.COMPANY, "Poetry");
        contentValues.put(Organization.TITLE, "Poet");
        contentValues.put(Organization.TYPE, Organization.TYPE_WORK);
        verifier.verify();
        verifier.verify(R.raw.v21_pref_handling, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
    }

    /**
@@ -652,8 +644,7 @@ public class VCardImporterTests extends VCardTestsBase {
     * into ContentResolver.
     */
    public void testV21ComplicatedCase() throws IOException, VCardException {
        ContactStructVerifier verifier = new ContactStructVerifier(
                R.raw.v21_complicated, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
        ContactStructVerifier verifier = new ContactStructVerifier();
        ContentValues contentValues =
            verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
        contentValues.put(StructuredName.FAMILY_NAME, "Gump");
@@ -741,7 +732,7 @@ public class VCardImporterTests extends VCardTestsBase {
        contentValues = verifier.createExpected(Website.CONTENT_ITEM_TYPE);
        contentValues.put(Website.URL, "http://www.example.com/");
        contentValues.put(Website.TYPE, Website.TYPE_HOMEPAGE);
        verifier.verify();
        verifier.verify(R.raw.v21_complicated, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
    }

    public void testV30Simple_Parsing() throws IOException, VCardException {
@@ -768,13 +759,13 @@ public class VCardImporterTests extends VCardTestsBase {
    }

    public void testV30Simple() throws IOException, VCardException {
        ContactStructVerifier verifier = new ContactStructVerifier(
                R.raw.v30_simple, VCardConfig.VCARD_TYPE_V30_GENERIC_UTF8);
        ContactStructVerifier verifier = new ContactStructVerifier();
        ContentValues contentValues =
            verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
        contentValues.put(StructuredName.FAMILY_NAME, "And");
        contentValues.put(StructuredName.GIVEN_NAME, "Roid");
        contentValues.put(StructuredName.DISPLAY_NAME, "And Roid");
        contentValues.put(StructuredName.PHONETIC_GIVEN_NAME, "android");

        contentValues = verifier.createExpected(Organization.CONTENT_ITEM_TYPE);
        contentValues.put(Organization.COMPANY, "Open");
@@ -786,7 +777,7 @@ public class VCardImporterTests extends VCardTestsBase {
        contentValues.put(Phone.LABEL, "VOICE");
        contentValues.put(Phone.NUMBER, "030-000-0000");
        contentValues.put(Phone.IS_PRIMARY, 1);
        verifier.verify();
        verifier.verify(R.raw.v30_simple, VCardConfig.VCARD_TYPE_V30_GENERIC_UTF8);
    }

    public void testV21Japanese1_Parsing() throws IOException, VCardException {
@@ -817,8 +808,10 @@ public class VCardImporterTests extends VCardTestsBase {
        verifier.verify(builder.vNodeList.get(0));
    }

    private void testV21Japanese1Common(ContactStructVerifier verifier, boolean japanese)
    private void testV21Japanese1Common(int resId, int vcardType, boolean japanese)
            throws IOException, VCardException {
        ContactStructVerifier verifier = new ContactStructVerifier();

        ContentValues contentValues =
            verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
        contentValues.put(StructuredName.FAMILY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9");
@@ -837,16 +830,16 @@ public class VCardImporterTests extends VCardTestsBase {
        contentValues.put(Phone.TYPE, Phone.TYPE_CUSTOM);
        contentValues.put(Phone.LABEL, "VOICE");
        contentValues.put(Phone.IS_PRIMARY, 1);
        verifier.verify();
        verifier.verify(resId, vcardType);
    }

    /**
     * Verifies vCard with Japanese can be parsed correctly with
     * {@link android.pim.vcard.VCardConfig#VCARD_TYPE_V21_GENERIC_UTF8}.
     */
    public void testV21Japanese1_Type_Generic_Utf8() throws IOException, VCardException {
        ContactStructVerifier verifier = new ContactStructVerifier(
                R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
        testV21Japanese1Common(verifier, false);
        testV21Japanese1Common(
                R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8, false);
    }

    /**
@@ -854,9 +847,8 @@ public class VCardImporterTests extends VCardTestsBase {
     * {@link android.pim.vcard.VCardConfig#VCARD_TYPE_V21_JAPANESE_SJIS}.
     */
    public void testV21Japanese1_Type_Japanese_Sjis() throws IOException, VCardException {
        ContactStructVerifier verifier = new ContactStructVerifier(
                R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS);
        testV21Japanese1Common(verifier, true);
        testV21Japanese1Common(
                R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS, true);
    }

    /**
@@ -865,9 +857,8 @@ public class VCardImporterTests extends VCardTestsBase {
     * since vCard 2.1 specifies the charset of each line if it contains non-Ascii.
     */
    public void testV21Japanese1_Type_Japanese_Utf8() throws IOException, VCardException {
        ContactStructVerifier verifier = new ContactStructVerifier(
                R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_JAPANESE_UTF8);
        testV21Japanese1Common(verifier, true);
        testV21Japanese1Common(
                R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_JAPANESE_UTF8, true);
    }

    public void testV21Japanese2_Parsing() throws IOException, VCardException {
@@ -910,8 +901,7 @@ public class VCardImporterTests extends VCardTestsBase {
    }

    public void testV21Japanese2_Type_Generic_Utf8() throws IOException, VCardException {
        ContactStructVerifier verifier = new ContactStructVerifier(
                R.raw.v21_japanese_2, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
        ContactStructVerifier verifier = new ContactStructVerifier();
        ContentValues contentValues =
            verifier.createExpected(StructuredName.CONTENT_ITEM_TYPE);
        contentValues.put(StructuredName.FAMILY_NAME, "\u5B89\u85E4");
@@ -940,7 +930,7 @@ public class VCardImporterTests extends VCardTestsBase {
        contentValues.put(StructuredPostal.TYPE, StructuredPostal.TYPE_HOME);
        contentValues = verifier.createExpected(Note.CONTENT_ITEM_TYPE);
        contentValues.put(Note.NOTE, "\u30E1\u30E2");
        verifier.verify();
        verifier.verify(R.raw.v21_japanese_2, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
    }

    // Following tests are old ones, though they still work fine.
+24 −17
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.test.AndroidTestCase;
import android.test.mock.MockContentProvider;
import android.test.mock.MockContentResolver;
import android.text.TextUtils;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
@@ -136,6 +137,13 @@ import java.util.Map.Entry;
                fakeResultArray[i] = new ContentProviderResult(uri);
            }

            Log.d("@@@", "size: " + size);
            for (int i = 0; i < size; i++) {
                ContentProviderOperation operation = operations.get(i);
                ContentValues contentValues = operation.resolveValueBackReferences(
                        fakeResultArray, i);
                Log.d("@@@", convertToEasilyReadableString(contentValues));
            }
            for (int i = 0; i < size; i++) {
                ContentProviderOperation operation = operations.get(i);
                ContentValues actualContentValues = operation.resolveValueBackReferences(
@@ -167,11 +175,9 @@ import java.util.Map.Entry;
                    for (String key: keyToBeRemoved) {
                        actualContentValues.remove(key);
                    }
                    /* For testing
                    Log.d("@@@",
                            String.format("MimeType: %s, data: %s",
                                    mimeType, actualContentValues.toString()));
                     */
                    // Remove RAW_CONTACT_ID entry just for safety, since we do not care
                    // how resolver-related code handles the entry in this unit test,
                    if (actualContentValues.containsKey(Data.RAW_CONTACT_ID)) {
@@ -179,18 +185,16 @@ import java.util.Map.Entry;
                    }
                    final Collection<ContentValues> contentValuesCollection =
                        mMimeTypeToExpectedContentValues.get(mimeType);
                    if (contentValuesCollection == null) {
                    if (contentValuesCollection.isEmpty()) {
                        fail("ContentValues for MimeType " + mimeType
                                + " is not expected at all (" + actualContentValues + ")");
                    }
                    boolean checked = false;
                    for (ContentValues expectedContentValues : contentValuesCollection) {
                        /* For testing
                        Log.d("@@@", "expected: "
                                + convertToEasilyReadableString(expectedContentValues));
                        Log.d("@@@", "actual  : "
                                + convertToEasilyReadableString(actualContentValues));
                         */
                        if (equalsForContentValues(expectedContentValues,
                                actualContentValues)) {
                            assertTrue(contentValuesCollection.remove(expectedContentValues));
@@ -230,13 +234,10 @@ import java.util.Map.Entry;
    }

    public class ContactStructVerifier {
        private final int mResourceId;
        private final int mVCardType;
        private final ImportVerificationResolver mResolver;
        // private final String mCharset;
        public ContactStructVerifier(int resId, int vCardType) {
            mResourceId = resId;
            mVCardType = vCardType;

        public ContactStructVerifier() {
            mResolver = new ImportVerificationResolver();
        }

@@ -247,16 +248,21 @@ import java.util.Map.Entry;
            return contentValues;
        }

        public void verify() throws IOException, VCardException {
            InputStream is = getContext().getResources().openRawResource(mResourceId);
        public void verify(int resId, int vCardType)
                throws IOException, VCardException {
            verify(getContext().getResources().openRawResource(resId), vCardType);
        }

        public void verify(InputStream is, int vCardType)
                throws IOException, VCardException {
            final VCardParser vCardParser;
            if (VCardConfig.isV30(mVCardType)) {
            if (VCardConfig.isV30(vCardType)) {
                vCardParser = new VCardParser_V30(true);  // use StrictParsing
            } else {
                vCardParser = new VCardParser_V21();
            }
            VCardDataBuilder builder =
                new VCardDataBuilder(null, null, false, mVCardType, null);
                new VCardDataBuilder(null, null, false, vCardType, null);
            builder.addEntryHandler(new EntryCommitter(mResolver));
            try {
                vCardParser.parse(is, builder);
@@ -283,12 +289,13 @@ import java.util.Map.Entry;
        SortedMap<String, String> sortedMap = new TreeMap<String, String>();
        for (Entry<String, Object> entry : contentValues.valueSet()) {
            final String key = entry.getKey();
            final String value = entry.getValue().toString();
            final Object value = entry.getValue();
            final String valueString = (value != null ? value.toString() : null);
            if (Data.MIMETYPE.equals(key)) {
                mimeTypeValue = value;
                mimeTypeValue = valueString;
            } else {
                assertNotNull(key);
                sortedMap.put(key, (value != null ? value.toString() : ""));
                sortedMap.put(key, valueString);
            }
        }
        StringBuilder builder = new StringBuilder();