textrendering/texthandling/ttext/T_RICH1A.CPP
changeset 0 1fb32624e06b
child 16 748ec5531811
equal deleted inserted replaced
-1:000000000000 0:1fb32624e06b
       
     1 /*
       
     2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32test.h>
       
    20 #include <txtrich.h>
       
    21 #include <gdi.h>
       
    22 #include <conpics.h>
       
    23 #include <s32stor.h>
       
    24 #include "../incp/T_PMLPAR.H"
       
    25 
       
    26 #define UNUSED_VAR(a) a = a
       
    27 
       
    28 LOCAL_D CTrapCleanup* TheTrapCleanup;
       
    29 LOCAL_D RTest test(_L("CRichText Document"));
       
    30 LOCAL_D const TInt KTestCleanupStack=0x200;
       
    31 
       
    32 class MAtomicTest
       
    33 	{
       
    34 public:
       
    35 	/** Test that the object is correctly set at stage aStage, then advance it
       
    36 	to stage aStage+1 with an atomic (with respect to leaving) operation.
       
    37 
       
    38 	The test at each stage should test that the previous stage really happened
       
    39 	and that no part of the new stage has happened.
       
    40 
       
    41 	RunAtomicTest will test that each of these operations really is atomic.
       
    42 	@param aStage The stage to test this object is at.
       
    43 	@return
       
    44 		ETrue if this object was successfully advanced to the next stage.
       
    45 		EFalse if there were no more stages to be advanced to.
       
    46 	*/
       
    47 	virtual TBool TestAndRunStageL(TInt aStage) = 0;
       
    48 	/** Tests that the leave reported in aError is suitable as an error code
       
    49 	from aStage. Panics if not.
       
    50 
       
    51 	@param aError Code that TestAndRunStageL(aStage) left with.
       
    52 	@param aStage Stage at which the leave occurred. */
       
    53 	virtual void TestErrorCondition(TInt aStage, TInt aError) = 0;
       
    54 	void RunAtomicTest();
       
    55 	};
       
    56 
       
    57 /** Runs TestAndRunStage repeatedly with different out-of-memory test
       
    58 conditions.
       
    59 
       
    60 It checks that the operations defined at each stage either leave and leave this
       
    61 object in the same condition, or return successfully and leave the object in
       
    62 the next stage. */
       
    63 void MAtomicTest::RunAtomicTest()
       
    64 	{
       
    65 	TInt stage = 0;
       
    66 	TInt failRate = 1;
       
    67 	TBool more = ETrue;
       
    68 	while (more)
       
    69 		{
       
    70 		__UHEAP_SETFAIL(RHeap::EDeterministic, failRate);
       
    71 		TRAPD(err, more = TestAndRunStageL(stage));
       
    72 		if (err == KErrNone)
       
    73 			{
       
    74 			failRate = 1;
       
    75 			++stage;
       
    76 			}
       
    77 		else
       
    78 			{
       
    79 			TestErrorCondition(stage, err);
       
    80 			++failRate;
       
    81 			}
       
    82 		}
       
    83 	__UHEAP_RESET;
       
    84 	}
       
    85 
       
    86 template<class S,class T,CEditableText::TDocumentStorage D>
       
    87 class CRichTest : public CRichText, public MAtomicTest
       
    88 	{
       
    89 public:
       
    90 	static CRichTest* NewL(CParaFormatLayer* aPara,CCharFormatLayer* aChar);
       
    91 
       
    92 	void DoFlatTests();
       
    93 	void RegisterMethodsL();
       
    94 	void InsertWithDelimsL();
       
    95 	void TestResetL();
       
    96 	void TestDelete1L();
       
    97 	void TestDelete2L();
       
    98     void TestApplyRemoveCharFormat();
       
    99 	void TestRemSpecParaFmtL();
       
   100 	void DoPML();
       
   101 	void TestForDefectTET5DHEWWL();
       
   102 	void TestForDefectINC010183L();
       
   103 	void TestForDefectINC064162L();
       
   104 	void TestForDefectINC109323L();
       
   105 	// Tests SetInsertCharFormat and friends for atomicity.
       
   106 	TBool TestAndRunStageL(TInt aStage);
       
   107 	void TestErrorCondition(TInt aStage, TInt aError);
       
   108 protected:
       
   109 	CRichTest(CParaFormatLayer* aPara,CCharFormatLayer* aChar);
       
   110 	};
       
   111 
       
   112 template<class S, class T,CEditableText::TDocumentStorage D>
       
   113 CRichTest<S,T,D>* CRichTest<S,T,D>::NewL(CParaFormatLayer* aPara,CCharFormatLayer* aChar)
       
   114 	{
       
   115 	CRichTest<S,T,D>* tmp=new(ELeave)CRichTest<S,T,D>(aPara,aChar);
       
   116 	tmp->ConstructL(D,EDefaultTextGranularity,EMultiPara);
       
   117 	return tmp;
       
   118 	}
       
   119 
       
   120 
       
   121 template<class S, class T,CEditableText::TDocumentStorage D>
       
   122 CRichTest<S,T,D>::CRichTest(CParaFormatLayer* aPara,CCharFormatLayer* aChar)
       
   123 	:CRichText(aPara,aChar)
       
   124 	{}
       
   125 
       
   126 
       
   127 template<class S, class T,CEditableText::TDocumentStorage D>
       
   128 void CRichTest<S,T,D>::DoFlatTests()
       
   129 	{
       
   130 	test.Start(_L("Registering all methods"));
       
   131 	RegisterMethodsL();
       
   132 	test.Next(_L("Inserting with embedded paragraph delimiters"));
       
   133 	InsertWithDelimsL();
       
   134 	test.End();
       
   135 	}
       
   136 
       
   137 
       
   138 template<class S, class T,CEditableText::TDocumentStorage D>
       
   139 void CRichTest<S,T,D>::InsertWithDelimsL()
       
   140 	{
       
   141 	test.Start(_L("Inserting into shared para"));
       
   142 
       
   143 	Reset();
       
   144 	TBuf<512> testbuf(_L("a"));
       
   145 	for (TInt ii=0;ii<8;ii++)
       
   146 		{
       
   147 		testbuf.Append('a');
       
   148 		testbuf.Append(CEditableText::EParagraphDelimiter);
       
   149 		}
       
   150 	InsertL(0,testbuf);
       
   151 	test(DocumentLength()==17);
       
   152 	test(ParagraphCount()==9);
       
   153 
       
   154 	Reset();
       
   155 	TBufC<512> bufC;
       
   156 	InsertL(0,bufC);
       
   157 		
       
   158 	Reset();
       
   159 	TBuf<512> buf(_L("Herewith"));
       
   160 	InsertL(0,buf);
       
   161 
       
   162 	InsertL(4,CEditableText::EParagraphDelimiter);
       
   163 	// THE ABOVE IS TEMPORARY ONLY _ REMOVE IT AS SOON AS YOUVE DONE.
       
   164 	
       
   165 	Reset();
       
   166 //	TBuf<512> buf(_L("Herewith"));
       
   167 	buf.Append(EParagraphDelimiter);
       
   168 	InsertL(0,buf);
       
   169 
       
   170 	buf.Append(_L("Is para one"));
       
   171 	buf.Append(EParagraphDelimiter);
       
   172 	InsertL(4,buf);
       
   173 
       
   174 	buf.Append(_L(" trailing text"));
       
   175 	InsertL(DocumentLength()-1,buf);
       
   176 	//////////////////////////////////
       
   177 	// Pathalogical case (1)
       
   178 	// Inserting text with delimiters between 2 adjacent pictures.
       
   179 	test.Next(_L("Inserting text with delimiters between 2 adjacent pictures."));
       
   180 	//
       
   181 	Reset();
       
   182 	CXzePicture* picA=CXzePicture::NewL('Z');
       
   183 	TPictureHeader hdrA;
       
   184 	hdrA.iPictureType=KUidXzePictureType;
       
   185 	hdrA.iPicture=picA;
       
   186 	//
       
   187 	CXzePicture* picB=CXzePicture::NewL('X');
       
   188 	TPictureHeader hdrB;
       
   189 	hdrB.iPictureType=KUidXzePictureType;
       
   190 	hdrB.iPicture=picB;
       
   191 	//
       
   192 	InsertL(0,hdrA);
       
   193 	InsertL(DocumentLength(),hdrB);
       
   194 	buf.SetLength(0);
       
   195 	buf.Append(_L("some"));
       
   196 	buf.Append(CEditableText::EParagraphDelimiter);
       
   197 	buf.Append(_L("trailing text"));
       
   198 	InsertL(1,buf);
       
   199 	//
       
   200 	Reset();  // Destroys all pictures.
       
   201 	picA=CXzePicture::NewL('Z');
       
   202 	hdrA.iPictureType=KUidXzePictureType;
       
   203 	hdrA.iPicture=picA;
       
   204 	picB=CXzePicture::NewL('X');
       
   205 	hdrB.iPictureType=KUidXzePictureType;
       
   206 	hdrB.iPicture=picB;
       
   207 	InsertL(0,hdrA);
       
   208 	InsertL(DocumentLength(),hdrB);
       
   209 	buf.SetLength(5);  // A single para delimiter, with no trailing text.
       
   210 	InsertL(1,buf);
       
   211 	////////////////////////////////
       
   212 	// Pathalogical case (2)
       
   213 	// Insert text with delimiters after a picture
       
   214 	test.Next(_L("Insert text with delimiters after a picture"));
       
   215 	//
       
   216 	Reset();  // Destroys all pictures.
       
   217 	picA=CXzePicture::NewL('Z');
       
   218 	hdrA.iPictureType=KUidXzePictureType;
       
   219 	hdrA.iPicture=picA;
       
   220 	InsertL(0,hdrA);
       
   221 	buf.SetLength(7);
       
   222 	InsertL(1,buf);
       
   223 
       
   224 	////////////////////////////////
       
   225 	// Pathalogical case (3)
       
   226 	// Insert text with delimiters before a picture
       
   227 	test.Next(_L("Insert text with delimiters before a picture"));
       
   228 	//
       
   229 	Reset();  // Destroys all pictures.
       
   230 	picA=CXzePicture::NewL('Z');
       
   231 	hdrA.iPictureType=KUidXzePictureType;
       
   232 	hdrA.iPicture=picA;
       
   233 	InsertL(0,hdrA);
       
   234 	buf.SetLength(7);
       
   235 	InsertL(0,buf);
       
   236 	//	
       
   237 	Reset();
       
   238 	test.End();
       
   239 	}
       
   240 
       
   241 
       
   242 template<class S, class T,CEditableText::TDocumentStorage D>
       
   243 void CRichTest<S,T,D>::RegisterMethodsL()
       
   244 //
       
   245 // 1st part of testing, involves all methods being called to ensure that all
       
   246 // methods exist and run without panicking.
       
   247 //
       
   248 	{
       
   249 	test.Start(_L("CRichText::NewL()"));
       
   250 
       
   251 	// InsertL()
       
   252 	test.Next(_L("InsertL()"));
       
   253 	TPtrC buf(_L("Herewith"));
       
   254 	InsertL(0,buf);
       
   255 
       
   256 //	11.3.97 DavidA defect test 
       
   257 	TCharFormat charFormat;
       
   258 	TCharFormatMask charFormatMask;
       
   259 	TInt lastChar=DocumentLength();
       
   260 	ApplyCharFormatL(charFormat,charFormatMask,lastChar,1);
       
   261 //	end of addition.
       
   262 
       
   263 
       
   264 	TPtrC buf2(_L("Hello"));
       
   265 	InsertL(0,buf2);
       
   266 
       
   267 	DeleteL(3,7);
       
   268 
       
   269 	// SetInsertCharFormatL()
       
   270 	test.Next(_L("SetInsertCharFormatL()"));
       
   271 	TCharFormat format; TCharFormatMask mask;
       
   272 	format.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
       
   273 	mask.SetAttrib(EAttFontStrokeWeight);
       
   274 	SetInsertCharFormatL(format,mask,3);
       
   275 	// Test for alloc heaven when doing multiple simultaneous SetInsertCharFormat()s.
       
   276 	format.iFontSpec.iFontStyle.SetPosture(EPostureItalic);
       
   277 	mask.SetAttrib(EAttFontPosture);
       
   278 	SetInsertCharFormatL(format,mask,3);
       
   279 	//
       
   280 	TPtrC buf3(_L(" is bold."));
       
   281 	InsertL(3,buf3);
       
   282 	CancelInsertCharFormat();
       
   283 
       
   284 	// Inserting new paragraph
       
   285 	test.Next(_L("Inserting paragraph delimiter (Insert(TChar))"));
       
   286 	InsertL(4,CEditableText::EParagraphDelimiter);
       
   287 
       
   288 	// Delete()
       
   289 	test.Next(_L("DeleteL()"));
       
   290 	DeleteL(5,1);
       
   291 
       
   292 	// Sensing character format over a specified range.
       
   293 	test.Next(_L("GetCharFormat()"));
       
   294 	TCharFormat charFormat1; TCharFormatMask undeterminedMask;
       
   295 	GetCharFormat(charFormat1,undeterminedMask,0,4);
       
   296 
       
   297 	// Sensing paragraph format over a specified range.
       
   298 	test.Next(_L("SenseParagraphFormatL()"));
       
   299 	CParaFormat* pParaFormat=NULL;
       
   300 	TRAPD(r,pParaFormat=CParaFormat::NewL());
       
   301 	test(r==KErrNone);
       
   302 	TParaFormatMask undeterminedParaMask;
       
   303 	GetParaFormatL(pParaFormat,undeterminedParaMask,0,DocumentLength());
       
   304 	delete pParaFormat;
       
   305 	
       
   306 	// DelSetInsertCharFormatL()
       
   307 	test.Next(_L("DelSetInsertCharFormatL()"));
       
   308 	TPtrC buf4(_L("This is para 2."));
       
   309 	InsertL(0,buf4);
       
   310 	SetInsertCharFormatL(format,mask,15);
       
   311 	TPtrC buf5(_L("In italic."));
       
   312 	InsertL(15,buf5);
       
   313 	DelSetInsertCharFormatL(4,5);
       
   314 	
       
   315 	// CancelInsertCharFormat()
       
   316 	test.Next(_L("CancelInsertCharFormat()"));
       
   317 	CancelInsertCharFormat();
       
   318 	
       
   319 	// ApplyParaFormatL()
       
   320 	test.Next(_L("ApplyParaFormatL()"));
       
   321 	CParaFormat* paraFormat=CParaFormat::NewL(); TParaFormatMask paraMask;
       
   322 	paraFormat->iHorizontalAlignment=CParaFormat::ECenterAlign;
       
   323 	paraMask.SetAttrib(EAttAlignment);
       
   324 	ApplyParaFormatL(paraFormat,paraMask,0,DocumentLength());
       
   325 
       
   326 	// ApplyCharFormatL()
       
   327 	test.Next(_L("ApplyCharFormatL()"));
       
   328 	format.iFontSpec.iFontStyle.SetPosture(EPostureItalic); mask.SetAttrib(EAttFontPosture);
       
   329 	format.iFontPresentation.iStrikethrough=EStrikethroughOn; mask.SetAttrib(EAttFontStrikethrough);
       
   330 	ApplyCharFormatL(format,mask,0,DocumentLength());
       
   331 
       
   332 	// SenseParaFormatL()
       
   333 	test.Next(_L("SenseParaFormatL()"));
       
   334 	GetParagraphFormatL(paraFormat,DocumentLength()-1);
       
   335 
       
   336 	// CountParas()
       
   337 	test.Next(_L("ParagraphCount()"));
       
   338 	ParagraphCount();
       
   339 
       
   340 	// ParagraphStart()
       
   341 	test.Next(_L("ParagraphStart()"));
       
   342 	TInt aPos=0;
       
   343 	ToParagraphStart(aPos);
       
   344 
       
   345 	// Reset
       
   346 	Reset();
       
   347 
       
   348 	delete paraFormat;
       
   349 
       
   350 	test.End();
       
   351 	}
       
   352 
       
   353 /**
       
   354 @SYMTestCaseID 			SYSLIB-ETEXT-UT-3548
       
   355 @SYMTestCaseDesc  		Testing behaviour of function ApplyCharFormatL() when called at end of document
       
   356 						that contains plain text. Applied formatting should work on subsequent text
       
   357 @SYMTestPriority  		High
       
   358 @SYMTestActions 		1. Insert text1
       
   359 						2. Switch on bold formatting
       
   360 						3. Insert text2
       
   361 						4. Test that first char of text1 is not bold and a character of text 2 is bold. 
       
   362 @SYMTestExpectedResults	ApplyCharFormatL() applies formatting from end of doc to subsequent character.
       
   363 @SYMDEF					INC109323
       
   364 */
       
   365 template<class S, class T,CEditableText::TDocumentStorage D>
       
   366 void CRichTest<S,T,D>::TestForDefectINC109323L()
       
   367 	{
       
   368 	__UHEAP_MARK;
       
   369 	test.Next(_L(" @SYMTestCaseID:SYSLIB-ETEXT-UT-3548 Test ApplyCharFormatL() for bold at end positions of text "));	
       
   370 	_LIT(KText1, "Testing Bold format");
       
   371 	_LIT(KText2, "bold");	
       
   372 
       
   373 	CParaFormatLayer* paraLayer = CParaFormatLayer::NewL();
       
   374 	CleanupStack::PushL(paraLayer);
       
   375 	CCharFormatLayer* charLayer = CCharFormatLayer::NewL();
       
   376 	CleanupStack::PushL(charLayer);
       
   377 	CRichText* doc = CRichText::NewL(paraLayer,charLayer,D);
       
   378 	CleanupStack::PushL(doc);
       
   379 	TCharFormat format1;
       
   380 	TCharFormat fmtCheck1;
       
   381 	format1.iFontPresentation.iUnderline = EUnderlineOff;
       
   382 	// initilizing format attributes
       
   383 	TCharFormatMask mask1;
       
   384 	TCharFormatMask mask2;	
       
   385 	fmtCheck1.iFontPresentation.iUnderline = EUnderlineOff;	
       
   386 	//Test document containing test string and cursor positioned at end of doc.
       
   387 	//Turn on bold formatting and subsequent characters are in bold format.
       
   388 	doc->InsertL(0, KText1);
       
   389 	format1.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
       
   390 	mask1.SetAttrib(EAttFontStrokeWeight);//Set Bold
       
   391 	doc->ApplyCharFormatL(format1, mask1, doc->DocumentLength(),0);//Apply Bold	
       
   392 	doc->InsertL(19, KText2);//These should be in bold
       
   393 	mask1.ClearAttrib(EAttFontStrokeWeight);//Remove bold formatting
       
   394 	doc->GetCharFormat(format1, mask1, 0, 1);//Get format of characters at position 0
       
   395 	doc->GetCharFormat(fmtCheck1, mask2, 22, 1);//Get format of characters at position 22
       
   396 	test(format1.iFontSpec.iFontStyle.StrokeWeight()!=EStrokeWeightBold);
       
   397 	test(fmtCheck1.iFontSpec.iFontStyle.StrokeWeight()==EStrokeWeightBold);	
       
   398 	//tidyup
       
   399 	CleanupStack::PopAndDestroy(doc);
       
   400 	CleanupStack::PopAndDestroy(charLayer);
       
   401 	CleanupStack::PopAndDestroy(paraLayer);	
       
   402 	__UHEAP_MARKEND;
       
   403 	}
       
   404 
       
   405 template<class S, class T,CEditableText::TDocumentStorage D>
       
   406 void CRichTest<S,T,D>::TestRemSpecParaFmtL()
       
   407 //
       
   408 // Test the RemoveSpecificParaFormatL() method of CRichText.
       
   409 //
       
   410 	{
       
   411 	__UHEAP_MARK;
       
   412 	test.Next(_L("RemoveSpecificParaFormatL()"));
       
   413 	CParaFormat* globalParaFormat=CParaFormat::NewLC();
       
   414 	TParaFormatMask globalParaMask;
       
   415 	globalParaFormat->iHorizontalAlignment=CParaFormat::ECenterAlign;
       
   416 	globalParaMask.SetAttrib(EAttAlignment);
       
   417 	CParaFormatLayer* paraLayer=CParaFormatLayer::NewL(globalParaFormat,globalParaMask);
       
   418 	CCharFormatLayer* charLayer=CCharFormatLayer::NewL();
       
   419 	CRichText* doc=NULL;
       
   420 	TRAPD(ret,doc=CRichText::NewL(paraLayer,charLayer,D));
       
   421 	if (ret!=KErrNone)
       
   422 		{
       
   423 		test(doc==NULL);
       
   424 		User::Leave(ret);
       
   425 		}
       
   426 	TPtrC buf1(_L("Here is paragraph one text."));
       
   427 	doc->InsertL(0,buf1);
       
   428 	//
       
   429 	// Apply specific paragraph format
       
   430 	CParaFormat* format=CParaFormat::NewLC();
       
   431 	TParaFormatMask mask;
       
   432 	format->iHorizontalAlignment=CParaFormat::ERightAlign;
       
   433 	mask.SetAttrib(EAttAlignment);
       
   434 	doc->ApplyParaFormatL(format,mask,1,1);
       
   435 	CParaFormat* sensedFormat=CParaFormat::NewLC();
       
   436 	doc->GetParagraphFormatL(sensedFormat,0);
       
   437 	test(sensedFormat->iHorizontalAlignment==CParaFormat::ERightAlign);
       
   438 	//
       
   439 	// Remove specific para format and test
       
   440 	doc->RemoveSpecificParaFormatL(0,1);
       
   441 	doc->GetParagraphFormatL(sensedFormat,0);
       
   442 	test(sensedFormat->iHorizontalAlignment==CParaFormat::ECenterAlign);
       
   443 	//
       
   444 	CleanupStack::PopAndDestroy(3); // the 2 para formats.
       
   445 	delete doc;
       
   446 	delete paraLayer;
       
   447 	delete charLayer;
       
   448 
       
   449 	__UHEAP_MARKEND;
       
   450 	}
       
   451 
       
   452 
       
   453 template<class S, class T,CEditableText::TDocumentStorage D>
       
   454 void CRichTest<S,T,D>::TestDelete1L()
       
   455 //
       
   456 // Test the DeleteL() method of CRichText.
       
   457 //
       
   458 	{
       
   459 	__UHEAP_MARK;
       
   460 	test.Next(_L("DeleteL()"));
       
   461 	CParaFormatLayer* paraLayer=CParaFormatLayer::NewL();
       
   462 	CCharFormatLayer* charLayer=CCharFormatLayer::NewL();
       
   463 	CRichText* doc=NULL;
       
   464 	TRAPD(ret,doc=CRichText::NewL(paraLayer,charLayer,D));
       
   465 	if (ret!=KErrNone)
       
   466 		{
       
   467 		test(doc==NULL);
       
   468 		User::Leave(ret);
       
   469 		}
       
   470 	TPtrC buf1(_L("Here is paragraph one text."));
       
   471 	TPtrC buf2(_L("Here is paragraph one text."));
       
   472 	doc->InsertL(0,buf1);
       
   473 	doc->InsertL(doc->DocumentLength(),EParagraphDelimiter);
       
   474 	doc->InsertL(doc->DocumentLength(),buf2);
       
   475 	//
       
   476 	// Apply formatting
       
   477 	TCharFormat applyFormat;
       
   478 	TCharFormatMask applyMask;
       
   479 	applyFormat.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
       
   480 	applyMask.SetAttrib(EAttFontStrokeWeight);
       
   481 	doc->ApplyCharFormatL(applyFormat,applyMask,8,28);
       
   482 	//
       
   483 	// Now try the delete - should end up with a single shared paragraph!!!
       
   484 	doc->DeleteL(8,28);
       
   485 	TInt documentLength=doc->DocumentLength();
       
   486 	test(documentLength==27);
       
   487 	//
       
   488 	delete doc;
       
   489 	delete paraLayer;
       
   490 	delete charLayer;
       
   491 
       
   492 	__UHEAP_MARKEND;
       
   493 	}
       
   494 
       
   495 
       
   496 template<class S, class T,CEditableText::TDocumentStorage D>
       
   497 void CRichTest<S,T,D>::TestDelete2L()
       
   498 //
       
   499 // Test the DeleteL() method of CRichText.
       
   500 // Deleting the paragraph delimiter between 2 paras of constant character format, but of varying
       
   501 // paragraph formats.
       
   502 //
       
   503 	{
       
   504 	__UHEAP_MARK;
       
   505 	test.Next(_L("DeleteL()"));
       
   506 	CParaFormatLayer* paraLayer=CParaFormatLayer::NewL();
       
   507 	CCharFormatLayer* charLayer=CCharFormatLayer::NewL();
       
   508 	CRichText* doc=NULL;
       
   509 	TRAPD(ret,doc=CRichText::NewL(paraLayer,charLayer,D));
       
   510 	if (ret!=KErrNone)
       
   511 		{
       
   512 		test(doc==NULL);
       
   513 		User::Leave(ret);
       
   514 		}
       
   515 	TPtrC buf1(_L("A"));
       
   516 	TPtrC buf2(_L("B"));
       
   517 	TPtrC buf3(_L("C"));
       
   518 	doc->InsertL(0,buf1);
       
   519 	doc->InsertL(doc->DocumentLength(),EParagraphDelimiter);
       
   520 	doc->InsertL(doc->DocumentLength(),buf2);
       
   521 	doc->InsertL(doc->DocumentLength(),EParagraphDelimiter);
       
   522 	doc->InsertL(doc->DocumentLength(),buf3);
       
   523 	//
       
   524 	// Apply formatting
       
   525 	CParaFormat* applyFormat=CParaFormat::NewLC();
       
   526 	TParaFormatMask applyMask;
       
   527 	applyFormat->iHorizontalAlignment=CParaFormat::ERightAlign;
       
   528 	applyMask.SetAttrib(EAttAlignment);
       
   529 	//
       
   530 	// Make 1st & 3rd para the same para format, different to para 2.
       
   531 	
       
   532 	doc->ApplyParaFormatL(applyFormat,applyMask,1,1);
       
   533 	doc->ApplyParaFormatL(applyFormat,applyMask,5,1);
       
   534 	CleanupStack::PopAndDestroy();  // para format
       
   535 	//
       
   536 	// Now try the delete - should end up with a single shared paragraph!!!
       
   537 	/*TBool parasMerged=*/doc->DeleteL(3,1);  // delete para 2 delimiter
       
   538 	TInt documentLength=doc->DocumentLength();
       
   539 	test(documentLength==4);
       
   540 	//
       
   541 	delete doc;
       
   542 	delete paraLayer;
       
   543 	delete charLayer;
       
   544 
       
   545 	__UHEAP_MARKEND;
       
   546 	}
       
   547 
       
   548 
       
   549 /**
       
   550 @SYMTestCaseID             SYSLIB-ETEXT-UT-3431
       
   551 @SYMTestCaseDesc          Testing behaviour of functions ApplyCharFormatL() and RemoveSpecificFormatL();
       
   552     formatting of text including end of document character
       
   553 @SYMTestPriority          High
       
   554 @SYMTestActions         1. format text and compare attribute values for equality
       
   555                         2. testing for fix of INC097216 whether EOD also formatted
       
   556                         3. remove formatting of text and compare attribute values for equality
       
   557                         4. testing for fix of DEF104149 whether EOD also has formatting removed
       
   558 @SYMTestExpectedResults    ApplyCharFormatL() and RemoveSpecificFormatL() apply and remove formatting from
       
   559     specified range of text including end of document character
       
   560 @SYMDEF                    DEF104149
       
   561 */
       
   562 template<class S, class T,CEditableText::TDocumentStorage D>
       
   563 void CRichTest<S,T,D>::TestApplyRemoveCharFormat()
       
   564     {
       
   565     __UHEAP_MARK;
       
   566     test.Next(_L(" @SYMTestCaseID:SYSLIB-ETEXT-UT-3431 Test ApplyCharFormatL() & RemoveSpecificCharFormat() "));	
       
   567     CParaFormatLayer* paraLayer = CParaFormatLayer::NewL();
       
   568     CleanupStack::PushL(paraLayer);
       
   569     CCharFormatLayer* charLayer = CCharFormatLayer::NewL();
       
   570     CleanupStack::PushL(charLayer);
       
   571     CRichText* doc = CRichText::NewL(paraLayer,charLayer,D);
       
   572     CleanupStack::PushL(doc);
       
   573     _LIT(KText1, "Hello there!");
       
   574     doc->InsertL(0, KText1);
       
   575     test(doc->DocumentLength()==12);
       
   576    
       
   577     // initilizing format (ie.underline) values
       
   578     TCharFormat formatCheck;
       
   579     formatCheck.iFontPresentation.iUnderline = EUnderlineOff;
       
   580     TCharFormat fmatCheck;
       
   581     formatCheck.iFontPresentation.iUnderline = EUnderlineOff;
       
   582     TCharFormat format;
       
   583     format.iFontPresentation.iUnderline = EUnderlineOn;
       
   584     TCharFormat formatNone;
       
   585     formatCheck.iFontPresentation.iUnderline = EUnderlineOff;
       
   586 
       
   587     // initilizing format attributes
       
   588     TCharFormatMask maskCheck;   
       
   589     TCharFormatMask mask;
       
   590     mask.SetAttrib(EAttFontUnderline);
       
   591    
       
   592     // underline KText1 and compare its attribute values with EUnderlineOn for equality
       
   593     doc->ApplyCharFormatL(format, mask, 0, 12);   
       
   594     doc->GetCharFormat(formatCheck, maskCheck, 0, 12);
       
   595     // testing for fix of INC097216 whether EOD also formatted
       
   596     doc->GetCharFormat(fmatCheck, maskCheck, 12, 1);
       
   597     test(format.IsEqual(formatCheck));
       
   598     test(format.IsEqual(fmatCheck));
       
   599 
       
   600     // remove underlining of KText1 and compare its attribute values with EUnderlineOff for equality
       
   601     doc->RemoveSpecificCharFormatL(0, 12);
       
   602     doc->GetCharFormat(formatCheck, maskCheck, 0, 12);
       
   603     // testing for fix of INC104149 whether EOD also has formatting removed
       
   604     doc->GetCharFormat(fmatCheck, maskCheck, 12, 1);
       
   605     test(formatCheck.IsEqual(formatNone));
       
   606     test(fmatCheck.IsEqual(formatNone));
       
   607    
       
   608     CleanupStack::PopAndDestroy(doc);
       
   609     CleanupStack::PopAndDestroy(charLayer);
       
   610     CleanupStack::PopAndDestroy(paraLayer);   
       
   611     __UHEAP_MARKEND;
       
   612     }
       
   613 
       
   614 
       
   615 template<class S, class T,CEditableText::TDocumentStorage D>
       
   616 void CRichTest<S,T,D>::TestResetL()
       
   617 //
       
   618 // Test the Reset() method of CRichText.
       
   619 //
       
   620 	{
       
   621 	__UHEAP_MARK;
       
   622 	test.Next(_L("Reset()"));
       
   623 	CParaFormatLayer* paraLayer=CParaFormatLayer::NewL();
       
   624 	CCharFormatLayer* charLayer=CCharFormatLayer::NewL();
       
   625 	CRichText* doc=NULL;
       
   626 	TRAPD(ret,doc=CRichText::NewL(paraLayer,charLayer,D));
       
   627 	if (ret!=KErrNone)
       
   628 		{
       
   629 		test(doc==NULL);
       
   630 		User::Leave(ret);
       
   631 		}
       
   632 	TPtrC buf1(_L("Here is paragraph one text."));
       
   633 	TPtrC buf2(_L("And here is that of the second paragraph"));
       
   634 	doc->InsertL(0,buf1);
       
   635 	doc->InsertL(doc->DocumentLength(),EParagraphDelimiter);
       
   636 	doc->InsertL(doc->DocumentLength(),buf2);
       
   637 	//
       
   638 	doc->Reset();
       
   639 	test(doc->ParagraphCount()==1);
       
   640 	doc->Reset();
       
   641 	test(doc->ParagraphCount()==1);
       
   642 	doc->Reset();
       
   643 	test(doc->ParagraphCount()==1);
       
   644 	delete doc;
       
   645 	delete paraLayer;
       
   646 	delete charLayer;
       
   647 
       
   648 	__UHEAP_MARKEND;
       
   649 	}
       
   650 	
       
   651 
       
   652 template<class S, class T,CEditableText::TDocumentStorage D>
       
   653 void CRichTest<S,T,D>::DoPML()
       
   654 //
       
   655 // Use PML source translator to produce a RichText component.
       
   656 //
       
   657 	{
       
   658  	__UHEAP_MARK;
       
   659 	test.Next(_L("Checking PML sourced RichText Component"));
       
   660  	// set filename
       
   661 	TFileName theFileName=_L("z:\\test\\app-framework\\etext\\t_rich1a.pml");
       
   662 	// Parse PML
       
   663 	CParser* myParser=NULL;
       
   664 	CRichText* richTextDoc=NULL;
       
   665 	TRAPD(ret, myParser=CParser::NewL());
       
   666 	CleanupStack::PushL(myParser);
       
   667 	TRAP(ret, richTextDoc=myParser->ParseL(theFileName));
       
   668 	CleanupStack::PushL(richTextDoc);
       
   669 	CParaFormatLayer* pl = const_cast<CParaFormatLayer*>(
       
   670 		richTextDoc->GlobalParaFormatLayer());
       
   671 	CleanupStack::PushL(pl);
       
   672 	CCharFormatLayer* cl = const_cast<CCharFormatLayer*>(
       
   673 		richTextDoc->GlobalCharFormatLayer());
       
   674 	CleanupStack::PushL(cl);
       
   675 	
       
   676 	TInt paraCount=richTextDoc->ParagraphCount();
       
   677 	test(paraCount==2);
       
   678 	TBool hasMarkupData=richTextDoc->HasMarkupData();
       
   679 	test(hasMarkupData==EFalse);
       
   680 
       
   681 	// Testing overloaded senseChars - looking at the indeterminate mask.
       
   682 //	TCharFormat charFormat;	TCharFormatMask charFormatMask;
       
   683 //	richTextDoc->GetCharFormat(0,17,charFormat,charFormatMask);
       
   684 //	test(charFormatMask==0);
       
   685 
       
   686 //	richTextDoc->GetCharFormat(17,10,charFormat,charFormatMask);
       
   687 
       
   688 	CParaFormat* paraFormat = 0;
       
   689 	paraFormat=CParaFormat::NewLC();
       
   690 	TParaFormatMask paraFormatMask;
       
   691 	richTextDoc->GetParaFormatL(paraFormat,paraFormatMask,0,2);
       
   692 	richTextDoc->GetParaFormatL(paraFormat,paraFormatMask,17,3);  // All para 2 and just para1
       
   693 
       
   694 	CleanupStack::PopAndDestroy(paraFormat);
       
   695 	CleanupStack::PopAndDestroy(cl);
       
   696 	CleanupStack::PopAndDestroy(pl);
       
   697 	CleanupStack::PopAndDestroy(richTextDoc);
       
   698 	CleanupStack::PopAndDestroy(myParser);
       
   699 	__UHEAP_MARKEND;
       
   700 	}
       
   701 
       
   702 template<class S, class T,CEditableText::TDocumentStorage D>
       
   703 void CRichTest<S,T,D>::TestForDefectTET5DHEWWL()
       
   704 //
       
   705 // Test the CRichTextIndex::InsertL() for defect TET-5DHEWW which 
       
   706 // should not be present from 15/10/02.
       
   707 //
       
   708 	{
       
   709 	__UHEAP_MARK;
       
   710 
       
   711 	test.Next(_L("Testing for the presence of defect TET-5DHEWW"));
       
   712 
       
   713 	CParaFormatLayer* paraLayer = CParaFormatLayer::NewL();
       
   714 	CCharFormatLayer* charLayer = CCharFormatLayer::NewL();
       
   715 
       
   716 	CRichText* doc = NULL;
       
   717 	TRAPD(ret, doc = CRichText::NewL(paraLayer,charLayer,D));
       
   718 	if (ret!=KErrNone)
       
   719 		{
       
   720 		test(doc==NULL);
       
   721 		User::Leave(ret);
       
   722 		}
       
   723 
       
   724 	TPtrC buf1(_L("sometext "));
       
   725 	doc->InsertL(0, buf1);
       
   726 
       
   727 	TCharFormat charFormat12(_L("Times New Roman"), 240);
       
   728 	TCharFormatMask charMask12;
       
   729 	charMask12.SetAttrib(EAttFontHeight);
       
   730 	doc->SetInsertCharFormatL(charFormat12, charMask12, doc->DocumentLength());
       
   731 
       
   732 	TPtrC buf2(_L("sometext "));
       
   733 	doc->InsertL(doc->DocumentLength(), buf2);
       
   734 
       
   735 	doc->SetInsertCharFormatL(charFormat12, charMask12, doc->DocumentLength());
       
   736 	doc->InsertL(doc->DocumentLength(), EParagraphDelimiter);
       
   737 
       
   738 	// Defect present in CRichTextIndex if test executable crashes/panics on the 
       
   739 	// previous line on a debug build. Should this test method return normally then 
       
   740 	// the EText library used does not contain the defect.
       
   741 
       
   742 	TInt docLen = doc->DocumentLength();
       
   743 	test(docLen==19);
       
   744 
       
   745 	test.Printf(_L("RTEST:                        Test PASSED - defect not present!\n"));
       
   746 
       
   747 	delete doc;
       
   748 	delete paraLayer;
       
   749 	delete charLayer;
       
   750 
       
   751 	__UHEAP_MARKEND;
       
   752 	}
       
   753 
       
   754 // CRichTextIndex::GetParaFormatL doesn't set TParaFormatMask correctly
       
   755 template<class S, class T,CEditableText::TDocumentStorage D>
       
   756 void CRichTest<S,T,D>::TestForDefectINC010183L()
       
   757 	{
       
   758 	__UHEAP_MARK;
       
   759 
       
   760 	test.Next(_L("Testing for the presence of defect INC010183"));
       
   761 
       
   762 	CParaFormatLayer* paraLayer = CParaFormatLayer::NewL();
       
   763 	CleanupStack::PushL(paraLayer);
       
   764 	CCharFormatLayer* charLayer = CCharFormatLayer::NewL();
       
   765 	CleanupStack::PushL(charLayer);
       
   766 
       
   767 	CRichText* doc = CRichText::NewL(paraLayer,charLayer,D);
       
   768 	CleanupStack::PushL(doc);
       
   769 
       
   770 	TPtrC buf1(_L("para1\x2029para2\x2029para3"));
       
   771 	doc->InsertL(0, buf1);
       
   772 
       
   773 	CParaFormat* pFormat = CParaFormat::NewLC();
       
   774 	pFormat->iBullet = new(ELeave) TBullet;
       
   775 	pFormat->iBullet->iHeightInTwips = 1;
       
   776 	TParaFormatMask pMask;
       
   777 	pMask.SetAttrib(EAttBullet);
       
   778 
       
   779 	doc->ApplyParaFormatL(pFormat, pMask, 8, 1);
       
   780 	doc->GetParaFormatL(pFormat, pMask, 0, 14);
       
   781 
       
   782 	// test that the bullet's "varies" flag is set.
       
   783 	test(pMask.AttribIsSet(EAttBullet));
       
   784 
       
   785 	doc->GetParaFormatL(pFormat, pMask, 7, 6);
       
   786 
       
   787 	// test that the bullet's "varies" flag is set.
       
   788 	test(pMask.AttribIsSet(EAttBullet));
       
   789 
       
   790 	CleanupStack::PopAndDestroy(pFormat);
       
   791 	CleanupStack::PopAndDestroy(doc);
       
   792 	CleanupStack::PopAndDestroy(charLayer);
       
   793 	CleanupStack::PopAndDestroy(paraLayer);
       
   794 
       
   795 	__UHEAP_MARKEND;
       
   796 	}
       
   797 
       
   798 
       
   799 // CRichTextIndex::InsertL, Insertion of zero-length text should not cancel the pending new TCharFormat.
       
   800 // This test sets the Strikethrough option on and applies it to a zero length section of text before checking
       
   801 // the format has been applied correctly. Then it inputs 3 characters and checks to see if the format of these
       
   802 // characters also has the character format applied to them.  
       
   803 template<class S, class T,CEditableText::TDocumentStorage D>
       
   804 void CRichTest<S,T,D>::TestForDefectINC064162L()
       
   805 	{
       
   806 	__UHEAP_MARK;
       
   807 	
       
   808 	test.Next(_L("INC064162 - Testing insertion of zero-length text doesn't cancel the pending TCharFormat"));
       
   809 	
       
   810 	TInt length = 3;	
       
   811 	TPtrC bufPtrLetterNone(_L(""));
       
   812 	TPtrC bufPtrLettersABC(_L("ABC"));
       
   813 	
       
   814 	CParaFormatLayer* paraLayer = CParaFormatLayer::NewL();
       
   815 	CleanupStack::PushL(paraLayer);
       
   816 	CCharFormatLayer* charLayer = CCharFormatLayer::NewL();
       
   817 	CleanupStack::PushL(charLayer);
       
   818 
       
   819 	CRichText* doc = CRichText::NewL(paraLayer,charLayer,D);
       
   820 	CleanupStack::PushL(doc);
       
   821 
       
   822 	TCharFormat cFormatCheck;
       
   823 	cFormatCheck.iFontPresentation.iStrikethrough = EStrikethroughOff;
       
   824 	
       
   825 	TCharFormat cFormat;
       
   826 	cFormat.iFontPresentation.iStrikethrough = EStrikethroughOn;
       
   827 
       
   828 	TCharFormatMask cMaskCheck;
       
   829 	
       
   830 	TCharFormatMask cMask;
       
   831 	cMask.SetAttrib(EAttFontStrikethrough);
       
   832 	
       
   833 	// Applying the strikethrough format on a zero length section of text.
       
   834 	doc->ApplyCharFormatL(cFormat,cMask,0,0);	
       
   835 
       
   836 	doc->InsertL(0, bufPtrLetterNone);
       
   837 	
       
   838 	doc->GetCharFormat(cFormatCheck, cMaskCheck,0,0);
       
   839 
       
   840 	// testing the format of the empty buf
       
   841 	test(cFormat.IsEqual(cFormatCheck));
       
   842 
       
   843 	doc->InsertL(0, bufPtrLettersABC);	
       
   844 	doc->GetCharFormat(cFormatCheck, cMaskCheck,0,length);
       
   845 	
       
   846 	// testing the format of the 3 characters
       
   847 	test(cFormat.IsEqual(cFormatCheck));
       
   848  
       
   849 	CleanupStack::PopAndDestroy(doc);
       
   850 	CleanupStack::PopAndDestroy(charLayer);
       
   851 	CleanupStack::PopAndDestroy(paraLayer);
       
   852 
       
   853 	__UHEAP_MARKEND;
       
   854 	}
       
   855 
       
   856 
       
   857 
       
   858 template<class S, class T,CEditableText::TDocumentStorage D>
       
   859 TBool CRichTest<S,T,D>::TestAndRunStageL(TInt aStage)
       
   860 	{
       
   861 	_LIT(KSomeText, "Text\x2029par ");
       
   862 	_LIT(KSomeTextPlus3, "Text\x2029par \x2029z ");
       
   863 	TCharFormat format;
       
   864 	TCharFormatMask mask;
       
   865 	TCharFormatMask varies;
       
   866 	switch (aStage)
       
   867 		{
       
   868 	case 0:
       
   869 		Reset();
       
   870 		return ETrue;
       
   871 	case 1:
       
   872 		test(DocumentLength() == 0);
       
   873 		InsertL(0, KSomeText);
       
   874 		return ETrue;
       
   875 	case 2:
       
   876 			{
       
   877 			TBuf<100> buf;
       
   878 			test(DocumentLength() == KSomeText().Length());
       
   879 			Extract(buf, 0, KSomeText().Length());
       
   880 			test(0 == buf.Compare(KSomeText));
       
   881 			TCharFormat format0;
       
   882 			GetCharFormat(format, varies, 0, KSomeText().Length());
       
   883 			test(varies.IsNull());		// format should not vary
       
   884 			test(format.IsEqual(format0));
       
   885 			}
       
   886 		// Set an insert char format for font height 100
       
   887 		mask.SetAttrib(EAttFontHeight);
       
   888 		format.iFontSpec.iHeight = 100;
       
   889 		SetInsertCharFormatL(format, mask, 9);
       
   890 		return ETrue;
       
   891 	case 3:
       
   892 		test(DocumentLength() == KSomeText().Length());
       
   893 		// Insert a carriage return and cancel the insert char format.
       
   894 		// This stands in place of moving the cursor away from the
       
   895 		// insertion point and back again.
       
   896 		InsertL(9, 0x2029);
       
   897 		return ETrue;
       
   898 	case 4:
       
   899 		test(DocumentLength() == KSomeText().Length() + 1);
       
   900 		CancelInsertCharFormat();
       
   901 		return ETrue;
       
   902 	case 5:
       
   903 		test(DocumentLength() == KSomeText().Length() + 1);
       
   904 		GetCharFormat(format, varies, 0, 9);
       
   905 			{
       
   906 			TCharFormat format0;
       
   907 			test(format.IsEqual(format0));
       
   908 			test(varies.IsNull());
       
   909 			}
       
   910 		GetCharFormat(format, varies, 9, 1);
       
   911 		test(varies.IsNull());
       
   912 		test(format.iFontSpec.iHeight == 100);
       
   913 		// Insert a character after the new carriage return. It should
       
   914 		// have height 100. This is what the defect INC038479 is
       
   915 		// complaining about. In fact it is a long-standing problem,
       
   916 		// long assumed to be too difficult to solve in a reasonable
       
   917 		// time.
       
   918 		InsertL(10, 'z');
       
   919 		return ETrue;
       
   920 	case 6:
       
   921 		test(DocumentLength() == KSomeText().Length() + 2);
       
   922 		GetCharFormat(format, varies, 9, 2);
       
   923 		test(varies.IsNull());
       
   924 		test(format.iFontSpec.iHeight == 100);
       
   925 		// Insert a space. This prepares us for checking for a regression
       
   926 		// that was introduced then fixed in the fix for INC038479.
       
   927 		InsertL(11, ' ');
       
   928 		return ETrue;
       
   929 	case 7:
       
   930 			{
       
   931 			TBuf<100> buf;
       
   932 			test(DocumentLength() == KSomeTextPlus3().Length());
       
   933 			Extract(buf, 0, KSomeTextPlus3().Length());
       
   934 			test(0 == buf.Compare(KSomeTextPlus3));
       
   935 			TCharFormat format0;
       
   936 			GetCharFormat(format, varies, 0, KSomeText().Length());
       
   937 			test(varies.IsNull());		// format should not vary across the original bit
       
   938 			test(format.IsEqual(format0));
       
   939 			GetCharFormat(format, varies, KSomeText().Length(), 3);
       
   940 			test(format.iFontSpec.iHeight == 100);
       
   941 			test(varies.IsNull());
       
   942 			}
       
   943 		// Set a new insert character format for bold
       
   944 		mask.SetAttrib(EAttFontStrokeWeight);
       
   945 		format.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
       
   946 		SetInsertCharFormatL(format, mask, 9);
       
   947 		return ETrue;
       
   948 	case 8:
       
   949 		// and unset the insert character format again
       
   950 		mask.SetAttrib(EAttFontStrokeWeight);
       
   951 		format.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightNormal);
       
   952 		SetInsertCharFormatL(format, mask, 9);
       
   953 		return ETrue;
       
   954 	case 9:
       
   955 		test(DocumentLength() == KSomeTextPlus3().Length());
       
   956 		// Add a carriage return.
       
   957 		InsertL(12, 0x2029);
       
   958 		return ETrue;
       
   959 	case 10:
       
   960 		test(DocumentLength() == KSomeTextPlus3().Length() + 1);
       
   961 		GetCharFormat(format, varies, KSomeTextPlus3().Length(), 1);
       
   962 		test(varies.IsNull());
       
   963 		test(format.iFontSpec.iFontStyle.StrokeWeight() == EStrokeWeightNormal);
       
   964 		return EFalse;
       
   965 	default:
       
   966 		return ETrue;
       
   967 		}
       
   968 	}
       
   969 
       
   970 template<class S, class T,CEditableText::TDocumentStorage D>
       
   971 void CRichTest<S,T,D>::TestErrorCondition(TInt aStage, TInt aError)
       
   972 	{
       
   973 	// No leaves possible except NoMemory.
       
   974 	test(aError == KErrNoMemory);
       
   975 	// Stage 4 should not leave at all.
       
   976 	test(aStage != 4);
       
   977 	}
       
   978 
       
   979 
       
   980 template<class S, class T, CEditableText::TDocumentStorage D>
       
   981 void TestClassesL()
       
   982 	{
       
   983 	__UHEAP_MARK;
       
   984 
       
   985 	CParaFormatLayer* paraLayer = CParaFormatLayer::NewL();
       
   986 	CleanupStack::PushL(paraLayer);
       
   987 	CCharFormatLayer* charLayer = CCharFormatLayer::NewL();
       
   988 	CleanupStack::PushL(charLayer);
       
   989 	CRichTest<S, T, D>* doc = CRichTest<S, T, D>::NewL(paraLayer, charLayer);
       
   990 	CleanupStack::PushL(doc);
       
   991 
       
   992 	doc->DoFlatTests();
       
   993 	doc->TestResetL();
       
   994 	doc->TestDelete1L();
       
   995 	doc->TestDelete2L();
       
   996 	doc->TestApplyRemoveCharFormat();
       
   997 	doc->TestRemSpecParaFmtL();
       
   998 	doc->DoPML();
       
   999 	doc->TestForDefectTET5DHEWWL();
       
  1000 	doc->TestForDefectINC010183L();
       
  1001 	doc->TestForDefectINC064162L();
       
  1002 	doc->TestForDefectINC109323L();
       
  1003 	test.Next(_L("INC038479 - Email editor: font settings made at doc end can be lost and returned to default"));
       
  1004 	// Also tests SetInsetCharFormat more thoroughly.
       
  1005 	doc->RunAtomicTest();
       
  1006 
       
  1007 	CleanupStack::PopAndDestroy(doc);
       
  1008 	CleanupStack::PopAndDestroy(charLayer);
       
  1009 	CleanupStack::PopAndDestroy(paraLayer);
       
  1010 
       
  1011 	__UHEAP_MARKEND;
       
  1012 	}
       
  1013 
       
  1014 void DoTestsL()
       
  1015 	{
       
  1016 	test.Start(_L("CRichText - Flat"));
       
  1017 	TestClassesL<TText,TPtrC,CEditableText::EFlatStorage>();
       
  1018 	test.Next(_L("CRichText - Segmented"));
       
  1019 	TestClassesL<TText,TPtrC,CEditableText::ESegmentedStorage>();
       
  1020 	test.End();
       
  1021 	}
       
  1022 
       
  1023 	
       
  1024 LOCAL_C void setupCleanup()
       
  1025 //
       
  1026 // Initialise the cleanup stack.
       
  1027 //
       
  1028 	{
       
  1029 
       
  1030 	TheTrapCleanup=CTrapCleanup::New();
       
  1031 	TRAPD(r,\
       
  1032 		{\
       
  1033 		for (TInt i=KTestCleanupStack;i>0;i--)\
       
  1034 			CleanupStack::PushL((TAny*)1);\
       
  1035 		test(r==KErrNone);\
       
  1036 		CleanupStack::Pop(KTestCleanupStack);\
       
  1037 		});
       
  1038 	}
       
  1039 
       
  1040 TInt E32Main()
       
  1041 	{
       
  1042 	setupCleanup();
       
  1043 	test.Title();
       
  1044 	__UHEAP_MARK;
       
  1045 	
       
  1046 	TRAPD(ret,DoTestsL());
       
  1047     test(ret == KErrNone);
       
  1048 	
       
  1049 	test.Close();
       
  1050 	__UHEAP_MARKEND;
       
  1051 	delete TheTrapCleanup;
       
  1052 	return 0;
       
  1053 	}