14199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/* 24199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Copyright (C) 2009 The Android Open Source Project 34199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * 44199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Licensed under the Apache License, Version 2.0 (the "License"); you may not 54199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * use this file except in compliance with the License. You may obtain a copy of 64199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * 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, WITHOUT 124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * License for the specific language governing permissions and limitations under 144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * the License. 154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */ 16677ef21613a9d35053ec098444832ce4125a847eDaisuke Miyakawapackage com.android.vcard.tests.testutils; 174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 187e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawaimport android.content.ContentResolver; 197e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawaimport android.content.EntityIterator; 207e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawaimport android.database.Cursor; 217e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawaimport android.net.Uri; 227e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawaimport android.test.AndroidTestCase; 237e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawaimport android.test.mock.MockContext; 247e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawaimport android.text.TextUtils; 257e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawaimport android.util.Log; 267e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawa 272c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Chengimport com.android.vcard.VCardComposer; 282c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Chengimport com.android.vcard.VCardConfig; 292c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Chengimport com.android.vcard.VCardEntryConstructor; 302c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Chengimport com.android.vcard.VCardParser; 312c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Chengimport com.android.vcard.VCardUtils; 322c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Chengimport com.android.vcard.exception.VCardException; 332c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng 34a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawaimport junit.framework.TestCase; 35a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa 364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.io.ByteArrayInputStream; 374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.io.IOException; 384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.io.InputStream; 394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.lang.reflect.Method; 404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/** 424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * <p> 434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * The class lets users checks that given expected vCard data are same as given actual vCard data. 444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Able to verify both vCard importer/exporter. 454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * </p> 464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * <p> 474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * First a user has to initialize the object by calling either 484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * {@link #initForImportTest(int, int)} or {@link #initForExportTest(int)}. 494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * "Round trip test" (import -> export -> import, or export -> import -> export) is not supported. 504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * </p> 514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */ 524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawapublic class VCardVerifier { 534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private static final String LOG_TAG = "VCardVerifier"; 5456174dfd0654acbe828e4db38537ec5a3a04d466Daisuke Miyakawa private static final boolean DEBUG = true; 554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 567e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawa /** 577e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawa * Special URI for testing. 587e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawa */ 597e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawa /* package */ static final String VCARD_TEST_AUTHORITY = "com.android.unit_tests.vcard"; 607e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawa private static final Uri VCARD_TEST_AUTHORITY_URI = 617e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawa Uri.parse("content://" + VCARD_TEST_AUTHORITY); 627e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawa /* package */ static final Uri CONTACTS_TEST_CONTENT_URI = 63677ef21613a9d35053ec098444832ce4125a847eDaisuke Miyakawa Uri.withAppendedPath(VCARD_TEST_AUTHORITY_URI, "contacts"); 647e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawa 654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private static class CustomMockContext extends MockContext { 664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final ContentResolver mResolver; 674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public CustomMockContext(ContentResolver resolver) { 684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mResolver = resolver; 694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa @Override 724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public ContentResolver getContentResolver() { 734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return mResolver; 744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 77a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa private final AndroidTestCase mAndroidTestCase; 784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private int mVCardType; 794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private boolean mIsDoCoMo; 804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // Only one of them must be non-empty. 824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private ExportTestResolver mExportTestResolver; 834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private InputStream mInputStream; 844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // To allow duplication, use list instead of set. 864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // When null, we don't need to do the verification. 874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private PropertyNodesVerifier mPropertyNodesVerifier; 884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private LineVerifier mLineVerifier; 894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private ContentValuesVerifier mContentValuesVerifier; 904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private boolean mInitialized; 914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private boolean mVerified = false; 924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private String mCharset; 934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 942c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng private String mExceptionContents; 952c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng 964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // Called by VCardTestsBase 97a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa public VCardVerifier(AndroidTestCase androidTestCase) { 98a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa mAndroidTestCase = androidTestCase; 994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mExportTestResolver = null; 1004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mInputStream = null; 1014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mInitialized = false; 1024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mVerified = false; 1034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // Should be called at the beginning of each import test. 1064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public void initForImportTest(int vcardType, int resId) { 1074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (mInitialized) { 108be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.fail("Already initialized"); 1094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mVCardType = vcardType; 1114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mIsDoCoMo = VCardConfig.isDoCoMo(vcardType); 1124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa setInputResourceId(resId); 1134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mInitialized = true; 1144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // Should be called at the beginning of each export test. 1174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public void initForExportTest(int vcardType) { 1184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa initForExportTest(vcardType, "UTF-8"); 1194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public void initForExportTest(int vcardType, String charset) { 1224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (mInitialized) { 123be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.fail("Already initialized"); 1244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 125a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa mExportTestResolver = new ExportTestResolver(mAndroidTestCase); 1264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mVCardType = vcardType; 1274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mIsDoCoMo = VCardConfig.isDoCoMo(vcardType); 1284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mInitialized = true; 1294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (TextUtils.isEmpty(charset)) { 1304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mCharset = "UTF-8"; 1314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else { 1324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mCharset = charset; 1334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private void setInputResourceId(int resId) { 137677ef21613a9d35053ec098444832ce4125a847eDaisuke Miyakawa final InputStream inputStream = 138677ef21613a9d35053ec098444832ce4125a847eDaisuke Miyakawa mAndroidTestCase.getContext().getResources().openRawResource(resId); 1394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (inputStream == null) { 140be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.fail("Wrong resId: " + resId); 1414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa setInputStream(inputStream); 1434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private void setInputStream(InputStream inputStream) { 1464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (mExportTestResolver != null) { 147be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.fail("addInputEntry() is called."); 1484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else if (mInputStream != null) { 149be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.fail("InputStream is already set"); 1504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mInputStream = inputStream; 1524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public ContactEntry addInputEntry() { 1554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (!mInitialized) { 156be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.fail("Not initialized"); 1574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (mInputStream != null) { 159be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.fail("setInputStream is called"); 1604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return mExportTestResolver.addInputContactEntry(); 1624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 164a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa public PropertyNodesVerifierElem addPropertyNodesVerifierElemWithoutVersion() { 1654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (!mInitialized) { 166be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.fail("Not initialized"); 1674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (mPropertyNodesVerifier == null) { 169a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa mPropertyNodesVerifier = new PropertyNodesVerifier(mAndroidTestCase); 1704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 171a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa return mPropertyNodesVerifier.addPropertyNodesVerifierElem(); 172a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa } 173677ef21613a9d35053ec098444832ce4125a847eDaisuke Miyakawa 174a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa public PropertyNodesVerifierElem addPropertyNodesVerifierElem() { 175a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa final PropertyNodesVerifierElem elem = addPropertyNodesVerifierElemWithoutVersion(); 176be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa final String versionString; 177be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa if (VCardConfig.isVersion21(mVCardType)) { 178be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa versionString = "2.1"; 179be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa } else if (VCardConfig.isVersion30(mVCardType)) { 180be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa versionString = "3.0"; 181be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa } else if (VCardConfig.isVersion40(mVCardType)) { 182be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa versionString = "4.0"; 183be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa } else { 184be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa throw new RuntimeException("Unexpected vcard type during a unit test"); 185be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa } 186be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa elem.addExpectedNodeWithOrder("VERSION", versionString); 1874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return elem; 1894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public PropertyNodesVerifierElem addPropertyNodesVerifierElemWithEmptyName() { 1924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (!mInitialized) { 193be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.fail("Not initialized"); 1944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1953d77102a83d0e412046ca0ff9dfdef1a44050ca3Daisuke Miyakawa final PropertyNodesVerifierElem elem = addPropertyNodesVerifierElem(); 1963d77102a83d0e412046ca0ff9dfdef1a44050ca3Daisuke Miyakawa if (VCardConfig.isVersion40(mVCardType)) { 1973d77102a83d0e412046ca0ff9dfdef1a44050ca3Daisuke Miyakawa elem.addExpectedNodeWithOrder("FN", ""); 1983d77102a83d0e412046ca0ff9dfdef1a44050ca3Daisuke Miyakawa } else if (VCardConfig.isVersion30(mVCardType)) { 1993d77102a83d0e412046ca0ff9dfdef1a44050ca3Daisuke Miyakawa elem.addExpectedNodeWithOrder("N", ""); 2003d77102a83d0e412046ca0ff9dfdef1a44050ca3Daisuke Miyakawa elem.addExpectedNodeWithOrder("FN", ""); 2014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else if (mIsDoCoMo) { 2024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa elem.addExpectedNodeWithOrder("N", ""); 2034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return elem; 2054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 2074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public LineVerifierElem addLineVerifierElem() { 2084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (!mInitialized) { 209be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.fail("Not initialized"); 2104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (mLineVerifier == null) { 212a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa mLineVerifier = new LineVerifier(mAndroidTestCase, mVCardType); 2134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return mLineVerifier.addLineVerifierElem(); 2154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 2174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public ContentValuesVerifierElem addContentValuesVerifierElem() { 2184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (!mInitialized) { 219be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.fail("Not initialized"); 2204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (mContentValuesVerifier == null) { 2224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mContentValuesVerifier = new ContentValuesVerifier(); 2234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 225a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa return mContentValuesVerifier.addElem(mAndroidTestCase); 2264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 2282c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng public void addVCardExceptionVerifier(String contents) { 2292c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng mExceptionContents = contents; 2302c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng } 2312c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng 232a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa /** 233677ef21613a9d35053ec098444832ce4125a847eDaisuke Miyakawa * Sets up sub-verifiers correctly and tries to parse vCard as {@link InputStream}. 234a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa * Errors around InputStream must be handled outside this method. 235a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa * 236a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa * Used both from {@link #verifyForImportTest()} and from {@link #verifyForExportTest()}. 237a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa */ 238a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa private void verifyWithInputStream(InputStream is) throws IOException { 2394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa try { 2404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // Note: we must not specify charset toward vCard parsers. This code checks whether 2414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // those parsers are able to encode given binary without any extra information for 2424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // charset. 243be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa final VCardParser parser = VCardUtils.getAppropriateParser(mVCardType); 2449ec6c05a1dbb17862a44f96e91975dfc01cebf6eDaisuke Miyakawa if (mContentValuesVerifier != null) { 2459ec6c05a1dbb17862a44f96e91975dfc01cebf6eDaisuke Miyakawa final VCardEntryConstructor constructor = new VCardEntryConstructor(mVCardType); 2469ec6c05a1dbb17862a44f96e91975dfc01cebf6eDaisuke Miyakawa constructor.addEntryHandler(mContentValuesVerifier); 2479ec6c05a1dbb17862a44f96e91975dfc01cebf6eDaisuke Miyakawa parser.addInterpreter(constructor); 2489ec6c05a1dbb17862a44f96e91975dfc01cebf6eDaisuke Miyakawa } 2499ec6c05a1dbb17862a44f96e91975dfc01cebf6eDaisuke Miyakawa if (mPropertyNodesVerifier != null) { 2509ec6c05a1dbb17862a44f96e91975dfc01cebf6eDaisuke Miyakawa parser.addInterpreter(mPropertyNodesVerifier); 2519ec6c05a1dbb17862a44f96e91975dfc01cebf6eDaisuke Miyakawa } 2529ec6c05a1dbb17862a44f96e91975dfc01cebf6eDaisuke Miyakawa parser.parse(is); 2532c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng if (mExceptionContents != null) { 2542c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng // exception contents exists, we expect an exception to occur. 2552c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng AndroidTestCase.fail(); 2562c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng } 257a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa } catch (VCardException e) { 2582c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng if (mExceptionContents != null) { 2592c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng AndroidTestCase.assertTrue(e.getMessage().contains(mExceptionContents)); 2602c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng } else { 2612c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng Log.e(LOG_TAG, "VCardException", e); 2622c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng AndroidTestCase.fail("Unexpected VCardException: " + e.getMessage()); 2632c9cf383b1c956c7185e97c2417ebd85b48fc0acChiao Cheng } 264a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa } 265a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa } 266a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa 267a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa private void verifyOneVCardForExport(final String vcard) { 268677ef21613a9d35053ec098444832ce4125a847eDaisuke Miyakawa if (DEBUG) Log.d(LOG_TAG, vcard); 269a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa InputStream is = null; 270a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa try { 2714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa is = new ByteArrayInputStream(vcard.getBytes(mCharset)); 272a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa verifyWithInputStream(is); 2734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } catch (IOException e) { 274be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.fail("Unexpected IOException: " + e.getMessage()); 2754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } finally { 2764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (is != null) { 2774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa try { 2784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa is.close(); 2794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } catch (IOException e) { 280be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.fail("Unexpected IOException: " + e.getMessage()); 2814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 2864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public void verify() { 2874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (!mInitialized) { 288a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa TestCase.fail("Not initialized."); 2894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (mVerified) { 291a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa TestCase.fail("verify() was called twice."); 2924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 293a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa 2944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (mInputStream != null) { 295a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa if (mExportTestResolver != null){ 296a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa TestCase.fail("There are two input sources."); 2974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 298a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa verifyForImportTest(); 2994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else if (mExportTestResolver != null){ 3004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa verifyForExportTest(); 3014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else { 302a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa TestCase.fail("No input is determined"); 3034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 3044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mVerified = true; 3054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 3064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 307a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa private void verifyForImportTest() { 3084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (mLineVerifier != null) { 309be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.fail("Not supported now."); 3104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 311a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa 312a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa try { 313a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa verifyWithInputStream(mInputStream); 314a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa } catch (IOException e) { 315a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa AndroidTestCase.fail("IOException was thrown: " + e.getMessage()); 316a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa } finally { 317a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa if (mInputStream != null) { 318a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa try { 319a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa mInputStream.close(); 320a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa } catch (IOException e) { 321a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa } 322a76f41e328f31c2e9e9006160d8f65fe651eeb6aDaisuke Miyakawa } 3234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 3244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 3254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 3264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public static EntityIterator mockGetEntityIteratorMethod( 3274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final ContentResolver resolver, 3284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final Uri uri, final String selection, 3294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final String[] selectionArgs, final String sortOrder) { 3304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (ExportTestResolver.class.equals(resolver.getClass())) { 3314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return ((ExportTestResolver)resolver).getProvider().queryEntities( 3324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa uri, selection, selectionArgs, sortOrder); 3334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 3344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 3354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa Log.e(LOG_TAG, "Unexpected provider given."); 3364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return null; 3374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 3384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 3394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private Method getMockGetEntityIteratorMethod() 3404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa throws SecurityException, NoSuchMethodException { 3414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return this.getClass().getMethod("mockGetEntityIteratorMethod", 3424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa ContentResolver.class, Uri.class, String.class, String[].class, String.class); 3434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 3444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 3454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private void verifyForExportTest() { 3467e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawa final CustomMockContext context = new CustomMockContext(mExportTestResolver); 3477e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawa final ContentResolver resolver = context.getContentResolver(); 3487e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawa final VCardComposer composer = new VCardComposer(context, mVCardType, mCharset); 3497e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawa // projection is ignored. 3507e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawa final Cursor cursor = resolver.query(CONTACTS_TEST_CONTENT_URI, null, null, null, null); 3517e4e86eb5ad2c8a68ca7005ef4dee64a82ce0198Daisuke Miyakawa if (!composer.init(cursor)) { 352be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.fail("init() failed. Reason: " + composer.getErrorReason()); 3534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 354be378d5b188f51cf717e5309e3c39180e85833a8Daisuke Miyakawa AndroidTestCase.assertFalse(composer.isAfterLast()); 3554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa try { 3564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa while (!composer.isAfterLast()) { 35756174dfd0654acbe828e4db38537ec5a3a04d466Daisuke Miyakawa Method mockGetEntityIteratorMethod = null; 3584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa try { 35956174dfd0654acbe828e4db38537ec5a3a04d466Daisuke Miyakawa mockGetEntityIteratorMethod = getMockGetEntityIteratorMethod(); 3604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } catch (Exception e) { 36156174dfd0654acbe828e4db38537ec5a3a04d466Daisuke Miyakawa AndroidTestCase.fail("Exception thrown: " + e); 3624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 36356174dfd0654acbe828e4db38537ec5a3a04d466Daisuke Miyakawa AndroidTestCase.assertNotNull(mockGetEntityIteratorMethod); 36456174dfd0654acbe828e4db38537ec5a3a04d466Daisuke Miyakawa final String vcard = composer.createOneEntry(mockGetEntityIteratorMethod); 36556174dfd0654acbe828e4db38537ec5a3a04d466Daisuke Miyakawa AndroidTestCase.assertNotNull(vcard); 36656174dfd0654acbe828e4db38537ec5a3a04d466Daisuke Miyakawa if (mLineVerifier != null) { 36756174dfd0654acbe828e4db38537ec5a3a04d466Daisuke Miyakawa mLineVerifier.verify(vcard); 36856174dfd0654acbe828e4db38537ec5a3a04d466Daisuke Miyakawa } 36956174dfd0654acbe828e4db38537ec5a3a04d466Daisuke Miyakawa verifyOneVCardForExport(vcard); 3704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 3714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } finally { 3724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa composer.terminate(); 3734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 3744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 3754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa} 376