pimappsupport/vcardandvcal/tsrc/tvgen.cpp
changeset 0 f979ecb2b13e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pimappsupport/vcardandvcal/tsrc/tvgen.cpp	Tue Feb 02 10:12:19 2010 +0200
@@ -0,0 +1,730 @@
+// Copyright (c) 1999-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:
+// Versit tests
+// 
+//
+
+// System includes
+#include <bautils.h>
+#include <e32test.h>
+#include <s32file.h>
+#include <e32math.h>
+#include <versit.h>
+#include <vprop.h>
+#include <vuid.h>
+#include <vcard.h>
+#include <vcal.h>
+
+// User includes
+#include "thelpers.h"
+
+//
+// STRUCTS
+//
+struct TPropertyDef
+	{
+	HBufC8*				iPropertyName;
+	TInt				iNumberOfValuesExpected;		// only used by array items
+	TUint32				iType;
+	};
+
+
+struct TPropertyParameterDef
+	{
+	HBufC8*				iParameterName;
+	HBufC8*				iParameterValue;
+	};
+
+
+//
+// GLOBAL DATA
+//
+LOCAL_D RTest									gTest(_L("TVERSIT2"));
+LOCAL_D CTrapCleanup*							gCleanup;
+LOCAL_D RFs										gFsSession;
+
+LOCAL_D CArrayFixFlat<TPropertyParameterDef>*	gParameterDefinitions;
+LOCAL_D CArrayFixFlat<TPropertyDef>*			gPropertyDefinitions;
+
+LOCAL_D CArrayFixFlat<TDateTime>*				gDateTimeArray;
+LOCAL_D CDesCArrayFlat*							gTextArray;
+
+LOCAL_D TInt64									gSeed;
+
+
+//
+// vCard files & directories needed for this test code
+//
+
+// Source vCards that are randomly generated by this code - they are written in this directory
+// for reference (this is the output exactly as it was generated)
+_LIT(KDirRandomlyGeneratedOut,			"C:\\vCards\\RandomlyGenerated\\Original\\");
+
+// This is the the vCard ouput that has been read in from the directory above and then
+// written back out to file without any modifications. They should theoretically be identical
+// (except any CHARSET parameters are removed, as this means that the original and newly created
+// vCard may potentially be encoded in different ways making comparison difficult).
+_LIT(KDirRandomlyGeneratedIn,			"C:\\vCards\\RandomlyGenerated\\ReadInAndThenWrittenOut\\");
+
+// This is the name of the vCard generated to be unique in the directory.
+_LIT(KNameGeneratedVCardName,			"vCard_for_test_%d");
+_LIT(KNameGeneratedVCardExtension,		".vcf");
+_LIT(KNameDeleteFileSpec,				"*.vcf");
+
+// This is the name of the log file generated for errors 
+_LIT(KNameErrorLogfile,"c:\\tvgen.log");
+
+//
+// Other contants
+//
+_LIT(KFailureDescription,		"Failed on %S tag\n");
+_LIT(KTestIndicator,			"Test [%d] about to commence\n");
+_LIT(KTestIndicatorSeparator,	"=================================\n\n");
+const TInt KMinNumberOfTestsToPerform = 100;
+const TInt KMaxNumberOfTestsToPerform = 100;
+
+
+//****************************************************************************************
+LOCAL_C void CreateArraysL()
+	{
+	gParameterDefinitions	= new(ELeave) CArrayFixFlat<TPropertyParameterDef>(10);
+	gPropertyDefinitions	= new(ELeave) CArrayFixFlat<TPropertyDef>(10);
+	gTextArray				= new(ELeave) CDesCArrayFlat(10);
+	gDateTimeArray			= new(ELeave) CArrayFixFlat<TDateTime>(10);
+	}
+
+
+//****************************************************************************************
+LOCAL_C void DestroyArraysL()
+	{
+	TInt count = gParameterDefinitions->Count();
+	for(TInt i=0; i<count; i++)
+		{
+		TPropertyParameterDef& def = gParameterDefinitions->At(i);
+		delete def.iParameterName;	def.iParameterName = NULL;
+		delete def.iParameterValue;	def.iParameterValue= NULL;
+		}
+
+	count = gPropertyDefinitions->Count();
+	for(TInt j=0; j<count; j++)
+		{
+		TPropertyDef& def = gPropertyDefinitions->At(j);
+		delete def.iPropertyName;	def.iPropertyName = NULL;
+		}
+
+	delete gPropertyDefinitions;
+	delete gParameterDefinitions;
+	delete gTextArray;
+	delete gDateTimeArray;
+	}
+
+
+//****************************************************************************************
+LOCAL_C void CreatePropertyParamL(const TDesC8& aParamName, const TDesC8& aParamValue)
+	{
+	TInt amountToPop = 1;
+	TPropertyParameterDef def;
+	def.iParameterName			= aParamName.AllocL();
+	CleanupStack::PushL(def.iParameterName);
+
+	if	(aParamValue.Length())
+		{
+		def.iParameterValue		= aParamValue.AllocL();
+		CleanupStack::PushL(def.iParameterValue);
+		amountToPop = 2;
+		}
+	else
+		def.iParameterValue = NULL;
+
+	gParameterDefinitions->AppendL(def);
+	
+	CleanupStack::Pop(amountToPop);
+	}
+
+
+//****************************************************************************************
+LOCAL_C void CreatePropertyDefinitionL(const TDesC8& aName, TUint32 aExpectedType, TInt aValueCount)
+	{
+	TPropertyDef def;
+	def.iNumberOfValuesExpected	= aValueCount;
+	def.iType					= aExpectedType;
+	def.iPropertyName			= aName.AllocL();
+	CleanupStack::PushL(def.iPropertyName);
+	gPropertyDefinitions->AppendL(def);
+	CleanupStack::Pop();
+	}
+
+
+//****************************************************************************************
+LOCAL_C TBool CheckWhetherPropertyAlreadyExistsL(CVersitParser* aParser, const TDesC8& aPropertyName)
+	{
+	CArrayPtr<CParserProperty>* propertyArray = aParser->ArrayOfProperties(EFalse); // don't take ownership
+	if	(!propertyArray)
+		return EFalse;
+	
+	const TInt count = propertyArray->Count();
+	for(TInt i=0; i<count; i++)
+		{
+		if	(propertyArray->At(i)->Name() == aPropertyName)
+			return ETrue;
+		}
+	return EFalse;
+	}
+
+
+//****************************************************************************************
+LOCAL_C void CreatePropertyValuesL()
+	{
+	// Simple text items
+	gTextArray->AppendL(_L("symbian.foundation@exp.example.test"));
+	gTextArray->AppendL(_L("me@here.com"));
+	gTextArray->AppendL(_L("this@there.com"));
+	gTextArray->AppendL(_L("1 Example Road Example Town ZZ99 EXP"));
+	gTextArray->AppendL(_L("Somewhere Road Example Town ZZ99 EXP"));
+	gTextArray->AppendL(_L("wibble"));
+	gTextArray->AppendL(_L("@@me@@here@@.com"));
+	gTextArray->AppendL(_L("01632 575 24211 10"));
+	gTextArray->AppendL(_L("5757847=====d98==y"));
+	gTextArray->AppendL(_L("@@me@@here@@.com"));
+	gTextArray->AppendL(_L("01632 575==24211"));
+	gTextArray->AppendL(_L("557895789æ?øö!¦µØ"));
+	gTextArray->AppendL(_L("item1"));
+	gTextArray->AppendL(_L("item2"));
+	gTextArray->AppendL(_L("item3"));
+	gTextArray->AppendL(_L("item4"));
+	gTextArray->AppendL(_L("item5"));
+	gTextArray->AppendL(_L("Some house"));
+	gTextArray->AppendL(_L("called some name"));
+	gTextArray->AppendL(_L("at some address"));
+	gTextArray->AppendL(_L("in this place"));
+	gTextArray->AppendL(_L("UK"));
+	gTextArray->AppendL(_L("testing multi"));
+	gTextArray->AppendL(_L("lines of text"));
+	gTextArray->AppendL(_L("addresses"));
+	gTextArray->AppendL(_L("with post;code"));
+	gTextArray->AppendL(_L("Firstname"));
+	gTextArray->AppendL(_L("Lastname"));
+	gTextArray->AppendL(_L("namefirst"));
+	gTextArray->AppendL(_L("namelast"));
+	gTextArray->AppendL(_L("246256265"));
+	gTextArray->AppendL(_L("/3/3/3/3"));
+	gTextArray->AppendL(_L("+=+=+==="));
+	gTextArray->AppendL(_L("+1+1=244=]1/2234"));
+
+	// Date items
+	TDateTime time(1999, EOctober, 15, 12, 53, 0, 0);
+	gDateTimeArray->AppendL(time);
+	time.SetYear(2000); time.SetMonth(EJanuary); time.SetDay(2);
+	gDateTimeArray->AppendL(time);
+	time.SetYear(1); time.SetMonth(EAugust); time.SetDay(10);
+	gDateTimeArray->AppendL(time);
+	time.SetYear(9999); time.SetMonth(EDecember); time.SetDay(20);
+	gDateTimeArray->AppendL(time);
+
+	// Date Time
+	TDateTime time2(1999, EOctober, 15, 12, 53, 0, 0);
+	gDateTimeArray->AppendL(time2);
+	time2.SetYear(2000); time2.SetHour(18); time2.SetMonth(EJanuary);
+	gDateTimeArray->AppendL(time2);
+	time2.SetYear(1); time2.SetHour(0); time2.SetMonth(EJanuary); time2.SetMinute(1);
+	gDateTimeArray->AppendL(time2);
+	time2.SetYear(9999); time2.SetHour(23); time2.SetMinute(59); time2.SetSecond(59);
+	gDateTimeArray->AppendL(time2);
+	}
+
+
+//****************************************************************************************
+LOCAL_C void CreatePropertyParametersL()
+	{
+	// Misc params
+	CreatePropertyParamL(_L8("WORK"), _L8(""));
+	CreatePropertyParamL(_L8("HOME"), _L8(""));
+	CreatePropertyParamL(_L8("INTERNET"), _L8(""));
+	CreatePropertyParamL(_L8("DEFAULT"), _L8(""));
+	CreatePropertyParamL(_L8("FAX"), _L8(""));
+	CreatePropertyParamL(_L8("CELL"), _L8(""));
+	CreatePropertyParamL(_L8("VOICE"), _L8(""));
+	CreatePropertyParamL(_L8("MOBILE"), _L8(""));
+	CreatePropertyParamL(_L8("PARCEL"), _L8(""));
+	CreatePropertyParamL(_L8("AVI"), _L8(""));
+	CreatePropertyParamL(_L8("MPEG"), _L8(""));
+	CreatePropertyParamL(_L8("GIF"), _L8(""));
+
+	/*
+	CreatePropertyParamL(_L("ENCODING"), _L("8-BIT"));
+	CreatePropertyParamL(_L("ENCODING"), _L("BASE64"));
+	CreatePropertyParamL(_L("ENCODING"), _L("QUOTED-PRINTABLE"));
+	CreatePropertyParamL(_L("CHARSET"), _L("UTF-8"));
+	CreatePropertyParamL(_L("CHARSET"), _L("UTF-7"));
+	CreatePropertyParamL(_L("CHARSET"), _L("ISO-8859-1"));
+	CreatePropertyParamL(_L("CHARSET"), _L("ISO-8859-2"));
+	CreatePropertyParamL(_L("CHARSET"), _L("ISO-8859-5"));
+	CreatePropertyParamL(_L("CHARSET"), _L("ISO-8859-9"));
+	*/
+
+	CreatePropertyParamL(_L8("CHARSET"), _L8("ASCII"));
+	CreatePropertyParamL(_L8("LANGUAGE"), _L8("en"));
+	CreatePropertyParamL(_L8("LANGUAGE"), _L8("fr-CA"));
+
+	// Epoc extended labels
+	CreatePropertyParamL(_L8("X-EPOCCNTMODELFIELDLABEL"), _L8("Misc"));
+	CreatePropertyParamL(_L8("X-EPOCCNTMODELFIELDLABEL"), _L8("Wibble"));
+	CreatePropertyParamL(_L8("X-EPOCCNTMODELFIELDLABEL"), _L8("Wobble"));
+	CreatePropertyParamL(_L8("X-EPOCCNTMODELFIELDLABEL"), _L8("This"));
+	CreatePropertyParamL(_L8("X-EPOCCNTMODELFIELDLABEL"), _L8("That"));
+	CreatePropertyParamL(_L8("X-EPOCCNTMODELFIELDLABEL"), _L8("Work address"));
+	CreatePropertyParamL(_L8("X-EPOCCNTMODELFIELDLABEL"), _L8("Home address"));
+	CreatePropertyParamL(_L8("X-EPOCCNTMODELFIELDLABEL"), _L8("Moble phone"));
+	CreatePropertyParamL(_L8("X-EPOCCNTMODELFIELDLABEL"), _L8("Epoc"));
+	CreatePropertyParamL(_L8("X-EPOCCNTMODELFIELDLABEL"), _L8("Symbian"));
+	CreatePropertyParamL(_L8("X-EPOCCNTMODELFIELDLABEL"), _L8("Psion"));
+	CreatePropertyParamL(_L8("X-EPOCCNTMODELFIELDLABEL"), _L8("Palm"));
+	CreatePropertyParamL(_L8("X-EPOCCNTMODELFIELDLABEL"), _L8("App Engines"));
+	}
+
+
+//****************************************************************************************
+LOCAL_C void CreatePropertyDefinitionsL()
+	{	
+	CreatePropertyDefinitionL(_L8("FN"),			KVersitPropertyHBufCUid,		1);
+	CreatePropertyDefinitionL(_L8("N"),			KVersitPropertyCDesCArrayUid,	2);
+	CreatePropertyDefinitionL(_L8("ADR"),		KVersitPropertyCDesCArrayUid,	5);
+	CreatePropertyDefinitionL(_L8("TITLE"),		KVersitPropertyHBufCUid,		1);
+	CreatePropertyDefinitionL(_L8("TEL"),		KVersitPropertyHBufCUid,		1);
+	CreatePropertyDefinitionL(_L8("EMAIL"),		KVersitPropertyHBufCUid,		1);
+	CreatePropertyDefinitionL(_L8("ROLE"),		KVersitPropertyHBufCUid,		1);
+	CreatePropertyDefinitionL(_L8("LABEL"),		KVersitPropertyHBufCUid,		1);
+	CreatePropertyDefinitionL(_L8("URL"),		KVersitPropertyHBufCUid,		1);
+	CreatePropertyDefinitionL(_L8("ORG"),		KVersitPropertyCDesCArrayUid,	1);
+	CreatePropertyDefinitionL(_L8("BDAY"),		KVersitPropertyDateUid,			1);
+	CreatePropertyDefinitionL(_L8("NOTE"),		KVersitPropertyHBufCUid,		1);
+	CreatePropertyDefinitionL(_L8("VERSION"),	KVersitPropertyHBufCUid,		1);
+	CreatePropertyDefinitionL(_L8("REV"),		KVersitPropertyDateTimeUid,		1);
+	}
+
+
+//****************************************************************************************
+LOCAL_C void CreateUserDefinedPropertyDefinitionsL()
+	{	
+	CreatePropertyDefinitionL(_L8("X-WVID"),			KVersitPropertyHBufCUid,		1);
+	CreatePropertyDefinitionL(_L8("X-MYPROP"),			KVersitPropertyHBufCUid,		1);	
+	}
+
+//****************************************************************************************
+LOCAL_C CParserPropertyValue* GetRandomPropertyValueL(TUint32 aType, TInt aNumberOfValues /*for array parameters*/)
+	{
+	TInt randomIndex = KErrNotFound;
+	switch (aType)
+		{
+		case KVersitPropertyHBufCUid:
+			{
+			randomIndex = VTestHelpers::MakeRandomNumber(0, gTextArray->Count()-1, gSeed);
+			return VTestHelpers::CreateTextPropertyValueL((*gTextArray)[randomIndex]);
+			}
+
+		case KVersitPropertyDateTimeUid:
+			{
+			randomIndex = VTestHelpers::MakeRandomNumber(0, gDateTimeArray->Count()-1, gSeed);
+			return VTestHelpers::CreateDateTimePropertyValueL((*gDateTimeArray)[randomIndex]);
+			}
+
+		case KVersitPropertyDateUid:
+			{
+			randomIndex = VTestHelpers::MakeRandomNumber(0, gDateTimeArray->Count()-1, gSeed);
+			return VTestHelpers::CreateDatePropertyValueL((*gDateTimeArray)[randomIndex]);
+			}
+
+		case KVersitPropertyCDesCArrayUid:
+			{
+			CDesCArray* array = NULL;
+			if (aNumberOfValues>0)
+				array = new(ELeave) CDesCArrayFlat(5);
+			TInt length=0;
+			TBool addSpace;
+			for(TInt i=0; i<aNumberOfValues; i++)
+				{
+				randomIndex = VTestHelpers::MakeRandomNumber(0, gTextArray->Count()-1, gSeed);
+				length+=(*gTextArray)[randomIndex].Length();
+				addSpace=(length>15);
+				if (addSpace)
+					length=0;
+				VTestHelpers::CreateDescriptorArrayL((*gTextArray)[randomIndex], array, addSpace);
+				}
+			CParserPropertyValueCDesCArray* propertyValue = VTestHelpers::CreateArrayPropertyValueL(array);
+			return propertyValue;
+			}
+
+		default:
+			User::Panic(_L("TVGen"), 0);
+			return NULL; // never reached
+		}
+	}
+
+
+//****************************************************************************************
+LOCAL_C CVersitParser* CreateVCardObjectLC()
+	{
+	// Crete vCard object
+
+	CVersitParser* parser = CParserVCard::NewL();
+	CleanupStack::PushL(parser);
+
+	const TInt KRandomNumberOfProperties = VTestHelpers::MakeRandomNumber(4, gPropertyDefinitions->Count()-1, gSeed);
+	const TInt maxLineLength=KMaxExternalizedTokenLength/3+1;
+	const TInt maxLineLength2=KMaxExternalizedTokenLength/2;
+	TInt lineLength=0;		//To stop a warning
+
+	for(TInt i=0; i<KRandomNumberOfProperties; i++)
+		{
+		// First of all pick a random property name from the property name array...
+		TInt randomNameIndex = -1;
+		TBool propertyIsValid = EFalse;
+		for(TInt j=0; j<gPropertyDefinitions->Count(); j++)
+			{
+			randomNameIndex = VTestHelpers::MakeRandomNumber(0, gPropertyDefinitions->Count()-1, gSeed); 
+			TPtrC8 name(*gPropertyDefinitions->At(randomNameIndex).iPropertyName);
+			if	(!CheckWhetherPropertyAlreadyExistsL(parser, name))
+				{
+				propertyIsValid = ETrue;
+				lineLength=name.Length()+1;
+				break;
+				}
+			}
+
+		if	(!propertyIsValid)
+			return parser; // no more unique properties to be added
+
+		// We've now established that "name" is unique in the current list of properties, so the 
+		// next step is to populate this property with random parameter data...
+		TInt randomNumberOfParametersToAdd = VTestHelpers::MakeRandomNumber(0, gParameterDefinitions->Count()-1, gSeed);
+		CArrayPtr<CParserParam>* arrayOfParams = NULL;
+		if	(randomNumberOfParametersToAdd)
+			{
+			arrayOfParams = new(ELeave) CArrayPtrFlat<CParserParam>(randomNumberOfParametersToAdd);
+			CleanupStack::PushL(arrayOfParams);
+			}
+		TInt oldLineLength;
+		for(TInt k=0; k<randomNumberOfParametersToAdd && lineLength<maxLineLength; k++)
+			{
+			// Get a random property
+			TPropertyParameterDef def = gParameterDefinitions->At(VTestHelpers::MakeRandomNumber(0, gParameterDefinitions->Count()-1, gSeed));
+			
+			// Check whether this property has already been added
+			if	(VTestHelpers::DoesParameterAlreadyExist(arrayOfParams, *def.iParameterName))
+				continue; // get another param as this one is already been added to the array
+
+			//CParserParam* param = CParserParam::NewL(*def.iParameterName,def.iParameterValue);
+			TPtr8 value(NULL,0);
+			oldLineLength=lineLength;
+			lineLength+=def.iParameterName->Length()+1;
+			if (def.iParameterValue)
+				{
+				value.Set(def.iParameterValue->Des());
+				lineLength+=def.iParameterValue->Length()+1;
+				}
+			if (lineLength>maxLineLength2)
+				{
+				lineLength=oldLineLength;
+				continue;
+				}
+			CParserParam* param = CParserParam::NewL(*def.iParameterName,value);
+			CleanupStack::PushL(param);
+			arrayOfParams->AppendL(param);
+			CleanupStack::Pop();
+			}
+
+
+		// Now generate a suitable property name & value pair for this property
+		TPropertyDef def			= gPropertyDefinitions->At(randomNameIndex);
+		CParserPropertyValue* value	= GetRandomPropertyValueL(def.iType, def.iNumberOfValuesExpected);
+		CParserProperty* property	= CParserProperty::NewL(*value, *def.iPropertyName, arrayOfParams);
+		parser->AddPropertyL(property); // will push on the cleanupstack and then pop off if no problem... odd, but thats the way it was written!
+
+		if	(randomNumberOfParametersToAdd)
+			CleanupStack::Pop(); // arrayOfParams
+		}
+
+	return parser;
+	}
+
+
+void DoWriteVCardToFileL(CVersitParser* aParserObject, const TDesC& aFileName)
+	{
+	RFile outputFile;
+	User::LeaveIfError(outputFile.Replace(gFsSession, aFileName, EFileShareExclusive | EFileStream | EFileWrite));
+	aParserObject->ExternalizeL(outputFile);
+	outputFile.Close();
+	}
+
+void WriteVCardToFile(CVersitParser* aParserObject, TInt aTestNumber, TDes& aFileName)
+	{
+	const TUint KAppendChar = '_';
+
+	// Generate the first bit of a unique filename
+	TInt repetitions = 0;
+	TFileName out;
+	do
+		{
+		aFileName.Format(KNameGeneratedVCardName, aTestNumber);
+		aFileName.AppendFill(KAppendChar, repetitions++);
+		aFileName += KNameGeneratedVCardExtension;
+		out += KDirRandomlyGeneratedOut;
+		out += aFileName;
+		} while(BaflUtils::FileExists(gFsSession, out));
+
+	DoWriteVCardToFileL(aParserObject, out);
+
+	// At this point we need to remove all ocurrances of the CHARSET tag as this messes
+	// up the comparison when the text is written to file and then streamed in again later.
+
+	CArrayPtr<CParserProperty>* properties = aParserObject->ArrayOfProperties(EFalse);
+	TInt propCount = properties->Count();
+	for(TInt i=0; i<propCount; i++)
+		{
+		STATIC_CAST(CParserPropertyWithoutCharsetTags*, properties->At(i))->RemoveAllCharsetTagsFromParametersL();
+		}
+
+	DoWriteVCardToFileL(aParserObject, _L("C:\\Test.vcf"));
+	}
+
+
+CVersitParser* ReadVCardFromFileLC(const TDesC& aFileName)
+	{
+	// Read in the written out file and then write it out straight away so that a comparison
+	// may be made manually if required.
+	// Then read in the 
+	TFileName file(KDirRandomlyGeneratedOut);
+	file += aFileName;
+
+	TInt bytesThroughFile = 0;
+	RFile inputFile;
+	User::LeaveIfError(inputFile.Open(gFsSession, file, EFileShareReadersOnly | EFileStream | EFileRead));
+
+	CVersitParser* readParser = CParserVCard::NewL();
+	CleanupStack::PushL(readParser);
+	readParser->InternalizeL(inputFile, bytesThroughFile);
+	inputFile.Close();
+
+	file  = KDirRandomlyGeneratedIn;
+	file += aFileName;
+	DoWriteVCardToFileL(readParser, file);
+
+	return readParser;
+	}
+
+
+TBool CreateVCardL(TInt aTestNumber, TFileText& aLogFile)
+	{
+	// Create a fully populated vCard.
+	CVersitParser* parser = CreateVCardObjectLC();
+
+	// Write the vCard to a file whilst obtaining the filename of the file written to
+	TFileName file;
+	WriteVCardToFile(parser, aTestNumber, file);
+
+	// Read the vCard from a file
+	CVersitParser* readParser = ReadVCardFromFileLC(file);
+
+	// Get a list of properties read from the file and from the artifically created vCard
+	CArrayPtr<CParserProperty>*	readProperties	= readParser->ArrayOfProperties(EFalse);
+	CArrayPtr<CParserProperty>*	properties		= parser->ArrayOfProperties(EFalse);
+
+	// Test that the property count is the same
+	TInt count = readProperties->Count();
+	gTest(count == properties->Count());
+
+	// Compare the properties one by one
+	TBool passedTest = ETrue;
+	for(TInt i=0; i<count; i++)
+		{
+		CComparitorParserProperty* property = STATIC_CAST(CComparitorParserProperty*, properties->At(i));
+		CComparitorParserProperty* readProperty = STATIC_CAST(CComparitorParserProperty*, readProperties->At(i));
+		if (!property->IsEqualL(readProperty))
+			{
+			passedTest=EFalse;
+			TPtrC8 propertyName = property->Name();
+			gTest.Printf(KFailureDescription, &propertyName);
+			// write to log file
+			TBuf<128> error;
+			error.Format(_L("Test %d failed on property %S\r"),aTestNumber,&propertyName);
+			aLogFile.Write(error);
+			}
+		}
+	
+	if (passedTest)
+		{
+		TBuf<32> success;
+		success.Format(_L("Test %d passed\r"),aTestNumber);
+		aLogFile.Write(success);
+		}
+	
+	CleanupStack::PopAndDestroy(2); // parser, readParser
+	return passedTest;
+	}
+
+
+void MakeDirectoriesL()
+	{
+	gFsSession.MkDirAll(KDirRandomlyGeneratedIn);
+	gFsSession.MkDirAll(KDirRandomlyGeneratedOut);
+	}
+
+
+void DeleteAllPreviousTestsL()
+	{
+	TFileName fileSpecToDelete;
+	
+	CFileMan* fileMan = CFileMan::NewL(gFsSession);
+	CleanupStack::PushL(fileMan);
+
+	// Delete all the vCards in the Original directory...
+	fileSpecToDelete  = KDirRandomlyGeneratedOut;
+	fileSpecToDelete += KNameDeleteFileSpec;
+	fileMan->Delete(fileSpecToDelete);
+
+	// Delete all the vCards in the ReadInWrittenOut directory...
+	fileSpecToDelete  = KDirRandomlyGeneratedIn;
+	fileSpecToDelete += KNameDeleteFileSpec;
+	fileMan->Delete(fileSpecToDelete);
+
+	CleanupStack::PopAndDestroy(); // fileMan
+	}
+
+void FileCleanup(TAny * aFileMan)
+	{
+	gFsSession.Delete(_L("C:\\Test.vcf"));
+	CFileMan* FileMan = (CFileMan*)aFileMan;
+	FileMan->RmDir(_L("C:\\vCards\\"));
+	}
+
+void PrepareForTestsL()
+	{
+	MakeDirectoriesL();
+	DeleteAllPreviousTestsL();
+	}
+
+void doMainL()
+	{
+	CFileMan* FileMan = CFileMan::NewL(gFsSession);
+	CleanupStack::PushL(FileMan);
+	CleanupStack::PushL(TCleanupItem(FileCleanup, FileMan));
+
+	TTime time;
+	time.UniversalTime();
+	gSeed = time.Int64();
+#if defined(__WINS__)
+	//gSeed=MAKE_TINT64(0x00e07096,0xb1f742e0);
+	TInt64 sSeed=gSeed;
+#endif
+
+	RFile file;
+	TInt err = file.Replace(gFsSession, KNameErrorLogfile(), EFileWrite+EFileShareAny+EFileStreamText);
+	User::LeaveIfError(err);
+	CleanupClosePushL(file);
+	TFileText logFile;
+	logFile.Set(file);
+
+	/*TBuf<1> u;
+	u.Append(0xfffe);
+	logFile.Write(u);*/
+
+	CreateArraysL();
+	CreatePropertyValuesL();
+	CreatePropertyParametersL();
+	CreatePropertyDefinitionsL();
+
+	const TInt KNumberOfTests = VTestHelpers::MakeRandomNumber(KMinNumberOfTestsToPerform, KMaxNumberOfTestsToPerform, gSeed);
+	TInt firstFail=0;
+	for(TInt ii=1; ii<KNumberOfTests; ++ii)
+		{
+		gTest.Console()->ClearScreen();
+		gTest.Printf(KTestIndicator,ii);
+		gTest.Printf(KTestIndicatorSeparator);
+		if (!CreateVCardL(ii,logFile) && firstFail==0)
+			firstFail=ii;
+		}
+	if (firstFail>0)
+		{
+		_LIT(KFail,"First test to fail = %d\n");
+		gTest.Printf(KFail,firstFail);
+		}
+
+	DestroyArraysL();
+	
+	PrepareForTestsL();
+	_LIT(KFail,"\r\n Starting Test for creating user properties\n");
+	gTest.Printf(KFail);
+
+	CreateArraysL();
+	CreatePropertyValuesL();
+	CreatePropertyParametersL();
+	CreateUserDefinedPropertyDefinitionsL();
+
+	const TInt KNumberOfTests1 = VTestHelpers::MakeRandomNumber(KMinNumberOfTestsToPerform, KMaxNumberOfTestsToPerform, gSeed);
+	firstFail=0;
+	for(TInt jj=1; jj<KNumberOfTests1; ++jj)
+		{
+		gTest.Console()->ClearScreen();
+		gTest.Printf(KTestIndicator,jj);
+		gTest.Printf(KTestIndicatorSeparator);
+		if (!CreateVCardL(jj,logFile) && firstFail==0)
+			firstFail=jj;
+		}
+	if (firstFail>0)
+		{
+		_LIT(KFail,"First test to fail = %d\n");
+		gTest.Printf(KFail,firstFail);
+		}
+
+	DestroyArraysL();
+	
+	CleanupStack::Pop(); //file.Close()
+	CleanupStack::PopAndDestroy(2, FileMan);
+	}
+
+/**
+@SYMTestCaseID PIM-TVGEN-0001
+*/	
+GLDEF_C TInt E32Main()
+	{	
+	
+	TTime startTime;
+	startTime.UniversalTime();
+	
+	__UHEAP_MARK;
+	gTest.Start(_L("@SYMTestCaseID PIM-TVGEN-0001 TVGEN"));
+	gTest.Title();
+	gCleanup = CTrapCleanup::New();
+	gFsSession.Connect();
+
+	TInt error = KErrNone;
+
+	TRAP(error, PrepareForTestsL());	
+	TRAP(error, doMainL());	
+	gTest(error==KErrNone);
+	delete gCleanup;	
+
+	gFsSession.Close();
+	gTest.End();
+	gTest.Close();
+	__UHEAP_MARKEND;
+	
+	TTime finishTime;
+	finishTime.UniversalTime();
+	TReal elapsed = (TReal)finishTime.MicroSecondsFrom(startTime).Int64();
+	gTest.Printf(_L("Elapsed time: %.4f\n"), elapsed/1000000);
+	
+	return(KErrNone);
+	}
+