ImportTestProvider.java revision 48dd8e86a81d2ab40eb762975c8211c225002bf0
1cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber/* 2cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Copyright (C) 2010 The Android Open Source Project 3cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * 4cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * you may not use this file except in compliance with the License. 6cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * You may obtain a copy of the License at 7cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * 8cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * 10cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Unless required by applicable law or agreed to in writing, software 11cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * See the License for the specific language governing permissions and 14cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * limitations under the License. 15cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber */ 16cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberpackage com.android.vcard.tests.testutils; 17cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 18cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.content.ContentProviderOperation; 19cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.content.ContentProviderResult; 20cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.content.ContentValues; 21cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.net.Uri; 22cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.provider.ContactsContract.CommonDataKinds.Email; 23cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.provider.ContactsContract.CommonDataKinds.Event; 24cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.provider.ContactsContract.CommonDataKinds.GroupMembership; 25cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.provider.ContactsContract.CommonDataKinds.Im; 26cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.provider.ContactsContract.CommonDataKinds.Nickname; 27cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.provider.ContactsContract.CommonDataKinds.Note; 28cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.provider.ContactsContract.CommonDataKinds.Organization; 29cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.provider.ContactsContract.CommonDataKinds.Phone; 30cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.provider.ContactsContract.CommonDataKinds.Photo; 31cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.provider.ContactsContract.CommonDataKinds.Relation; 32cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.provider.ContactsContract.CommonDataKinds.SipAddress; 33cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 34cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal; 35cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport android.provider.ContactsContract.CommonDataKinds.Website; 365bc087c573c70c84c6a39946457590b42d392a33Andreas Huberimport android.provider.ContactsContract.Data; 375bc087c573c70c84c6a39946457590b42d392a33Andreas Huberimport android.provider.ContactsContract.RawContacts; 385bc087c573c70c84c6a39946457590b42d392a33Andreas Huberimport android.test.AndroidTestCase; 395bc087c573c70c84c6a39946457590b42d392a33Andreas Huberimport android.test.mock.MockContentProvider; 405bc087c573c70c84c6a39946457590b42d392a33Andreas Huberimport android.text.TextUtils; 41cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 42cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport junit.framework.TestCase; 43cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 44cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport java.util.ArrayList; 45cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport java.util.Arrays; 46cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport java.util.Collection; 47cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport java.util.HashMap; 48cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport java.util.HashSet; 49cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport java.util.Map; 50cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport java.util.Map.Entry; 51cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport java.util.Set; 52cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport java.util.SortedMap; 53cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberimport java.util.TreeMap; 54cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 55cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberpublic class ImportTestProvider extends MockContentProvider { 56f933441648ef6a71dee783d733aac17b9508b452Andreas Huber private static final Set<String> sKnownMimeTypeSet = 57f933441648ef6a71dee783d733aac17b9508b452Andreas Huber new HashSet<String>(Arrays.asList(StructuredName.CONTENT_ITEM_TYPE, 58f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Nickname.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE, 59f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Email.CONTENT_ITEM_TYPE, StructuredPostal.CONTENT_ITEM_TYPE, 60f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Im.CONTENT_ITEM_TYPE, Organization.CONTENT_ITEM_TYPE, 61f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Event.CONTENT_ITEM_TYPE, Photo.CONTENT_ITEM_TYPE, 62f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Note.CONTENT_ITEM_TYPE, Website.CONTENT_ITEM_TYPE, 63f933441648ef6a71dee783d733aac17b9508b452Andreas Huber Relation.CONTENT_ITEM_TYPE, Event.CONTENT_ITEM_TYPE, 64f933441648ef6a71dee783d733aac17b9508b452Andreas Huber GroupMembership.CONTENT_ITEM_TYPE, SipAddress.CONTENT_ITEM_TYPE)); 65f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 66f933441648ef6a71dee783d733aac17b9508b452Andreas Huber final Map<String, Collection<ContentValues>> mMimeTypeToExpectedContentValues; 67f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public ImportTestProvider(AndroidTestCase androidTestCase) { 695bc087c573c70c84c6a39946457590b42d392a33Andreas Huber mMimeTypeToExpectedContentValues = 705bc087c573c70c84c6a39946457590b42d392a33Andreas Huber new HashMap<String, Collection<ContentValues>>(); 715bc087c573c70c84c6a39946457590b42d392a33Andreas Huber for (String acceptanbleMimeType : sKnownMimeTypeSet) { 725bc087c573c70c84c6a39946457590b42d392a33Andreas Huber // Do not use HashSet since the current implementation changes the content of 735bc087c573c70c84c6a39946457590b42d392a33Andreas Huber // ContentValues after the insertion, which make the result of hashCode() 745bc087c573c70c84c6a39946457590b42d392a33Andreas Huber // changes... 75f933441648ef6a71dee783d733aac17b9508b452Andreas Huber mMimeTypeToExpectedContentValues.put( 76f933441648ef6a71dee783d733aac17b9508b452Andreas Huber acceptanbleMimeType, new ArrayList<ContentValues>()); 77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 79f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 80f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public void addExpectedContentValues(ContentValues expectedContentValues) { 81f933441648ef6a71dee783d733aac17b9508b452Andreas Huber final String mimeType = expectedContentValues.getAsString(Data.MIMETYPE); 82f933441648ef6a71dee783d733aac17b9508b452Andreas Huber if (!sKnownMimeTypeSet.contains(mimeType)) { 83f933441648ef6a71dee783d733aac17b9508b452Andreas Huber TestCase.fail(String.format( 84cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber "Unknow MimeType %s in the test code. Test code should be broken.", 85cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mimeType)); 86cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 87cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 88cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber final Collection<ContentValues> contentValuesCollection = 89cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mMimeTypeToExpectedContentValues.get(mimeType); 90cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber contentValuesCollection.add(expectedContentValues); 91cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 92cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber 93cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber @Override 94cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber public ContentProviderResult[] applyBatch( 952a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber ArrayList<ContentProviderOperation> operations) { 96cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (operations == null) { 972a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber TestCase.fail("There is no operation."); 985bc087c573c70c84c6a39946457590b42d392a33Andreas Huber } 995bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 1005bc087c573c70c84c6a39946457590b42d392a33Andreas Huber final int size = operations.size(); 1015bc087c573c70c84c6a39946457590b42d392a33Andreas Huber ContentProviderResult[] fakeResultArray = new ContentProviderResult[size]; 1025bc087c573c70c84c6a39946457590b42d392a33Andreas Huber for (int i = 0; i < size; i++) { 1032a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber Uri uri = Uri.withAppendedPath(RawContacts.CONTENT_URI, String.valueOf(i)); 1042a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber fakeResultArray[i] = new ContentProviderResult(uri); 105f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 106f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 107cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber for (int i = 0; i < size; i++) { 108f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber ContentProviderOperation operation = operations.get(i); 109cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber ContentValues contentValues = operation.resolveValueBackReferences( 110f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber fakeResultArray, i); 111cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 1122a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber for (int i = 0; i < size; i++) { 1132a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber ContentProviderOperation operation = operations.get(i); 1142a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber ContentValues actualContentValues = operation.resolveValueBackReferences( 115cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber fakeResultArray, i); 116cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber final Uri uri = operation.getUri(); 117cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (uri.equals(RawContacts.CONTENT_URI)) { 118cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber TestCase.assertNull(actualContentValues.get(RawContacts.ACCOUNT_NAME)); 119cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber TestCase.assertNull(actualContentValues.get(RawContacts.ACCOUNT_TYPE)); 120cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } else if (uri.equals(Data.CONTENT_URI)) { 121cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber final String mimeType = actualContentValues.getAsString(Data.MIMETYPE); 122cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (!sKnownMimeTypeSet.contains(mimeType)) { 123cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber TestCase.fail(String.format( 124cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber "Unknown MimeType %s. " + 125cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber "(Maybe the MimeType is added after developing this test suite." + 126cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber "Please look into %s if you strongly believe the type is regitimate)", 127bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber ImportTestProvider.class.getSimpleName(), mimeType)); 128f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 1293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block // Remove data meaningless in this unit tests. 130bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber // Specifically, Data.DATA1 - DATA7 are set to null or empty String 131cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber // regardless of the input, but it may change depending on how 132cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber // resolver-related code handles it. 133cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber // Here, we ignore these implementation-dependent specs and 134cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber // just check whether vCard importer correctly inserts rellevent data. 135cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber Set<String> keyToBeRemoved = new HashSet<String>(); 1365bc087c573c70c84c6a39946457590b42d392a33Andreas Huber for (Entry<String, Object> entry : actualContentValues.valueSet()) { 13732f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber Object value = entry.getValue(); 13832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber if (value == null || TextUtils.isEmpty(value.toString())) { 1392a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber keyToBeRemoved.add(entry.getKey()); 140bff07d0b22a5ee2d9f044f6cb5e4be1532017ab0Andreas Huber } 1419a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber } 1429a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber for (String key: keyToBeRemoved) { 1439a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber actualContentValues.remove(key); 1449a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber } 1459a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber /* for testing 1469a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber Log.d("@@@", 1479a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber String.format("MimeType: %s, data: %s", 1489a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber mimeType, actualContentValues.toString())); */ 1499a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber // Remove RAW_CONTACT_ID entry just for safety, since we do not care 1509a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber // how resolver-related code handles the entry in this unit test, 1519a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber if (actualContentValues.containsKey(Data.RAW_CONTACT_ID)) { 15222fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber actualContentValues.remove(Data.RAW_CONTACT_ID); 1539a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber } 15422fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber final Collection<ContentValues> contentValuesCollection = 1559a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber mMimeTypeToExpectedContentValues.get(mimeType); 1569a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber if (contentValuesCollection.isEmpty()) { 1579a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber TestCase.fail("ContentValues for MimeType " + mimeType 1589a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber + " is not expected at all (" + actualContentValues + ")"); 1599a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber } 1609a442c1b9a051edc6d4ceb0daad2d0a8433e7b0bAndreas Huber boolean checked = false; 16122fc52f6f72f39e33c3970d0291de3569118aa5cAndreas Huber for (ContentValues expectedContentValues : contentValuesCollection) { 1622a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber /*for testing 1632a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber Log.d("@@@", "expected: " 1642a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber + convertToEasilyReadableString(expectedContentValues)); 1652a4d22d79e927f2245537921e10fc5fda1c47a29Andreas Huber Log.d("@@@", "actual : " 166cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber + convertToEasilyReadableString(actualContentValues));*/ 167cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (equalsForContentValues(expectedContentValues, 168cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber actualContentValues)) { 169cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber TestCase.assertTrue(contentValuesCollection.remove(expectedContentValues)); 170cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber checked = true; 171cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber break; 172cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 173cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 174cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber if (!checked) { 175cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber final StringBuilder builder = new StringBuilder(); 176cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber builder.append("\n"); 177cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber builder.append("Unexpected: "); 178cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber builder.append(convertToEasilyReadableString(actualContentValues)); 179cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber builder.append("\n"); 180cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber builder.append("Expected : "); 181cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber for (ContentValues expectedContentValues : contentValuesCollection) { 182cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber builder.append(convertToEasilyReadableString(expectedContentValues)); 183cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber } 184f933441648ef6a71dee783d733aac17b9508b452Andreas Huber TestCase.fail(builder.toString()); 185f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 186f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } else { 187f933441648ef6a71dee783d733aac17b9508b452Andreas Huber TestCase.fail("Unexpected Uri has come: " + uri); 188f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 189f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } // for (int i = 0; i < size; i++) { 190f933441648ef6a71dee783d733aac17b9508b452Andreas Huber return fakeResultArray; 191f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 192f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 193f933441648ef6a71dee783d733aac17b9508b452Andreas Huber /** 194f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Checks all expected ContentValues are consumed during import. 195f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 196f933441648ef6a71dee783d733aac17b9508b452Andreas Huber public void verify() { 197f933441648ef6a71dee783d733aac17b9508b452Andreas Huber StringBuilder builder = new StringBuilder(); 198f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (Collection<ContentValues> contentValuesCollection : 199cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber mMimeTypeToExpectedContentValues.values()) { 200 for (ContentValues expectedContentValues: contentValuesCollection) { 201 builder.append(convertToEasilyReadableString(expectedContentValues)); 202 builder.append("\n"); 203 } 204 } 205 if (builder.length() > 0) { 206 final String failMsg = 207 "There is(are) remaining expected ContentValues instance(s): \n" 208 + builder.toString(); 209 TestCase.fail(failMsg); 210 } 211 } 212 213 /** 214 * Utility method to print ContentValues whose content is printed with sorted keys. 215 */ 216 private String convertToEasilyReadableString(ContentValues contentValues) { 217 if (contentValues == null) { 218 return "null"; 219 } 220 String mimeTypeValue = ""; 221 SortedMap<String, String> sortedMap = new TreeMap<String, String>(); 222 for (Entry<String, Object> entry : contentValues.valueSet()) { 223 final String key = entry.getKey(); 224 final Object value = entry.getValue(); 225 final String valueString = (value != null ? value.toString() : null); 226 if (Data.MIMETYPE.equals(key)) { 227 mimeTypeValue = valueString; 228 } else { 229 TestCase.assertNotNull(key); 230 sortedMap.put(key, valueString); 231 } 232 } 233 StringBuilder builder = new StringBuilder(); 234 builder.append(Data.MIMETYPE); 235 builder.append('='); 236 builder.append(mimeTypeValue); 237 for (Entry<String, String> entry : sortedMap.entrySet()) { 238 final String key = entry.getKey(); 239 final String value = entry.getValue(); 240 builder.append(' '); 241 builder.append(key); 242 builder.append("=\""); 243 builder.append(value); 244 builder.append('"'); 245 } 246 return builder.toString(); 247 } 248 249 private static boolean equalsForContentValues( 250 final ContentValues expected, final ContentValues actual) { 251 if (expected == actual) { 252 return true; 253 } else if (expected == null || actual == null || expected.size() != actual.size()) { 254 return false; 255 } 256 257 for (Entry<String, Object> entry : expected.valueSet()) { 258 final String key = entry.getKey(); 259 final Object value = entry.getValue(); 260 if (!actual.containsKey(key)) { 261 return false; 262 } 263 // Type mismatch usuall happens as importer doesn't care the type of each value. 264 // For example, variable type might be Integer when importing the type of TEL, 265 // while variable type would be String when importing the type of RELATION. 266 final Object actualValue = actual.get(key); 267 if (value instanceof byte[]) { 268 if (!Arrays.equals((byte[])value, (byte[])actualValue)) { 269 byte[] e = (byte[])value; 270 byte[] a = (byte[])actualValue; 271 return false; 272 } 273 } else if (!value.equals(actualValue) && 274 !value.toString().equals(actualValue.toString())) { 275 return false; 276 } 277 } 278 return true; 279 } 280}