ImportTestProvider.java revision 5f363a8136349b242d243c3c0c14e6d5a065d23f
14199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/*
24199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Copyright (C) 2010 The Android Open Source Project
34199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *
44199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Licensed under the Apache License, Version 2.0 (the "License");
54199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * you may not use this file except in compliance with the License.
64199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * You may obtain a copy of the License at
74199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *
84199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *      http://www.apache.org/licenses/LICENSE-2.0
94199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *
104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Unless required by applicable law or agreed to in writing, software
114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * distributed under the License is distributed on an "AS IS" BASIS,
124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * See the License for the specific language governing permissions and
144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * limitations under the License.
154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */
164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawapackage com.android.vcard.tests.test_utils;
174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentProviderOperation;
194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentProviderResult;
204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentValues;
214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.net.Uri;
224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Email;
234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Event;
244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.GroupMembership;
254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Im;
264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Nickname;
274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Note;
284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Organization;
294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Phone;
304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Photo;
314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Relation;
324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Website;
355f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawaimport android.provider.ContactsContract.Data;
365f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawaimport android.provider.ContactsContract.RawContacts;
375f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawaimport android.test.AndroidTestCase;
384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.test.mock.MockContentProvider;
394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.text.TextUtils;
404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.util.Log;
414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport junit.framework.TestCase;
434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.ArrayList;
454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Arrays;
464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Collection;
474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.HashMap;
484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.HashSet;
494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Map;
505f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawaimport java.util.Map.Entry;
514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Set;
524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.SortedMap;
534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.TreeMap;
544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/* package */ class ImportTestProvider extends MockContentProvider {
564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private static final Set<String> sKnownMimeTypeSet =
574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        new HashSet<String>(Arrays.asList(StructuredName.CONTENT_ITEM_TYPE,
584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                Nickname.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE,
594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                Email.CONTENT_ITEM_TYPE, StructuredPostal.CONTENT_ITEM_TYPE,
604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                Im.CONTENT_ITEM_TYPE, Organization.CONTENT_ITEM_TYPE,
614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                Event.CONTENT_ITEM_TYPE, Photo.CONTENT_ITEM_TYPE,
624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                Note.CONTENT_ITEM_TYPE, Website.CONTENT_ITEM_TYPE,
634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                Relation.CONTENT_ITEM_TYPE, Event.CONTENT_ITEM_TYPE,
644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                GroupMembership.CONTENT_ITEM_TYPE));
654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    final Map<String, Collection<ContentValues>> mMimeTypeToExpectedContentValues;
674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
685f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa    public ImportTestProvider(AndroidTestCase androidTestCase) {
694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mMimeTypeToExpectedContentValues =
704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            new HashMap<String, Collection<ContentValues>>();
714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        for (String acceptanbleMimeType : sKnownMimeTypeSet) {
724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Do not use HashSet since the current implementation changes the content of
734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // ContentValues after the insertion, which make the result of hashCode()
744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // changes...
754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mMimeTypeToExpectedContentValues.put(
764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    acceptanbleMimeType, new ArrayList<ContentValues>());
774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void addExpectedContentValues(ContentValues expectedContentValues) {
814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String mimeType = expectedContentValues.getAsString(Data.MIMETYPE);
824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (!sKnownMimeTypeSet.contains(mimeType)) {
835f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa            TestCase.fail(String.format(
844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    "Unknow MimeType %s in the test code. Test code should be broken.",
854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mimeType));
864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final Collection<ContentValues> contentValuesCollection =
894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                mMimeTypeToExpectedContentValues.get(mimeType);
904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        contentValuesCollection.add(expectedContentValues);
914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    @Override
944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public ContentProviderResult[] applyBatch(
954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            ArrayList<ContentProviderOperation> operations) {
964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (operations == null) {
975f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa            TestCase.fail("There is no operation.");
984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final int size = operations.size();
1014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        ContentProviderResult[] fakeResultArray = new ContentProviderResult[size];
1024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        for (int i = 0; i < size; i++) {
1034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Uri uri = Uri.withAppendedPath(RawContacts.CONTENT_URI, String.valueOf(i));
1044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            fakeResultArray[i] = new ContentProviderResult(uri);
1054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        for (int i = 0; i < size; i++) {
1084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            ContentProviderOperation operation = operations.get(i);
1094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            ContentValues contentValues = operation.resolveValueBackReferences(
1104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    fakeResultArray, i);
1114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        for (int i = 0; i < size; i++) {
1134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            ContentProviderOperation operation = operations.get(i);
1144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            ContentValues actualContentValues = operation.resolveValueBackReferences(
1154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    fakeResultArray, i);
1164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final Uri uri = operation.getUri();
1174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (uri.equals(RawContacts.CONTENT_URI)) {
1185f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa                TestCase.assertNull(actualContentValues.get(RawContacts.ACCOUNT_NAME));
1195f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa                TestCase.assertNull(actualContentValues.get(RawContacts.ACCOUNT_TYPE));
1204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else if (uri.equals(Data.CONTENT_URI)) {
1214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final String mimeType = actualContentValues.getAsString(Data.MIMETYPE);
1224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (!sKnownMimeTypeSet.contains(mimeType)) {
1235f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa                    TestCase.fail(String.format(
1244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            "Unknown MimeType %s. Probably added after developing this test",
1254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            mimeType));
1264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
1274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // Remove data meaningless in this unit tests.
1284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // Specifically, Data.DATA1 - DATA7 are set to null or empty String
1294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // regardless of the input, but it may change depending on how
1304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // resolver-related code handles it.
1314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // Here, we ignore these implementation-dependent specs and
1324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // just check whether vCard importer correctly inserts rellevent data.
1334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                Set<String> keyToBeRemoved = new HashSet<String>();
1344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (Entry<String, Object> entry : actualContentValues.valueSet()) {
1354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    Object value = entry.getValue();
1364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (value == null || TextUtils.isEmpty(value.toString())) {
1374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        keyToBeRemoved.add(entry.getKey());
1384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
1394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
1404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (String key: keyToBeRemoved) {
1414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    actualContentValues.remove(key);
1424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
1434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                /* for testing
1444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                Log.d("@@@",
1454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        String.format("MimeType: %s, data: %s",
1464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                                mimeType, actualContentValues.toString())); */
1474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // Remove RAW_CONTACT_ID entry just for safety, since we do not care
1484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // how resolver-related code handles the entry in this unit test,
1494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (actualContentValues.containsKey(Data.RAW_CONTACT_ID)) {
1504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    actualContentValues.remove(Data.RAW_CONTACT_ID);
1514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
1524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final Collection<ContentValues> contentValuesCollection =
1534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mMimeTypeToExpectedContentValues.get(mimeType);
1544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (contentValuesCollection.isEmpty()) {
1555f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa                    TestCase.fail("ContentValues for MimeType " + mimeType
1564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            + " is not expected at all (" + actualContentValues + ")");
1574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
1584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                boolean checked = false;
1594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (ContentValues expectedContentValues : contentValuesCollection) {
1604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    /*for testing
1614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    Log.d("@@@", "expected: "
1624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            + convertToEasilyReadableString(expectedContentValues));
1634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    Log.d("@@@", "actual  : "
1644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            + convertToEasilyReadableString(actualContentValues));*/
1654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (equalsForContentValues(expectedContentValues,
1664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            actualContentValues)) {
1675f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa                        TestCase.assertTrue(contentValuesCollection.remove(expectedContentValues));
1684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        checked = true;
1694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        break;
1704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
1714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
1724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (!checked) {
1734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    final StringBuilder builder = new StringBuilder();
1744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append("Unexpected: ");
1754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(convertToEasilyReadableString(actualContentValues));
1764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append("\nExpected: ");
1774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    for (ContentValues expectedContentValues : contentValuesCollection) {
1784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder.append(convertToEasilyReadableString(expectedContentValues));
1794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
1805f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa                    TestCase.fail(builder.toString());
1814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
1824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
1835f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa                TestCase.fail("Unexpected Uri has come: " + uri);
1844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }  // for (int i = 0; i < size; i++) {
1864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return fakeResultArray;
1874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void verify() {
1904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        StringBuilder builder = new StringBuilder();
1914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        for (Collection<ContentValues> contentValuesCollection :
1924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                mMimeTypeToExpectedContentValues.values()) {
1934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (ContentValues expectedContentValues: contentValuesCollection) {
1944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.append(convertToEasilyReadableString(expectedContentValues));
1954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.append("\n");
1964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (builder.length() > 0) {
1994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final String failMsg =
2004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                "There is(are) remaining expected ContentValues instance(s): \n"
2014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    + builder.toString();
2025f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa            TestCase.fail(failMsg);
2034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
2054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
2074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Utility method to print ContentValues whose content is printed with sorted keys.
2084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
2094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String convertToEasilyReadableString(ContentValues contentValues) {
2104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (contentValues == null) {
2114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return "null";
2124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        String mimeTypeValue = "";
2144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        SortedMap<String, String> sortedMap = new TreeMap<String, String>();
2154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        for (Entry<String, Object> entry : contentValues.valueSet()) {
2164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final String key = entry.getKey();
2174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final Object value = entry.getValue();
2184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final String valueString = (value != null ? value.toString() : null);
2194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (Data.MIMETYPE.equals(key)) {
2204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                mimeTypeValue = valueString;
2214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
2225f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa                TestCase.assertNotNull(key);
2234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                sortedMap.put(key, valueString);
2244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        StringBuilder builder = new StringBuilder();
2274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        builder.append(Data.MIMETYPE);
2284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        builder.append('=');
2294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        builder.append(mimeTypeValue);
2304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        for (Entry<String, String> entry : sortedMap.entrySet()) {
2314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final String key = entry.getKey();
2324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final String value = entry.getValue();
2334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.append(' ');
2344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.append(key);
2354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.append("=\"");
2364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.append(value);
2374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.append('"');
2384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return builder.toString();
2404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
2414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private static boolean equalsForContentValues(
2434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            ContentValues expected, ContentValues actual) {
2444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (expected == actual) {
2454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return true;
2464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (expected == null || actual == null || expected.size() != actual.size()) {
2474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return false;
2484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        for (Entry<String, Object> entry : expected.valueSet()) {
2514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final String key = entry.getKey();
2524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final Object value = entry.getValue();
2534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!actual.containsKey(key)) {
2544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
2554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (value instanceof byte[]) {
2574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                Object actualValue = actual.get(key);
2584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (!Arrays.equals((byte[])value, (byte[])actualValue)) {
2594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    byte[] e = (byte[])value;
2604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    byte[] a = (byte[])actualValue;
2614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    Log.d("@@@", "expected (len: " + e.length + "): " + Arrays.toString(e));
2624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    Log.d("@@@", "actual (len: " + a.length + "): " + Arrays.toString(a));
2634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    return false;
2644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
2654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else if (!value.equals(actual.get(key))) {
2664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                Log.d("@@@", "different.");
2674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
2684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return true;
2714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
2724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa}