diff -r fd64c38c277d -r b46a585f6909 phonebookengines_old/contactsmodel/tsrc/T_GENERALADDRESS.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines_old/contactsmodel/tsrc/T_GENERALADDRESS.CPP Fri Jun 11 13:29:23 2010 +0300 @@ -0,0 +1,960 @@ +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +// System includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// User includes +#include "T_UTILS.H" + +// Flags +#define OOM_TESTS + +// Globals +static RTest TheTest(_L("T_GENERALADDRESS - Test General Address Export and Import")); +static CCntTest* TheTestHelper; + +// Type definitions +typedef void (*TGAFunction)(TBool& aPrintedTestTitle); + +// Constants +const TInt KIntContactFieldVCardMapGENERALADDRESS = 0; +const TUid KUidContactFieldVCardMapGENERALADDRESS = { KIntContactFieldVCardMapGENERALADDRESS }; + +// Literal constants +_LIT(KTestDatabaseFile, "C:GeneralAddressDatabase.cdb"); +// +_LIT(KTestNameFamily, "Bloggs"); +_LIT(KTestNameGiven, "Joe"); +// +_LIT(KTestAddressHOME, "_HOME"); +_LIT(KTestAddressWORK, "_WORK"); +_LIT(KTestAddressPREF, "_PREF"); +_LIT(KTestAddressGENERALADDRESS, "_GENERALADDRESS"); +// +_LIT(KTestAddressPOSTOFFICE, "POSTOFFICE"); +_LIT(KTestAddressEXTENDEDADR, "EXTENDEDADR"); +_LIT(KTestAddressADR, "ADR"); +_LIT(KTestAddressLOCALITY, "LOCALITY"); +_LIT(KTestAddressREGION, "REGION"); +_LIT(KTestAddressPOSTCODE, "POSTCODE"); +_LIT(KTestAddressCOUNTRY, "COUNTRY"); +// +_LIT(KTestVCardExportFileName, "C:\\T_GENERALADDRESS_EXPORTED.TXT"); +_LIT(KTestVCardImportFileName, "C:\\T_GENERALADDRESS_IMPORTED.TXT"); +// +_LIT8(KVersitParam8GeneralAddress, ""); + + +// Utility methods + +/** + * Create a simple contact with just the name fields populated + */ +static TContactItemId CreateContactL(CContactDatabase& aDatabase) + { + const TContactItemId templateId = aDatabase.TemplateId(); + // + CContactItem* templateCard = aDatabase.ReadContactLC(templateId); + CContactCard* card = CContactCard::NewL(templateCard); + CleanupStack::PushL(card); + // + SetNameL(*card, KUidContactFieldFamilyName, KUidContactFieldVCardMapUnusedN, KTestNameFamily, EFalse); + SetNameL(*card, KUidContactFieldGivenName, KUidContactFieldVCardMapUnusedN, KTestNameGiven, EFalse); + // + const TContactItemId id = aDatabase.AddNewContactL(*card); + CleanupStack::PopAndDestroy(2, templateCard); + return id; + } + +/** + * Combine a value and a postfix to create a real unified value + */ +static HBufC* ConstructAddressValueLC(const TDesC& aValue, const TDesC& aPostFix) + { + HBufC* value = HBufC::NewLC(aValue.Length() + aPostFix.Length()); + TPtr pValue(value->Des()); + pValue = aValue; + pValue.Append(aPostFix); + // + return value; + } + +/** + * Add a specific address field to a vCard + */ +static void AddAddressFieldL(CContactItem& aContact, TFieldType aFieldType, TUid aMapping, TFieldType aExtraFieldType, const TDesC& aValue, const TDesC& aValuePostFix) + { + CContentType* content = CContentType::NewL(aFieldType, aMapping); + CleanupStack::PushL(content); + content->AddFieldTypeL(aExtraFieldType); + // + CContactItemField* contactItemField = CContactItemField::NewLC(KStorageTypeText, *content); + // + HBufC* value = ConstructAddressValueLC(aValue, aValuePostFix); + // + contactItemField->TextStorage()->SetStandardTextL(*value); + CleanupStack::PopAndDestroy(value); + // + aContact.AddFieldL(*contactItemField); + CleanupStack::Pop(contactItemField); + // + CleanupStack::PopAndDestroy(content); + } + +/** + * Return the post fix descriptor for a given field type (HOME, WORK, PREF, General) + */ +static TPtrC PostFixForFieldType(TFieldType aType) + { + TPtrC postFix(KNullDesC); + switch(aType.iUid) + { + case KIntContactFieldVCardMapHOME: + postFix.Set(KTestAddressHOME); + break; + case KIntContactFieldVCardMapWORK: + postFix.Set(KTestAddressWORK); + break; + case KIntContactFieldVCardMapPREF: + postFix.Set(KTestAddressPREF); + break; + case KIntContactFieldVCardMapGENERALADDRESS: + postFix.Set(KTestAddressGENERALADDRESS); + break; + default: + TheTest(EFalse); + break; + } + // + return postFix; + } + +/** + * Add a specific address type to a contact card + */ +static void AddAddressL(CContactDatabase& aDatabase, TContactItemId aId, TFieldType aExtraFieldType) + { + const TPtrC postFix(PostFixForFieldType(aExtraFieldType)); + // + CContactItem* card = aDatabase.OpenContactLX(aId); + CleanupStack::PushL(card); + // + AddAddressFieldL(*card, KUidContactFieldPostOffice, KUidContactFieldVCardMapPOSTOFFICE, aExtraFieldType, KTestAddressPOSTOFFICE, postFix); + AddAddressFieldL(*card, KUidContactFieldExtendedAddress, KUidContactFieldVCardMapEXTENDEDADR, aExtraFieldType, KTestAddressEXTENDEDADR, postFix); + AddAddressFieldL(*card, KUidContactFieldAddress, KUidContactFieldVCardMapADR, aExtraFieldType, KTestAddressADR, postFix); + AddAddressFieldL(*card, KUidContactFieldLocality, KUidContactFieldVCardMapLOCALITY, aExtraFieldType, KTestAddressLOCALITY, postFix); + AddAddressFieldL(*card, KUidContactFieldRegion, KUidContactFieldVCardMapREGION, aExtraFieldType, KTestAddressREGION, postFix); + AddAddressFieldL(*card, KUidContactFieldPostcode, KUidContactFieldVCardMapPOSTCODE, aExtraFieldType, KTestAddressPOSTCODE, postFix); + AddAddressFieldL(*card, KUidContactFieldCountry, KUidContactFieldVCardMapCOUNTRY, aExtraFieldType, KTestAddressCOUNTRY, postFix); + // + aDatabase.CommitContactL(*card); + CleanupStack::PopAndDestroy(card); + CleanupStack::Pop(); // lock record + } + +/** + * Export a specific contact to a vCard file + */ +static void ExportContactAsVCardL(CContactDatabase& aDatabase, TContactItemId aId, RFs& aFsSession, const TDesC& aVCardFileName) + { + CContactIdArray* idArray = CContactIdArray::NewLC(); + idArray->AddL(aId); + // + RFile outfile; + const TInt error = outfile.Replace(aFsSession, aVCardFileName, EFileWrite); + User::LeaveIfError(error); + CleanupClosePushL(outfile); + // + RFileWriteStream writeStream(outfile); + CleanupClosePushL(writeStream); + // + const TUid KVersitVCardUid = { KUidVCardConvDefaultImpl }; + aDatabase.ExportSelectedContactsL(KVersitVCardUid, *idArray, writeStream, CContactDatabase::EDefault); + writeStream.CommitL(); + CleanupStack::PopAndDestroy(3, idArray); // writeStream, outfile, idArray + } + +/** + * Parse a file using the Symbian vCard parser and return the parsed data structures + * to the caller + */ +static CParserVCard* ParseVCardFileLC(RFs& aFsSession, const TDesC& aVCardFileName) + { + CParserVCard* parser = CParserVCard::NewL(); + CleanupStack::PushL(parser); + // + RFile readFile; + const TInt error = readFile.Open(aFsSession, aVCardFileName, EFileRead); + User::LeaveIfError(error); + CleanupClosePushL(readFile); + // + RFileReadStream readStream(readFile); + CleanupClosePushL(readStream); + parser->InternalizeL(readStream); + CleanupStack::PopAndDestroy(2); // readStream, readFile + // + return parser; + } + +/** + * Returns the property parameter name value used by Versit for this particular + * Contacts Model field type (E.g. HOME, WORK, PREF, etc). Returns KNullDesC in + * the case of General Address. Panic (fails the test) if the type is not recognised. + */ +static TPtrC8 VersitPropertyParameterNameForContactsModelFieldType(TFieldType aAddressType) + { + TPtrC8 propParamValue(KNullDesC8); + // + switch(aAddressType.iUid) + { + case KIntContactFieldVCardMapHOME: + propParamValue.Set(KVersitParam8Home); + break; + case KIntContactFieldVCardMapWORK: + propParamValue.Set(KVersitParam8Work); + break; + case KIntContactFieldVCardMapPREF: + propParamValue.Set(KVersitParam8Pref); + break; + case KIntContactFieldVCardMapGENERALADDRESS: + break; + default: + TheTest(EFalse); + break; + } + // + return propParamValue; + } + +/** + * Search a vCard property for the presence of a specific address type, e.g. HOME, WORK, PREF or "General" + */ +static TBool ValidateVCardPropertyForAddressType(const CParserProperty& aProperty, const TDesC8& aPropertyParameterType) + { + TBool validated = EFalse; + + // Have to perform more substancial checks if we're looking for just a general address... + if (aPropertyParameterType.Length()) + { + // HOME, WORK, PREF + validated = (aProperty.Param(aPropertyParameterType) != NULL); + } + else + { + // In the case of General Address, which won't have an associated property parameter + // we must check that none of the other types are present for this address. If none are + // matched, then this address can be considered general. + const TBool foundHOME = (aProperty.Param(KVersitParam8Home) != NULL); + const TBool foundWORK = (aProperty.Param(KVersitParam8Work) != NULL); + const TBool foundPREF = (aProperty.Param(KVersitParam8Pref) != NULL); + // + validated = !(foundHOME || foundWORK || foundPREF); + } + // + return validated; + } + +/** + * Check that the specified actual value found in the vCard matches the expected value + * which is constructed from the raw value and post fix. + */ +static TBool ValidateAddressSubFieldL(const TDesC& aActualValue, const TDesC& aExpectedRawValue, const TDesC& aPostFix) + { + HBufC* expectedValue = ConstructAddressValueLC(aExpectedRawValue, aPostFix); + const TBool match = (expectedValue->CompareF(aActualValue) == 0); + CleanupStack::PopAndDestroy(expectedValue); + // + return match; + } + +/** + * Check that the specified array contains exact matches for each of the 7 address + * sub field values. + */ +static TBool ValidateAddressSubFieldValuesL(const CDesCArray& aArray, const TDesC& aPostFix) + { + TPtrC actualValue; + // + actualValue.Set(aArray[0]); + if (!ValidateAddressSubFieldL(actualValue, KTestAddressPOSTOFFICE, aPostFix)) + return EFalse; + actualValue.Set(aArray[1]); + if (!ValidateAddressSubFieldL(actualValue, KTestAddressEXTENDEDADR, aPostFix)) + return EFalse; + actualValue.Set(aArray[2]); + if (!ValidateAddressSubFieldL(actualValue, KTestAddressADR, aPostFix)) + return EFalse; + actualValue.Set(aArray[3]); + if (!ValidateAddressSubFieldL(actualValue, KTestAddressLOCALITY, aPostFix)) + return EFalse; + actualValue.Set(aArray[4]); + if (!ValidateAddressSubFieldL(actualValue, KTestAddressREGION, aPostFix)) + return EFalse; + actualValue.Set(aArray[5]); + if (!ValidateAddressSubFieldL(actualValue, KTestAddressPOSTCODE, aPostFix)) + return EFalse; + actualValue.Set(aArray[6]); + if (!ValidateAddressSubFieldL(actualValue, KTestAddressCOUNTRY, aPostFix)) + return EFalse; + // + return ETrue; + } + +/** + * Check a vCard for the presence of a specific address type. Returns ETrue + * if the type is found within the vCard. + */ +static TBool ValidateVCardForAddressL(CParserVCard& aVCard, TFieldType aAddressType) + { + TBool validated = EFalse; + const TUid KVersitAddressPropertyValueType = { KVersitPropertyCDesCArrayUid }; + const TPtrC8 propValueType = VersitPropertyParameterNameForContactsModelFieldType(aAddressType); + // + CArrayPtr* properties = aVCard.PropertyL(KVersitTokenADR, KVersitAddressPropertyValueType, EFalse); + if (properties) + { + CleanupStack::PushL(properties); + const TInt count = properties->Count(); + for(TInt i=0; iAt(i); + if (ValidateVCardPropertyForAddressType(property, propValueType)) + { + // Next verify the property values + CParserPropertyValueCDesCArray* value = static_cast(property.Value()); + CDesCArray* array = value->Value(); + + // There must be 7 sub-fields + if (array->MdcaCount() == 7) + { + // Check each sub-field for the correct value + const TPtrC postFix = PostFixForFieldType(aAddressType); + validated = ValidateAddressSubFieldValuesL(*array, postFix); + } + } + } + CleanupStack::PopAndDestroy(properties); + } + return validated; + } + +/** + * Create a vCard N property and add it to the specified vCard parser object + */ +static void AddNameToVCardL(CParserVCard& aVCard) + { + // For the property value itself + CDesCArrayFlat* desArray = new (ELeave)CDesCArrayFlat(4); + CleanupStack::PushL(desArray); + + // Add the names + desArray->AppendL(KTestNameFamily); + desArray->AppendL(KTestNameGiven); + desArray->AppendL(KNullDesC); + desArray->AppendL(KNullDesC); + desArray->AppendL(KNullDesC); + + // Create the property value + CParserPropertyValue* value = new(ELeave) CParserPropertyValueCDesCArray(desArray); + CleanupStack::Pop(desArray); + CleanupStack::PushL(value); + // + CParserGroupedProperty* property = CParserGroupedProperty::NewL(*value, KVersitTokenN, NULL, NULL); + CleanupStack::Pop(value); // value + + // This pushes property before anything can leave... + aVCard.AddPropertyL(property); + } + +/** + * Combine the address data and the post fix to form a new combined address data value + * and append it to the specified array + */ +static void AddAddressSubFieldToArrayL(CDesCArray& aArray, const TDesC& aAddress, const TDesC& aPostFix) + { + HBufC* value = ConstructAddressValueLC(aAddress, aPostFix); + aArray.AppendL(*value); + CleanupStack::PopAndDestroy(value); + } + +/** + * Create a vCard ADR property and add it to the specified vCard parser object + */ +static void AddAddressToVCardL(CParserVCard& aVCard, const TDesC8& aAddressType) + { + // For the property parameters + CArrayPtr* arrayOfParams = new(ELeave) CArrayPtrFlat(5); + CleanupStack::PushL(TCleanupItem(CleanUpResetAndDestroy, arrayOfParams)); + + // If the address type is NULL then its a general address, in which case it doesn't + // need a property parameter. Otherwise, assume it does + if (aAddressType.Length()) + { + CParserParam* parserParam = CParserParam::NewL(aAddressType, KNullDesC); + CleanupStack::PushL(parserParam); + arrayOfParams->AppendL(parserParam); + CleanupStack::Pop(parserParam); + } + + // Create the value array + CDesCArrayFlat* desArray = new (ELeave)CDesCArrayFlat(4); + CleanupStack::PushL(desArray); + + // Pick the correct postfix + TPtrC postFix(KNullDesC); + if (aAddressType == KVersitParam8Home) + postFix.Set(KTestAddressHOME); + else if (aAddressType == KVersitParam8Work) + postFix.Set(KTestAddressWORK); + else if (aAddressType == KVersitParam8Pref) + postFix.Set(KTestAddressPREF); + else if (aAddressType == KVersitParam8GeneralAddress) + postFix.Set(KTestAddressGENERALADDRESS); + + // Add the names + AddAddressSubFieldToArrayL(*desArray, KTestAddressPOSTOFFICE, postFix); + AddAddressSubFieldToArrayL(*desArray, KTestAddressEXTENDEDADR, postFix); + AddAddressSubFieldToArrayL(*desArray, KTestAddressADR, postFix); + AddAddressSubFieldToArrayL(*desArray, KTestAddressLOCALITY, postFix); + AddAddressSubFieldToArrayL(*desArray, KTestAddressREGION, postFix); + AddAddressSubFieldToArrayL(*desArray, KTestAddressPOSTCODE, postFix); + AddAddressSubFieldToArrayL(*desArray, KTestAddressCOUNTRY, postFix); + + // Create the property value + CParserPropertyValue* value = new (ELeave) CParserPropertyValueCDesCArray(desArray); + CleanupStack::Pop(desArray); + CleanupStack::PushL(value); + + // And finally, the property itself + CParserGroupedProperty* property = CParserGroupedProperty::NewL(*value, KVersitTokenADR, NULL, arrayOfParams); + CleanupStack::Pop(2, arrayOfParams); // value, arrayOfParams + + // Add to vCard object - takes ownership of property immediately + aVCard.AddPropertyL(property); + } + +/** + * Create a simple vCard which contains only an N (Name) property + */ +static CParserVCard* CreateVCardLC() + { + CParserVCard* parser = CParserVCard::NewL(); + CleanupStack::PushL(parser); + // + AddNameToVCardL(*parser); + // + return parser; + } + +/** + * Export the specified vCard object to a file + */ +static void CreateVCardFileFromVCardObjectL(CParserVCard& aVCard, RFs& aFsSession, const TDesC& aVCardFileName) + { + RFile outfile; + const TInt error = outfile.Replace(aFsSession, aVCardFileName, EFileWrite); + User::LeaveIfError(error); + CleanupClosePushL(outfile); + // + RFileWriteStream writeStream(outfile); + CleanupClosePushL(writeStream); + // + aVCard.ExternalizeL(writeStream); + writeStream.CommitL(); + CleanupStack::PopAndDestroy(2); // writeStream, outfile + } + +/** + * Import the specified vCard to the contacts database and return the newly created contact item + */ +static CContactItem* ImportVCardLC(CContactDatabase& aDatabase, RFs& aFsSession, const TDesC& aVCardFileName) + { + RFile readFile; + const TInt error = readFile.Open(aFsSession, aVCardFileName, EFileRead); + User::LeaveIfError(error); + CleanupClosePushL(readFile); + // + RFileReadStream readStream(readFile); + CleanupClosePushL(readStream); + // + TBool importSuccessful = EFalse; + const TInt options = CContactDatabase::EDefault; + const TUid KVersitVCardUid = { KUidVCardConvDefaultImpl }; + // + CArrayPtr* contacts = aDatabase.ImportContactsL(KVersitVCardUid, readStream, importSuccessful, options); + CleanupStack::PopAndDestroy(2); // readStream, readFile + + // Check import results + TheTest(importSuccessful); + TheTest(contacts != NULL); + TheTest(contacts->Count() == 1); + + // Delete container, but not the contact itself + CContactItem* item = contacts->At(0); + CleanupStack::PushL(item); + delete contacts; + return item; + } + +/** + * Check the specified field set for the presence of a specific field which conforms + * to the specified address type + */ +static TBool LocateAddressFieldByType(CContactItemFieldSet& aFieldSet, TFieldType aFieldType, TUid aMapping, const TDesC& aExpectedValue, const TDesC& aExpectedPostFix) + { + TBool located = EFalse; + + // Locate field + TInt pos = KErrNotFound; + if (aFieldType != KNullUid) // KNullUid is for general address + pos = aFieldSet.Find(aFieldType, aMapping); + else + pos = aFieldSet.Find(aMapping); + // + if (pos != KErrNotFound) + { + // Make real value + HBufC* value = ConstructAddressValueLC(aExpectedValue, aExpectedPostFix); + + // Verify + CContactItemField& field = aFieldSet[pos]; + CContactTextField* storage = field.TextStorage(); + located = (storage->Text().CompareF(*value) == 0); + // + CleanupStack::PopAndDestroy(value); + } + // + return located; + } + +/** + * Check the specified contact card contains an address corresponding to the specified type + */ +static TBool ValidateContactForAddressTypeL(CContactItem& aContact, TFieldType aAddressType) + { + CContactItemFieldSet& fieldSet = aContact.CardFields(); + const TPtrC postFix(PostFixForFieldType(aAddressType)); + // + if (!LocateAddressFieldByType(fieldSet, aAddressType, KUidContactFieldVCardMapPOSTOFFICE, KTestAddressPOSTOFFICE, postFix)) + return EFalse; + if (!LocateAddressFieldByType(fieldSet, aAddressType, KUidContactFieldVCardMapEXTENDEDADR, KTestAddressEXTENDEDADR, postFix)) + return EFalse; + if (!LocateAddressFieldByType(fieldSet, aAddressType, KUidContactFieldVCardMapADR, KTestAddressADR, postFix)) + return EFalse; + if (!LocateAddressFieldByType(fieldSet, aAddressType, KUidContactFieldVCardMapLOCALITY, KTestAddressLOCALITY, postFix)) + return EFalse; + if (!LocateAddressFieldByType(fieldSet, aAddressType, KUidContactFieldVCardMapREGION, KTestAddressREGION, postFix)) + return EFalse; + if (!LocateAddressFieldByType(fieldSet, aAddressType, KUidContactFieldVCardMapPOSTCODE, KTestAddressPOSTCODE, postFix)) + return EFalse; + if (!LocateAddressFieldByType(fieldSet, aAddressType, KUidContactFieldVCardMapCOUNTRY, KTestAddressCOUNTRY, postFix)) + return EFalse; + // + return ETrue; + } + + +// Tests + +static void Test1L(TBool& aPrintedTestTitle) + { + if (!aPrintedTestTitle) + { + TheTest.Next(_L("EXPORT General address")); + + aPrintedTestTitle = ETrue; + } + // + RFs& fsSession = TheTestHelper->Fs(); + CContactDatabase& database = *TheTestHelper->Db(); + // + const TContactItemId contactId = CreateContactL(database); + AddAddressL(database, contactId, KUidContactFieldVCardMapGENERALADDRESS); + ExportContactAsVCardL(database, contactId, fsSession, KTestVCardExportFileName); + CParserVCard* parser = ParseVCardFileLC(fsSession, KTestVCardExportFileName); + TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapGENERALADDRESS)); + CleanupStack::PopAndDestroy(parser); + } + +static void Test2L(TBool& aPrintedTestTitle) + { + if (!aPrintedTestTitle) + { + TheTest.Next(_L("EXPORT General, Home address")); + + aPrintedTestTitle = ETrue; + } + // + RFs& fsSession = TheTestHelper->Fs(); + CContactDatabase& database = *TheTestHelper->Db(); + // + const TContactItemId contactId = CreateContactL(database); + AddAddressL(database, contactId, KUidContactFieldVCardMapGENERALADDRESS); + AddAddressL(database, contactId, KUidContactFieldVCardMapHOME); + ExportContactAsVCardL(database, contactId, fsSession, KTestVCardExportFileName); + CParserVCard* parser = ParseVCardFileLC(fsSession, KTestVCardExportFileName); + TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapGENERALADDRESS)); + TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapHOME)); + CleanupStack::PopAndDestroy(parser); + } + +static void Test3L(TBool& aPrintedTestTitle) + { + if (!aPrintedTestTitle) + { + TheTest.Next(_L("EXPORT General, Work address")); + + aPrintedTestTitle = ETrue; + } + // + RFs& fsSession = TheTestHelper->Fs(); + CContactDatabase& database = *TheTestHelper->Db(); + // + const TContactItemId contactId = CreateContactL(database); + AddAddressL(database, contactId, KUidContactFieldVCardMapGENERALADDRESS); + AddAddressL(database, contactId, KUidContactFieldVCardMapWORK); + ExportContactAsVCardL(database, contactId, fsSession, KTestVCardExportFileName); + CParserVCard* parser = ParseVCardFileLC(fsSession, KTestVCardExportFileName); + TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapGENERALADDRESS)); + TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapWORK)); + CleanupStack::PopAndDestroy(parser); + } + + +static void Test4L(TBool& aPrintedTestTitle) + { + if (!aPrintedTestTitle) + { + TheTest.Next(_L("EXPORT General, Home, Work address")); + + aPrintedTestTitle = ETrue; + } + // + RFs& fsSession = TheTestHelper->Fs(); + CContactDatabase& database = *TheTestHelper->Db(); + // + const TContactItemId contactId = CreateContactL(database); + AddAddressL(database, contactId, KUidContactFieldVCardMapGENERALADDRESS); + AddAddressL(database, contactId, KUidContactFieldVCardMapHOME); + AddAddressL(database, contactId, KUidContactFieldVCardMapWORK); + ExportContactAsVCardL(database, contactId, fsSession, KTestVCardExportFileName); + CParserVCard* parser = ParseVCardFileLC(fsSession, KTestVCardExportFileName); + TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapGENERALADDRESS)); + TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapHOME)); + TheTest(ValidateVCardForAddressL(*parser, KUidContactFieldVCardMapWORK)); + CleanupStack::PopAndDestroy(parser); + } + + +static void Test5L(TBool& aPrintedTestTitle) + { + if (!aPrintedTestTitle) + { + TheTest.Next(_L("IMPORT General address")); + + aPrintedTestTitle = ETrue; + } + // + RFs& fsSession = TheTestHelper->Fs(); + CContactDatabase& database = *TheTestHelper->Db(); + // + CParserVCard* vCard = CreateVCardLC(); + AddAddressToVCardL(*vCard, KVersitParam8GeneralAddress); + CreateVCardFileFromVCardObjectL(*vCard, fsSession, KTestVCardImportFileName); + CleanupStack::PopAndDestroy(vCard); + CContactItem* item = ImportVCardLC(database, fsSession, KTestVCardImportFileName); + TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapGENERALADDRESS)); + CleanupStack::PopAndDestroy(item); + } + +static void Test6L(TBool& aPrintedTestTitle) + { + if (!aPrintedTestTitle) + { + TheTest.Next(_L("IMPORT General, Home address")); + + aPrintedTestTitle = ETrue; + } + // + RFs& fsSession = TheTestHelper->Fs(); + CContactDatabase& database = *TheTestHelper->Db(); + // + CParserVCard* vCard = CreateVCardLC(); + AddAddressToVCardL(*vCard, KVersitParam8GeneralAddress); + AddAddressToVCardL(*vCard, KVersitParam8Home); + CreateVCardFileFromVCardObjectL(*vCard, fsSession, KTestVCardImportFileName); + CleanupStack::PopAndDestroy(vCard); + CContactItem* item = ImportVCardLC(database, fsSession, KTestVCardImportFileName); + TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapGENERALADDRESS)); + TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapHOME)); + CleanupStack::PopAndDestroy(item); + } + + +static void Test7L(TBool& aPrintedTestTitle) + { + if (!aPrintedTestTitle) + { + TheTest.Next(_L("IMPORT General, Work address")); + + aPrintedTestTitle = ETrue; + } + // + RFs& fsSession = TheTestHelper->Fs(); + CContactDatabase& database = *TheTestHelper->Db(); + // + CParserVCard* vCard = CreateVCardLC(); + AddAddressToVCardL(*vCard, KVersitParam8GeneralAddress); + AddAddressToVCardL(*vCard, KVersitParam8Work); + CreateVCardFileFromVCardObjectL(*vCard, fsSession, KTestVCardImportFileName); + CleanupStack::PopAndDestroy(vCard); + CContactItem* item = ImportVCardLC(database, fsSession, KTestVCardImportFileName); + TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapGENERALADDRESS)); + TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapWORK)); + CleanupStack::PopAndDestroy(item); + } + + +static void Test8L(TBool& aPrintedTestTitle) + { + if (!aPrintedTestTitle) + { + TheTest.Next(_L("IMPORT General, Home, Work address")); + + aPrintedTestTitle = ETrue; + } + RFs& fsSession = TheTestHelper->Fs(); + CContactDatabase& database = *TheTestHelper->Db(); + // + CParserVCard* vCard = CreateVCardLC(); + AddAddressToVCardL(*vCard, KVersitParam8GeneralAddress); + AddAddressToVCardL(*vCard, KVersitParam8Home); + AddAddressToVCardL(*vCard, KVersitParam8Work); + CreateVCardFileFromVCardObjectL(*vCard, fsSession, KTestVCardImportFileName); + CleanupStack::PopAndDestroy(vCard); + CContactItem* item = ImportVCardLC(database, fsSession, KTestVCardImportFileName); + TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapGENERALADDRESS)); + TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapHOME)); + TheTest(ValidateContactForAddressTypeL(*item, KUidContactFieldVCardMapWORK)); + CleanupStack::PopAndDestroy(item); + } + +static void RunListOfTestsL(const RArray& aTests) + { + TBool printedTestTitle = EFalse; + const TInt count = aTests.Count(); + for(TInt i=0; iCreateDatabaseL(); + TRAPD(err, (*test)(printedTestTitle)); + + // Ensure that we close the database if a leave occurs or + // else the OOM test code thinks we've leaked it + TheTestHelper->CloseDatabase(); + + // Cascade error + User::LeaveIfError(err); + + printedTestTitle = EFalse; + } + } + +static void TestExportL() + { + RArray array; + CleanupClosePushL(array); + // + User::LeaveIfError(array.Append(static_cast(Test1L))); + User::LeaveIfError(array.Append(static_cast(Test2L))); + User::LeaveIfError(array.Append(static_cast(Test3L))); + User::LeaveIfError(array.Append(static_cast(Test4L))); + // + RunListOfTestsL(array); + // + CleanupStack::PopAndDestroy(&array); + } + +static void TestImportL() + { + RArray array; + CleanupClosePushL(array); + // + User::LeaveIfError(array.Append(static_cast(Test5L))); + User::LeaveIfError(array.Append(static_cast(Test6L))); + User::LeaveIfError(array.Append(static_cast(Test7L))); + User::LeaveIfError(array.Append(static_cast(Test8L))); + // + RunListOfTestsL(array); + // + CleanupStack::PopAndDestroy(&array); + } + + +static void RunTestsL() + { + TRAPD(errExport, TestExportL()); + TheTest(errExport == KErrNone || errExport == KErrNoMemory); + // + TRAPD(errImport, TestImportL()); + TheTest(errImport == KErrNone || errImport == KErrNoMemory); + } + +#ifdef OOM_TESTS + +static void ExpandCleanupStackL() + { + // Reserve some space on the cleanup stack: + { + for (TInt ii=0;ii<1000;++ii) + CleanupStack::PushL(&ii); + } + CleanupStack::Pop(1000); + } + +static void PrepareTestSkipsL(RArray& aSkipArray, TInt aCount, ...) + { + aSkipArray.Reset(); + // + VA_LIST list; + VA_START(list, aCount); + // + TInt* startPtr = reinterpret_cast(&list); // Same as list[0] + for(TInt i=0; i& aSkipArray) + { + // + TBool printedTestTitle = EFalse; + TInt ret = KErrNoMemory; + TInt failAt = 0; + while(ret != KErrNone) + { + failAt += failAt/50 + 1; + TheTest.Printf(_L("OOM step: %d\n"), failAt); + if (aSkipArray.Find(failAt) != KErrNotFound) + continue; + // + __UHEAP_MARK; + TheTestHelper->CreateDatabaseL(); + + __UHEAP_SETFAIL(RHeap::EDeterministic, failAt); + TRAP(ret, aFunction(printedTestTitle)); + __UHEAP_RESET; + + // Ensure that we close the database + TheTestHelper->CloseDatabase(); + + + __UHEAP_MARKEND; + // + if (ret != KErrNoMemory && ret != KErrNone) + { + TheTest.Printf(_L("Non standard error: %d\n"),ret); + TheTest.Getch(); + } + TheTest(ret == KErrNoMemory || ret == KErrNone); + } + // + return KErrNone; + } + +static void RunOOMTestsL() + { + ExpandCleanupStackL(); + // + RArray knownFailures; + CleanupClosePushL(knownFailures); + + // EXPORT + PrepareTestSkipsL(knownFailures, 0); + RunOOMTestL(Test1L, knownFailures); + // + // (Skip OOM on Test2L, Test3L and Test4L as they execute the same code as Test1L) + + // IMPORT + PrepareTestSkipsL(knownFailures, 0); + RunOOMTestL(Test5L, knownFailures); + // + // (Skip OOM on Test6L, Test7L and Test8L as they execute the same code as Test5L) + + CleanupStack::PopAndDestroy(&knownFailures); + } +#endif + +static void DoMainL() + { + CTestRegister* TempFiles = CTestRegister::NewLC(); + TempFiles->RegisterL(KTestDatabaseFile, EFileTypeCnt); + TempFiles->RegisterL(KTestVCardExportFileName); + TempFiles->RegisterL(KTestVCardImportFileName); + + // Run normal testing + TRAPD(testRet, RunTestsL()); + TheTest(testRet == KErrNone); + + // Run OOM testing +#ifdef OOM_TESTS + TRAPD(oomRet, RunOOMTestsL()); + TheTest(oomRet == KErrNone); +#endif + + CleanupStack::PopAndDestroy(TempFiles); + } + +/** + +@SYMTestCaseID PIM-T-GENERALADDRESS-0001 + +*/ + +GLDEF_C TInt E32Main() + { + __UHEAP_MARK; + TheTest.Start(_L("@SYMTESTCaseID:PIM-T-GENERALADDRESS-0001 T_GENERALADDRESS - Test General Address Export and Import")); + + + // Stupid test library alert... + TheTestHelper = new(ELeave) CCntTest(); + TheTestHelper->ConstructL(TheTest, KTestDatabaseFile); + + TRAP_IGNORE(DoMainL()); + // + TheTestHelper->EndTestLib(KErrNone); + // + __UHEAP_MARKEND; + return(KErrNone); + }