1673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa/* 2673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa * Copyright (C) 2009 The Android Open Source Project 3673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa * 4673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa * Licensed under the Apache License, Version 2.0 (the "License"); 5673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa * you may not use this file except in compliance with the License. 6673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa * You may obtain a copy of the License at 7673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa * 8673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa * http://www.apache.org/licenses/LICENSE-2.0 9673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa * 10673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa * Unless required by applicable law or agreed to in writing, software 11673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa * distributed under the License is distributed on an "AS IS" BASIS, 12673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa * See the License for the specific language governing permissions and 14673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa * limitations under the License. 15673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa */ 161a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenpackage android.pim.vcard; 17673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 18673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.content.ContentProviderOperation; 19673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.content.ContentProviderResult; 20673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.content.ContentValues; 21673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.net.Uri; 22673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.provider.ContactsContract.Data; 23673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.provider.ContactsContract.RawContacts; 24673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Email; 25673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Event; 26673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.GroupMembership; 27673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Im; 28673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Nickname; 29673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Note; 30673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Organization; 31673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Phone; 32673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Photo; 33673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Relation; 34673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 35673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal; 36673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Website; 37673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.test.mock.MockContentResolver; 38673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport android.text.TextUtils; 39673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 40673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport junit.framework.TestCase; 41673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 42673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport java.util.ArrayList; 43673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport java.util.Arrays; 44673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport java.util.Collection; 45673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport java.util.HashMap; 46673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport java.util.HashSet; 47673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport java.util.Map; 48673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport java.util.Set; 49673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport java.util.SortedMap; 50673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport java.util.TreeMap; 51673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawaimport java.util.Map.Entry; 52673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 53673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa/* package */ class ImportTestResolver extends MockContentResolver { 54673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final ImportTestProvider mProvider; 55673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 56673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa public ImportTestResolver(TestCase testCase) { 57673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mProvider = new ImportTestProvider(testCase); 58673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 59673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 60673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa @Override 61673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa public ContentProviderResult[] applyBatch(String authority, 62673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa ArrayList<ContentProviderOperation> operations) { 63673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa equalsString(authority, RawContacts.CONTENT_URI.toString()); 64673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa return mProvider.applyBatch(operations); 65673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 66673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 67673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa public void addExpectedContentValues(ContentValues expectedContentValues) { 68673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mProvider.addExpectedContentValues(expectedContentValues); 69673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 70673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 71673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa public void verify() { 72673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mProvider.verify(); 73673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 74673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 75673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa private static boolean equalsString(String a, String b) { 76673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (a == null || a.length() == 0) { 77673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa return b == null || b.length() == 0; 78673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } else { 79673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa return a.equals(b); 80673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 81673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 82673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa} 83673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 84673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa/* package */ class ImportTestProvider extends MockContentProvider { 85673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa private static final Set<String> sKnownMimeTypeSet = 86673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa new HashSet<String>(Arrays.asList(StructuredName.CONTENT_ITEM_TYPE, 87673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa Nickname.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE, 88673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa Email.CONTENT_ITEM_TYPE, StructuredPostal.CONTENT_ITEM_TYPE, 89673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa Im.CONTENT_ITEM_TYPE, Organization.CONTENT_ITEM_TYPE, 90673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa Event.CONTENT_ITEM_TYPE, Photo.CONTENT_ITEM_TYPE, 91673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa Note.CONTENT_ITEM_TYPE, Website.CONTENT_ITEM_TYPE, 92673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa Relation.CONTENT_ITEM_TYPE, Event.CONTENT_ITEM_TYPE, 93673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa GroupMembership.CONTENT_ITEM_TYPE)); 94673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 95673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final Map<String, Collection<ContentValues>> mMimeTypeToExpectedContentValues; 96673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 97673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa private final TestCase mTestCase; 98673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 99673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa public ImportTestProvider(TestCase testCase) { 100673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mTestCase = testCase; 101673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mMimeTypeToExpectedContentValues = 102673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa new HashMap<String, Collection<ContentValues>>(); 103673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa for (String acceptanbleMimeType : sKnownMimeTypeSet) { 104673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa // Do not use HashSet since the current implementation changes the content of 105673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa // ContentValues after the insertion, which make the result of hashCode() 106673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa // changes... 107673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mMimeTypeToExpectedContentValues.put( 108673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa acceptanbleMimeType, new ArrayList<ContentValues>()); 109673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 110673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 111673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 112673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa public void addExpectedContentValues(ContentValues expectedContentValues) { 113673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final String mimeType = expectedContentValues.getAsString(Data.MIMETYPE); 114673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (!sKnownMimeTypeSet.contains(mimeType)) { 115673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mTestCase.fail(String.format( 116673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa "Unknow MimeType %s in the test code. Test code should be broken.", 117673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mimeType)); 118673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 119673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 120673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final Collection<ContentValues> contentValuesCollection = 121673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mMimeTypeToExpectedContentValues.get(mimeType); 122673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa contentValuesCollection.add(expectedContentValues); 123673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 124673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 125673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa @Override 126673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa public ContentProviderResult[] applyBatch( 127673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa ArrayList<ContentProviderOperation> operations) { 128673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (operations == null) { 129673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mTestCase.fail("There is no operation."); 130673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 131673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 132673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final int size = operations.size(); 133673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa ContentProviderResult[] fakeResultArray = new ContentProviderResult[size]; 134673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa for (int i = 0; i < size; i++) { 135673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa Uri uri = Uri.withAppendedPath(RawContacts.CONTENT_URI, String.valueOf(i)); 136673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa fakeResultArray[i] = new ContentProviderResult(uri); 137673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 138673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 139673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa for (int i = 0; i < size; i++) { 140673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa ContentProviderOperation operation = operations.get(i); 141673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa ContentValues contentValues = operation.resolveValueBackReferences( 142673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa fakeResultArray, i); 143673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 144673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa for (int i = 0; i < size; i++) { 145673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa ContentProviderOperation operation = operations.get(i); 146673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa ContentValues actualContentValues = operation.resolveValueBackReferences( 147673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa fakeResultArray, i); 148673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final Uri uri = operation.getUri(); 149673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (uri.equals(RawContacts.CONTENT_URI)) { 150673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mTestCase.assertNull(actualContentValues.get(RawContacts.ACCOUNT_NAME)); 151673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mTestCase.assertNull(actualContentValues.get(RawContacts.ACCOUNT_TYPE)); 152673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } else if (uri.equals(Data.CONTENT_URI)) { 153673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final String mimeType = actualContentValues.getAsString(Data.MIMETYPE); 154673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (!sKnownMimeTypeSet.contains(mimeType)) { 155673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mTestCase.fail(String.format( 156673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa "Unknown MimeType %s. Probably added after developing this test", 157673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mimeType)); 158673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 159673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa // Remove data meaningless in this unit tests. 160673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa // Specifically, Data.DATA1 - DATA7 are set to null or empty String 161673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa // regardless of the input, but it may change depending on how 162673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa // resolver-related code handles it. 163673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa // Here, we ignore these implementation-dependent specs and 164673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa // just check whether vCard importer correctly inserts rellevent data. 165673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa Set<String> keyToBeRemoved = new HashSet<String>(); 166673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa for (Entry<String, Object> entry : actualContentValues.valueSet()) { 167673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa Object value = entry.getValue(); 168673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (value == null || TextUtils.isEmpty(value.toString())) { 169673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa keyToBeRemoved.add(entry.getKey()); 170673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 171673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 172673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa for (String key: keyToBeRemoved) { 173673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa actualContentValues.remove(key); 174673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 175673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa /* for testing 176673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa Log.d("@@@", 177673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa String.format("MimeType: %s, data: %s", 178673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mimeType, actualContentValues.toString())); */ 179673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa // Remove RAW_CONTACT_ID entry just for safety, since we do not care 180673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa // how resolver-related code handles the entry in this unit test, 181673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (actualContentValues.containsKey(Data.RAW_CONTACT_ID)) { 182673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa actualContentValues.remove(Data.RAW_CONTACT_ID); 183673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 184673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final Collection<ContentValues> contentValuesCollection = 185673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mMimeTypeToExpectedContentValues.get(mimeType); 186673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (contentValuesCollection.isEmpty()) { 187673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mTestCase.fail("ContentValues for MimeType " + mimeType 188673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa + " is not expected at all (" + actualContentValues + ")"); 189673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 190673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa boolean checked = false; 191673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa for (ContentValues expectedContentValues : contentValuesCollection) { 192673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa /*for testing 193673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa Log.d("@@@", "expected: " 194673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa + convertToEasilyReadableString(expectedContentValues)); 195673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa Log.d("@@@", "actual : " 196673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa + convertToEasilyReadableString(actualContentValues));*/ 197673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (equalsForContentValues(expectedContentValues, 198673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa actualContentValues)) { 199673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mTestCase.assertTrue(contentValuesCollection.remove(expectedContentValues)); 200673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa checked = true; 201673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa break; 202673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 203673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 204673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (!checked) { 205673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final StringBuilder builder = new StringBuilder(); 206673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa builder.append("Unexpected: "); 207673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa builder.append(convertToEasilyReadableString(actualContentValues)); 208673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa builder.append("\nExpected: "); 209673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa for (ContentValues expectedContentValues : contentValuesCollection) { 210673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa builder.append(convertToEasilyReadableString(expectedContentValues)); 211673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 212673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mTestCase.fail(builder.toString()); 213673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 214673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } else { 215673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mTestCase.fail("Unexpected Uri has come: " + uri); 216673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 217673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } // for (int i = 0; i < size; i++) { 2187e25f5cbfbe433c6ffe06a17ef42c471baf07c93Daniel Lehmann return fakeResultArray; 219673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 220673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 221673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa public void verify() { 222673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa StringBuilder builder = new StringBuilder(); 223673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa for (Collection<ContentValues> contentValuesCollection : 224673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mMimeTypeToExpectedContentValues.values()) { 225673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa for (ContentValues expectedContentValues: contentValuesCollection) { 226673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa builder.append(convertToEasilyReadableString(expectedContentValues)); 227673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa builder.append("\n"); 228673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 229673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 230673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (builder.length() > 0) { 231673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final String failMsg = 232673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa "There is(are) remaining expected ContentValues instance(s): \n" 233673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa + builder.toString(); 234673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mTestCase.fail(failMsg); 235673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 236673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 237673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 238673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa /** 239673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa * Utility method to print ContentValues whose content is printed with sorted keys. 240673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa */ 241673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa private String convertToEasilyReadableString(ContentValues contentValues) { 242673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (contentValues == null) { 243673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa return "null"; 244673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 245673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa String mimeTypeValue = ""; 246673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa SortedMap<String, String> sortedMap = new TreeMap<String, String>(); 247673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa for (Entry<String, Object> entry : contentValues.valueSet()) { 248673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final String key = entry.getKey(); 249673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final Object value = entry.getValue(); 250673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final String valueString = (value != null ? value.toString() : null); 251673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (Data.MIMETYPE.equals(key)) { 252673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mimeTypeValue = valueString; 253673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } else { 254673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa mTestCase.assertNotNull(key); 255673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa sortedMap.put(key, valueString); 256673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 257673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 258673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa StringBuilder builder = new StringBuilder(); 259673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa builder.append(Data.MIMETYPE); 260673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa builder.append('='); 261673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa builder.append(mimeTypeValue); 262673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa for (Entry<String, String> entry : sortedMap.entrySet()) { 263673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final String key = entry.getKey(); 264673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final String value = entry.getValue(); 265673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa builder.append(' '); 266673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa builder.append(key); 267673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa builder.append("=\""); 268673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa builder.append(value); 269673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa builder.append('"'); 270673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 271673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa return builder.toString(); 272673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 273673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 274673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa private static boolean equalsForContentValues( 275673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa ContentValues expected, ContentValues actual) { 276673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (expected == actual) { 277673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa return true; 278673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } else if (expected == null || actual == null || expected.size() != actual.size()) { 279673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa return false; 280673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 281673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa 282673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa for (Entry<String, Object> entry : expected.valueSet()) { 283673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final String key = entry.getKey(); 284673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa final Object value = entry.getValue(); 285673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (!actual.containsKey(key)) { 286673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa return false; 287673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 288673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (value instanceof byte[]) { 289673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa Object actualValue = actual.get(key); 290673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa if (!Arrays.equals((byte[])value, (byte[])actualValue)) { 291673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa return false; 292673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 293673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } else if (!value.equals(actual.get(key))) { 294673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa return false; 295673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 296673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 297673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa return true; 298673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa } 299673c1d1fc9f3c004e999f763a9c718e656497d32Daisuke Miyakawa} 300