// Copyright (c) 2005-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:// @file // @internalComponent - Internal Symbian test code// This is a support app used by Apparc\tef\TApparcTestServer (TApparc4Step in particular)// This application covers the following tests for the static objects// Test 1 : Existing CCoeStatic derived objects using the 2 parameter// constructor must be destroyed before the app ui.// Way to test this,// Case 1: Get hold of a particular static using CCoeEnv::Static(TUid aUid) // in an application's override of CEikAppUi::PrepareToExit() and confirm the // returned pointer is not null. // Case 2: Then, the same thing is done in the app ui's destructor to check that // the pointer is now null.// Test 2: A static constructed with a negative priority should be accessible from the // app ui's destructor, but then destroyed before another static that has a lower priority value.// Way to test this,// Case 1: Construct a static (A) using the 3 parameter constructor, specifying a negative priority.// Then construct another static (B) specifying a priority (A's priority - 1). // Check that static A is still non-null when accessed from the app ui's destructor. // Case 2: Then check that static A is null when accessed from B's destructor.// Test 3: Given two statics with different positive priorities,// the higher priority one should be destroyed first.// Way to test this,// Case 1: If (for example) static A has priority EDefaultDestructionPriority,// and static B has EDefaultDestructionPriority-1, A's destructor should be able to access B,// Case 2: But B's destructor shouldn't be able to access A.// Test 4: Statics with priorities immediately either side of the pre/post-destroy app ui should be destroyed before/after the app ui. Should also test that // the first negative priority static is destroyed and not "skipped over" when the code calculates// which static should be destroyed next after the app ui has been destroyed.// Way to test this,// Case 1: We could create statics A, B and C with priority zero, -1 and -2 respectively. // Then check in the app ui destructor that A is null, and B and C are both non-null.// Case 2: Then in B's destructor check that C is still non-null.// Case 3: And in C's destructor check that B is now null.// // tapparctestapp.cpp//#include <coeccntx.h>#include <apgtask.h>#include <eikenv.h>#include <eikappui.h>#include <eikapp.h>#include <eikdoc.h>#include <techview/eikmenup.h>#include <f32file.h>#include <techview/eikon.hrh>#include <eikstart.h> //TKAS added for exe-app#include <tapparctestapp.rsg>// File which stores the test results_LIT(KApparcTestResultsFileName, "c:\\system\\Apparctest\\ApparcTestResultsFile.txt");_LIT(KApparcTestDir, "c:\\system\\Apparctest\\");_LIT8(KTestPass ,"PASS\r\n");_LIT8(KTestFail,"FAIL\r\n");_LIT8(KApparcTest1,"Test1:");_LIT8(KApparcTest2,"Test2:");_LIT8(KApparcTest3,"Test3:");_LIT8(KApparcTest4,"Test4:");_LIT8(KApparcTestCase1,"Case1:");_LIT8(KApparcTestCase2,"Case2:");_LIT8(KApparcTestCase3,"Case3:");const TUid KUidApparcTestApp = {0x100048F3};// Uids for diffent classes for static const TUid KUidTestStatic = {0x13003ACE}; const TUid KUidTestStaticNegativePrioA = {0x13004ACE}; const TUid KUidTestStaticNegativePrioB = {0x13005ACE}; const TUid KUidTestStaticPosPriA = {0x13006ACE};const TUid KUidTestStaticPosPriB = {0x13007ACE};const TUid KUidTestStaticPriZeroA= {0x13009ACE};const TUid KUidTestStaticPriOneB = {0x1300AACE};const TUid KUidTestStaticPriTwoC = {0x1300BACE};// Priorities for static objectsenum {ENegativePriortyStaticA = -3};enum {EPriorityTwoStaticC= -2,EPriorityOneStaticB = -1,EPriorityZeroStaticA= 0};// static class for Test case 1 class CTApparcTestStatic : public CCoeStatic {public: inline CTApparcTestStatic(RFile& aFile); inline static CTApparcTestStatic* Self(); ~CTApparcTestStatic(); RFile iFile; };CTApparcTestStatic::~CTApparcTestStatic() { }// Static class with negative priority for Test case 2.class CTApparcTestNegativePrioStaticA : public CCoeStatic {public: inline CTApparcTestNegativePrioStaticA(RFile& aFile); inline static CTApparcTestNegativePrioStaticA* Self(); ~CTApparcTestNegativePrioStaticA(); RFile& iFile; };// Static class with negative priority for Test case 2. (priority less than CTApparcTestNegativePrioStaticA)class CTApparcTestNegativePrioStaticB : public CCoeStatic {public: inline CTApparcTestNegativePrioStaticB(); inline static CTApparcTestNegativePrioStaticB* Self(); static CTApparcTestNegativePrioStaticB* NewL(); void ConstructL(); ~CTApparcTestNegativePrioStaticB(); RFile iFile; RFs iFs; };CTApparcTestNegativePrioStaticA::~CTApparcTestNegativePrioStaticA() { }CTApparcTestNegativePrioStaticB::~CTApparcTestNegativePrioStaticB() { // Test 2, Case 2 CTApparcTestNegativePrioStaticA* testCoeStaticA = CTApparcTestNegativePrioStaticA::Self(); iFile.Write(KApparcTest2); iFile.Write(KApparcTestCase2); if(testCoeStaticA == NULL) iFile.Write(KTestPass); else iFile.Write(KTestFail); // CTApparcTestNegativePrioStaticB class object is the most negative prioritised // static objects .Hence the file and session handles are closed here as no // more logging is required hereafter. iFile.Close(); iFs.Close(); }// Static class with positive priority for Test case 3:class CTApparcTestPosPrioStaticA : public CCoeStatic {public: inline CTApparcTestPosPrioStaticA(RFile& aFile); inline static CTApparcTestPosPrioStaticA* Self(); ~CTApparcTestPosPrioStaticA(); RFile& iFile; };// static class with positive priority less than CTApparcTestPosPrioStaticA for Test case 3.class CTApparcTestPosPrioStaticB : public CCoeStatic {public: inline CTApparcTestPosPrioStaticB(RFile& aFile); inline static CTApparcTestPosPrioStaticB* Self(); ~CTApparcTestPosPrioStaticB(); RFile& iFile; };CTApparcTestPosPrioStaticA::~CTApparcTestPosPrioStaticA() { // Test 3 , Case 1 CTApparcTestPosPrioStaticB* testPosPrioStaticB = CTApparcTestPosPrioStaticB::Self(); iFile.Write(KApparcTest3); iFile.Write(KApparcTestCase1); if(testPosPrioStaticB != NULL) iFile.Write(KTestPass); else iFile.Write(KTestFail); }CTApparcTestPosPrioStaticB::~CTApparcTestPosPrioStaticB() { // Test 3 , Case 2 CTApparcTestPosPrioStaticA* testPosPrioStaticA = CTApparcTestPosPrioStaticA::Self(); iFile.Write(KApparcTest3); iFile.Write(KApparcTestCase2); if(testPosPrioStaticA == NULL) iFile.Write(KTestPass); else iFile.Write(KTestFail); }// static class with priority 0 for test case 4class CTApparcTestPrioZeroStaticA : public CCoeStatic {public: inline CTApparcTestPrioZeroStaticA(RFile& aFile); inline static CTApparcTestPrioZeroStaticA* Self(); ~CTApparcTestPrioZeroStaticA(); RFile& iFile; };// static class with priority -1 for test case 4class CTApparcTestPrioOneStaticB : public CCoeStatic {public: inline CTApparcTestPrioOneStaticB(RFile& aFile); inline static CTApparcTestPrioOneStaticB* Self(); ~CTApparcTestPrioOneStaticB(); RFile& iFile; };// static class with priority -2 for test case 4 class CTApparcTestPrioTwoStaticC : public CCoeStatic {public: inline CTApparcTestPrioTwoStaticC(RFile& aFile); inline static CTApparcTestPrioTwoStaticC* Self(); ~CTApparcTestPrioTwoStaticC(); RFile& iFile; };CTApparcTestPrioZeroStaticA::~CTApparcTestPrioZeroStaticA() { }CTApparcTestPrioOneStaticB::~CTApparcTestPrioOneStaticB() { // Test 4 , Case 2 CTApparcTestPrioTwoStaticC* testPrioTwoCoeStaticC = CTApparcTestPrioTwoStaticC::Self(); iFile.Write(KApparcTest4); iFile.Write(KApparcTestCase2); if(testPrioTwoCoeStaticC != NULL) iFile.Write(KTestPass); else iFile.Write(KTestFail); }CTApparcTestPrioTwoStaticC::~CTApparcTestPrioTwoStaticC() { // Test 4 , Case 3 CTApparcTestPrioOneStaticB* testPrioOneCoeStaticB = CTApparcTestPrioOneStaticB::Self(); iFile.Write(KApparcTest4); iFile.Write(KApparcTestCase3); if(testPrioOneCoeStaticB == NULL) iFile.Write(KTestPass); else iFile.Write(KTestFail); }////// CTApparcTestAppView////class CTApparcTestAppView : public CCoeControl {public: static CTApparcTestAppView* NewL(const TRect& aRect); CTApparcTestAppView(); ~CTApparcTestAppView(); void ConstructL(const TRect& aRect);private: // Inherited from CCoeControl void Draw(const TRect& /*aRect*/) const;private: HBufC* iApparcTestText; };CTApparcTestAppView::CTApparcTestAppView() { }CTApparcTestAppView* CTApparcTestAppView::NewL(const TRect& aRect) { CTApparcTestAppView* self = new(ELeave) CTApparcTestAppView(); CleanupStack::PushL(self); self->ConstructL(aRect); CleanupStack::Pop(); return self; }CTApparcTestAppView::~CTApparcTestAppView() { delete iApparcTestText; }void CTApparcTestAppView::ConstructL(const TRect& aRect) { iApparcTestText = iEikonEnv->AllocReadResourceL(R_TAPPARCTEST_TEXT_TITLE); CreateWindowL(); SetRect(aRect); ActivateL(); }void CTApparcTestAppView::Draw(const TRect& /*aRect*/) const { CWindowGc& gc = SystemGc(); TRect drawRect = Rect(); const CFont* fontUsed = iEikonEnv->TitleFont(); gc.Clear(); gc.UseFont(fontUsed); TInt baselineOffset=(drawRect.Height() - fontUsed->HeightInPixels())/2; gc.DrawText(*iApparcTestText,drawRect,baselineOffset,CGraphicsContext::ECenter, 0); gc.DiscardFont(); }////// CTApparcTestAppUi////class CTApparcTestAppUi : public CEikAppUi {public: void ConstructL(); ~CTApparcTestAppUi();private: // Inherirted from class CEikAppUi void PrepareToExit(); void HandleCommandL(TInt aCommand);private: CCoeControl* iAppView; };void CTApparcTestAppUi::ConstructL() { BaseConstructL(); iAppView = CTApparcTestAppView::NewL(ClientRect()); // Constructs the static object for tests CTApparcTestNegativePrioStaticB* testCoeStaticB = CTApparcTestNegativePrioStaticB::NewL(); CTApparcTestStatic* testCoeStatic = new (ELeave)CTApparcTestStatic(testCoeStaticB->iFile); CTApparcTestNegativePrioStaticA* testCoeStaticA = new(ELeave)CTApparcTestNegativePrioStaticA(testCoeStaticB->iFile); CTApparcTestPrioTwoStaticC* testPrioTwoStaticC = new(ELeave) CTApparcTestPrioTwoStaticC(testCoeStaticB->iFile); CTApparcTestPosPrioStaticA* testPosPriStaticA = new(ELeave) CTApparcTestPosPrioStaticA(testCoeStaticB->iFile); CTApparcTestPosPrioStaticB* testPosPriStaticB = new(ELeave) CTApparcTestPosPrioStaticB(testCoeStaticB->iFile); CTApparcTestPrioZeroStaticA* testPrioZeroStaticA = new(ELeave) CTApparcTestPrioZeroStaticA(testCoeStaticB->iFile); CTApparcTestPrioOneStaticB* testPrioOneStaticB = new(ELeave) CTApparcTestPrioOneStaticB(testCoeStaticB->iFile); // to get rid of compiler warnings if(testCoeStatic==NULL || testCoeStaticA == NULL || testCoeStaticB == NULL|| testPosPriStaticA ==NULL || testPosPriStaticB == NULL || testPrioZeroStaticA == NULL || testPrioOneStaticB == NULL|| testPrioTwoStaticC == NULL) return; }CTApparcTestAppUi::~CTApparcTestAppUi() { CTApparcTestNegativePrioStaticB* testNegStaticB = CTApparcTestNegativePrioStaticB::Self(); // Test 1, Case 2 CTApparcTestStatic* testCoeStatic = CTApparcTestStatic::Self(); testNegStaticB->iFile.Write(KApparcTest1); testNegStaticB->iFile.Write(KApparcTestCase2); if(testCoeStatic == NULL) testNegStaticB->iFile.Write(KTestPass); else testNegStaticB->iFile.Write(KTestFail); // Test 2, Case 1 CTApparcTestNegativePrioStaticA* testCoeStaticA = CTApparcTestNegativePrioStaticA::Self(); testNegStaticB->iFile.Write(KApparcTest2); testNegStaticB->iFile.Write(KApparcTestCase1); if(testCoeStaticA != NULL) testNegStaticB->iFile.Write(KTestPass); else testNegStaticB->iFile.Write(KTestFail); // Test 4, Case 1 CTApparcTestPrioZeroStaticA* testPrioZeroCoeStaticA = CTApparcTestPrioZeroStaticA::Self(); CTApparcTestPrioOneStaticB* testPrioOneCoeStaticB = CTApparcTestPrioOneStaticB::Self(); CTApparcTestPrioTwoStaticC* testPrioTwoCoeStaticC = CTApparcTestPrioTwoStaticC::Self(); testNegStaticB->iFile.Write(KApparcTest4); testNegStaticB->iFile.Write(KApparcTestCase1); if(testPrioZeroCoeStaticA == NULL && testPrioOneCoeStaticB != NULL && testPrioTwoCoeStaticC != NULL) testNegStaticB->iFile.Write(KTestPass); else testNegStaticB->iFile.Write(KTestFail); delete iAppView; }void CTApparcTestAppUi::HandleCommandL(TInt aCommand) { switch (aCommand) { case EEikCmdExit: Exit(); break; } }void CTApparcTestAppUi::PrepareToExit() { CEikAppUi::PrepareToExit(); // Test 1, Case 1 CTApparcTestStatic* testCoeStatic = CTApparcTestStatic::Self(); testCoeStatic->iFile.Write(KApparcTest1); testCoeStatic->iFile.Write(KApparcTestCase1); if(testCoeStatic != NULL) testCoeStatic->iFile.Write(KTestPass); else testCoeStatic->iFile.Write(KTestFail); }////// CTApparcTestDocument////class CTApparcTestDocument : public CEikDocument {public: static CTApparcTestDocument* NewL(CEikApplication& aApp); CTApparcTestDocument(CEikApplication& aApp); void ConstructL();private: // Inherited from CEikDocument CEikAppUi* CreateAppUiL(); };CTApparcTestDocument::CTApparcTestDocument(CEikApplication& aApp) : CEikDocument(aApp) { }CEikAppUi* CTApparcTestDocument::CreateAppUiL() { return new(ELeave) CTApparcTestAppUi; }////// CTApparcTestApplication////class CTApparcTestApplication : public CEikApplication {private: // Inherited from class CApaApplication CApaDocument* CreateDocumentL(); TUid AppDllUid() const;private: CApaDocument* CreateDocumentL(CApaProcess* a) { return CEikApplication::CreateDocumentL(a); } };TUid CTApparcTestApplication::AppDllUid() const { return KUidApparcTestApp; }CApaDocument* CTApparcTestApplication::CreateDocumentL() { return new (ELeave) CTApparcTestDocument(*this); }EXPORT_C CApaApplication* NewApplication() { return new CTApparcTestApplication; }GLDEF_C TInt E32Main() { return EikStart::RunApplication(NewApplication); }// inline function for CTApparcTestStaticinline CTApparcTestStatic::CTApparcTestStatic(RFile& aFile) : CCoeStatic(KUidTestStatic),iFile(aFile) { }inline CTApparcTestStatic* CTApparcTestStatic::Self() { return STATIC_CAST(CTApparcTestStatic*,CCoeEnv::Static(KUidTestStatic)); }// inline functions for CTApparcTestNegativePrioStaticAinline CTApparcTestNegativePrioStaticA::CTApparcTestNegativePrioStaticA(RFile& aFile) : CCoeStatic(KUidTestStaticNegativePrioA,ENegativePriortyStaticA),iFile(aFile) { }inline CTApparcTestNegativePrioStaticA* CTApparcTestNegativePrioStaticA::Self() { return STATIC_CAST(CTApparcTestNegativePrioStaticA*,CCoeEnv::Static(KUidTestStaticNegativePrioA)); }// inline functions for CTApparcTestNegativePrioStaticB inline CTApparcTestNegativePrioStaticB::CTApparcTestNegativePrioStaticB() : CCoeStatic(KUidTestStaticNegativePrioB,ENegativePriortyStaticA - 1) { }inline CTApparcTestNegativePrioStaticB* CTApparcTestNegativePrioStaticB::Self() { return STATIC_CAST(CTApparcTestNegativePrioStaticB*,CCoeEnv::Static(KUidTestStaticNegativePrioB)); }CTApparcTestNegativePrioStaticB* CTApparcTestNegativePrioStaticB::NewL() { CTApparcTestNegativePrioStaticB* self = new(ELeave)CTApparcTestNegativePrioStaticB(); CleanupStack::PushL(self); self->ConstructL(); CleanupStack::Pop(); return self; }void CTApparcTestNegativePrioStaticB::ConstructL() { User::LeaveIfError(iFs.Connect()); TInt err = iFs.MkDirAll(KApparcTestDir); err = iFile.Create(iFs,KApparcTestResultsFileName,EFileWrite | EFileShareAny); if(err == KErrAlreadyExists) iFile.Open(iFs,KApparcTestResultsFileName,EFileWrite | EFileShareAny); }// inline functions for CTApparcTestPosPrioStaticA inline CTApparcTestPosPrioStaticA::CTApparcTestPosPrioStaticA(RFile& aFile) : CCoeStatic(KUidTestStaticPosPriA,EDefaultDestructionPriority),iFile(aFile) { }inline CTApparcTestPosPrioStaticA* CTApparcTestPosPrioStaticA::Self() { return STATIC_CAST(CTApparcTestPosPrioStaticA*,CCoeEnv::Static(KUidTestStaticPosPriA)); }// inline functions for CTApparcTestPosPrioStaticB inline CTApparcTestPosPrioStaticB::CTApparcTestPosPrioStaticB(RFile& aFile) : CCoeStatic(KUidTestStaticPosPriB,EDefaultDestructionPriority-1),iFile(aFile) { }inline CTApparcTestPosPrioStaticB* CTApparcTestPosPrioStaticB::Self() { return STATIC_CAST(CTApparcTestPosPrioStaticB*,CCoeEnv::Static(KUidTestStaticPosPriB)); }// inline functions for CTApparcTestPrioZeroStaticA inline CTApparcTestPrioZeroStaticA::CTApparcTestPrioZeroStaticA(RFile& aFile) : CCoeStatic(KUidTestStaticPriZeroA,EPriorityZeroStaticA),iFile(aFile) { }inline CTApparcTestPrioZeroStaticA* CTApparcTestPrioZeroStaticA::Self() { return STATIC_CAST(CTApparcTestPrioZeroStaticA*,CCoeEnv::Static(KUidTestStaticPriZeroA)); }// inline functions for CTApparcTestPrioOneStaticB inline CTApparcTestPrioOneStaticB::CTApparcTestPrioOneStaticB(RFile& aFile) : CCoeStatic(KUidTestStaticPriOneB,EPriorityOneStaticB),iFile(aFile) { }inline CTApparcTestPrioOneStaticB* CTApparcTestPrioOneStaticB::Self() { return STATIC_CAST(CTApparcTestPrioOneStaticB*,CCoeEnv::Static(KUidTestStaticPriOneB)); }// inline functions for CTApparcTestPrioTwoStaticC inline CTApparcTestPrioTwoStaticC::CTApparcTestPrioTwoStaticC(RFile& aFile) : CCoeStatic(KUidTestStaticPriTwoC,EPriorityTwoStaticC),iFile(aFile) { }inline CTApparcTestPrioTwoStaticC* CTApparcTestPrioTwoStaticC::Self(){ return STATIC_CAST(CTApparcTestPrioTwoStaticC*,CCoeEnv::Static(KUidTestStaticPriTwoC));}