// 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:
//
#include "testframeutils.h"
_LIT(KCantOpenFile, "Could not open file: %S");
_LIT(KSectionNotFound, "Could not find section: %S");
_LIT(KMiscFileError, "File error");
_LIT(KInfoTestFinished, "[%4d] Test finished: %S");
_LIT(KInfoTestStarted, "[%4d] Starting test: %S");
_LIT(KInfoTestError, "[%4d] Test failed in section: %S, command %S, reason %d");
//
//
// TTestDebugInfo
//
TInt TTestDebugInfo::LineNumber()
{
return iLineNumber;
}
HBufC* TTestDebugInfo::TestStartStringLC()
{
TBuf<256> startString;
HBufC* sectionName = TestHarnessNameLC();
startString.Format(KInfoTestStarted, iLineNumber, sectionName);
CleanupStack::PopAndDestroy(sectionName);
HBufC* startStringHBufC = HBufC::NewLC(startString.Length());
(startStringHBufC->Des()).Copy(startString);
return startStringHBufC;
}
HBufC* TTestDebugInfo::TestCompleteStringLC()
{
TBuf<256> startString;
HBufC* sectionName = TestHarnessNameLC();
startString.Format(KInfoTestFinished, iLineNumber, sectionName);
CleanupStack::PopAndDestroy(sectionName);
HBufC* startStringHBufC = HBufC::NewLC(startString.Length());
(startStringHBufC->Des()).Copy(startString);
return startStringHBufC;
}
HBufC* TTestDebugInfo::TestFailedStringLC(TInt aReason)
{
TBuf<256> failedString;
HBufC* sectionName = SectionNameLC();
HBufC* commandName = CommandNameLC();
failedString.Format(KInfoTestError, iLineNumber, sectionName, commandName, aReason);
CleanupStack::PopAndDestroy(2, sectionName);
HBufC* failedStringHBufC = HBufC::NewLC(failedString.Length());
(failedStringHBufC->Des()).Copy(failedString);
return failedStringHBufC;
}
void TTestDebugInfo::SetTestHarnessName(TInt aTestHarnessPosition)
{
iTestHarnessPosition = aTestHarnessPosition;
}
HBufC* TTestDebugInfo::SectionNameLC()
{
TBuf8<128> sectionName;
iScriptFile->GetLineL(sectionName, iSectionPosition);
HBufC* sectionNameHBufC = HBufC::NewLC(sectionName.Length());
sectionNameHBufC->Des().Copy(sectionName);
return sectionNameHBufC;
}
HBufC* TTestDebugInfo::TestHarnessNameLC()
{
TBuf8<128> sectionName;
iScriptFile->GetLineL(sectionName, iTestHarnessPosition);
HBufC* sectionNameHBufC = HBufC::NewLC(sectionName.Length());
sectionNameHBufC->Des().Copy(sectionName);
return sectionNameHBufC;
}
HBufC* TTestDebugInfo::CommandNameLC()
{
TBuf8<128> commandName;
iScriptFile->GetLineL(commandName, iCommandPosition);
HBufC* commandNameHBufC = HBufC::NewLC(commandName.Length());
commandNameHBufC->Des().Copy(commandName);
return commandNameHBufC;
}
TTestDebugInfo::TTestDebugInfo(CTestScript& aTestScript, TInt aSectionPosition, TInt aCommandPosition, TInt aLineNumber) : iScriptFile(&aTestScript), iSectionPosition(aSectionPosition), iCommandPosition(aCommandPosition), iLineNumber(aLineNumber)
{
}
TTestDebugInfo::TTestDebugInfo(CTestScript& aTestScript, TInt aSectionPosition, TInt aCommandPosition) : iScriptFile(&aTestScript), iSectionPosition(aSectionPosition), iCommandPosition(aCommandPosition), iLineNumber(0)
{
}
TTestDebugInfo::TTestDebugInfo() : iScriptFile(0), iSectionPosition(0), iCommandPosition(0), iLineNumber(0)
{
}
//
//
// CTestScript
//
CTestScript::~CTestScript()
{
delete iSectionPositions;
iFile.Close();
}
CTestScript* CTestScript::NewL(RFs& aFs)
{
CTestScript* self = new (ELeave) CTestScript(aFs);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
void CTestScript::ConstructL()
{
iSectionPositions = new (ELeave) CArrayFixFlat<TSectionPosition>(10);
}
TBool CTestScript::LoadFileL(const TDesC& aFileName)
{
iFile.Close();
TBool loaded = EFalse;
iSectionPositions->ResizeL(0);
iEndOfFile = EFalse;
TTestScriptString line;
TInt err = iFile.Open(iFs, aFileName, EFileShareAny);
if (err == KErrNone)
// Scan the file for file sections, eg. [section1]
{
TInt lineNumber = 0;
TSectionPosition section;
section.iSectionPosition = 0;
while (GetLineL(line))
{
lineNumber++;
if (IsSection(line))
// If the line is the start of a section then add it to the list.
{
// Strip the '[' and ']' characters
line = line.Mid(1, line.Size() - 2);
// Store the section name and the position
section.iSectionName = line;
section.iFilePosition = 0;
section.iLineNumber = lineNumber;
err = iFile.Seek(ESeekCurrent, section.iFilePosition);
iSectionPositions->AppendL(section);
}
section.iSectionPosition = 0;
err = iFile.Seek(ESeekCurrent, section.iSectionPosition);
}
loaded = ETrue;
}
else
{
iLastError.Format(KCantOpenFile, aFileName);
}
return loaded;
}
CTestSection* CTestScript::GetSectionL(const TDesC& aSectionName)
{
CTestSection* newSection = 0;
TSectionPosition section;
TTestScriptString command;
TBool sectionFound = EFalse;
// Look for the section name in the array
TInt sectionIndex = iSectionPositions->Count();
TBuf<128> tempSectionNameU;
while ((sectionIndex--) && (!sectionFound))
{
tempSectionNameU.Copy(((*iSectionPositions)[sectionIndex]).iSectionName);
if (tempSectionNameU == aSectionName)
{
section = (*iSectionPositions)[sectionIndex];
sectionFound = ETrue;
}
}
if (!sectionFound)
{
iLastError.Format(KSectionNotFound, aSectionName);
}
else
{
newSection = CTestSection::NewL(section.iSectionPosition, tempSectionNameU, section.iLineNumber);
CleanupStack::PushL(newSection);
TInt err = iFile.Seek(ESeekStart, section.iFilePosition);
if (err == KErrNone)
{
TInt commandLineNumber = section.iLineNumber;
TInt commandPosition = 0;
iFile.Seek(ESeekCurrent, commandPosition);
while (GetNextCommandInSectionL(command, commandLineNumber))
{
newSection->AddCommandL(command, commandPosition, commandLineNumber);
commandPosition = 0;
iFile.Seek(ESeekCurrent, commandPosition);
}
}
else
{
iLastError = KMiscFileError;
}
CleanupStack::Pop(newSection);
}
return newSection;
}
CTestScript::CTestScript(RFs& aFs) : iFs(aFs)
{
}
TBool CTestScript::GetLineL(TTestScriptString& aLine)
{
TBool noError = EFalse;
TInt startPosition = 0;
// Save the current position
TInt err = iFile.Seek(ESeekCurrent, startPosition);
if (err == KErrNone)
{
// Read a block of data
TTestScriptString dataFromFile;
err = iFile.Read(dataFromFile);
if (err != KErrNone)
{
iLastError.Copy(KMiscFileError);
}
else
{
// Look for the cr/lf pair or the end of the line
TInt bytesOnLine = 0;
TBool finished = EFalse;
while (!finished)
{
if (bytesOnLine == dataFromFile.Size())
{
finished = ETrue;
}
else if (dataFromFile[bytesOnLine] == 0x0d)
{
finished = ETrue;
}
else
{
bytesOnLine++;
}
}
TInt startOfNextLine = startPosition + bytesOnLine + 1;
if (bytesOnLine+1 < dataFromFile.Size())
{
if (dataFromFile[bytesOnLine+1] == 0x0a)
{
startOfNextLine++;
}
}
// Seek to after the cr/lf pair
iFile.Seek(ESeekStart, startOfNextLine);
// Set the line
aLine.Copy(dataFromFile.Left(bytesOnLine));
// Get rid of any trailing white-space
TInt whiteSpaceIndex = aLine.Size();
TBool noMoreWhiteSpace = EFalse;
while ((whiteSpaceIndex--) && (!noMoreWhiteSpace))
{
if ((aLine[whiteSpaceIndex] == ' ')
|| (aLine[whiteSpaceIndex] == '\t'))
{
aLine.SetLength(whiteSpaceIndex);
}
else
{
noMoreWhiteSpace = ETrue;
}
}
if (dataFromFile.Size() != 0)
{
noError = ETrue;
}
}
}
return noError;
}
TBool CTestScript::IsSection(const TDesC8& aLine) const
{
TBool isSection = EFalse;
if (aLine.Size() > 2)
{
if (aLine[0] == '[' && (aLine[aLine.Size() - 1] == ']'))
{
isSection = ETrue;
}
}
return isSection;
}
TBool CTestScript::IsSectionEnd(const TDesC8& aLine) const
{
TBool isSectionEnd = EFalse;
if (aLine.Length() == 1 && aLine[0] == '.')
{
isSectionEnd = ETrue;
}
return isSectionEnd;
}
// MU 20-11-00 New command to determine if the aLine is a comment.
TBool CTestScript::IsComment(const TDesC8& aLine) const
{
TBool isComment = EFalse;
if (aLine.Size() >= 2)
{
if (aLine[0] == '/' && aLine[1] == '/')
{
isComment = ETrue;
}
}
return isComment;
}
// MU 20-11-00 Changed this function to get the next "valid" command in section.
// This now allows the user to have comments within sections.
// Note: the first blank line in a section denotes the end of a section.
TBool CTestScript::GetNextCommandInSectionL(TTestScriptString& aCommand, TInt& aLineNumber)
{
TBool commandFound;
do {
GetLineL(aCommand);
aLineNumber++;
}
while (aCommand.Size() > 0 && IsComment(aCommand));
if(aCommand.Size() > 0 && !IsSection(aCommand) && !IsSectionEnd(aCommand))
commandFound = ETrue;
else
commandFound = EFalse;
return commandFound;
}
TBool CTestScript::GetLineL(TTestScriptString& aLine, TInt aPos)
{
TBool lineFound = EFalse;
TInt err = iFile.Seek(ESeekStart, aPos);
if (err == KErrNone)
{
lineFound = GetLineL(aLine);
}
return lineFound;
}
//
//
// CTestSection
//
CTestSection* CTestSection::NewL(TInt aSectionPosition, const TDesC& aSectionName, TInt aLineNumber)
{
CTestSection* self = new (ELeave) CTestSection(aSectionPosition, aLineNumber);
CleanupStack::PushL(self);
self->ConstructL();
self->iSectionName = aSectionName;
CleanupStack::Pop(self);
return self;
}
// Returns current command line number if found
TInt CTestSection::GetCurrentCommand(TDes& aCurrentCommand) const
{
TInt currentCommand = 0;
if (iCommandIndex < iCommandList->Count())
{
aCurrentCommand.Copy((*iCommandList)[iCommandIndex].iCommand);
currentCommand = (*iCommandList)[iCommandIndex].iLineNumber;
}
return currentCommand;
}
TBool CTestSection::NextCommand()
{
TBool nextCommandFound = EFalse;
if ((iCommandIndex + 1) < iCommandList->Count())
{
nextCommandFound = ETrue;
}
iCommandIndex++;
return nextCommandFound;
}
void CTestSection::AddCommandL(const CTestScript::TTestScriptString& aCommand, TInt aCommandPosition, TInt aLineNumber)
{
TCommandInfo command;
command.iCommand = aCommand;
command.iCommandPosition = aCommandPosition;
command.iLineNumber = aLineNumber;
iCommandList->AppendL(command);
}
CTestSection::CTestSection(TInt aSectionPosition, TInt aLineNumber) : iSectionPosition(aSectionPosition), iLineNumber(aLineNumber)
{
}
void CTestSection::ConstructL()
{
iCommandList = new (ELeave) CArrayFixFlat<TCommandInfo>(10);
}
CTestSection::~CTestSection()
{
delete iCommandList;
}
TInt CTestSection::SectionPosition() const
{
return iSectionPosition;
}
TInt CTestSection::CurrentCommandPosition() const
{
return (*iCommandList)[iCommandIndex].iCommandPosition;
}
const TDesC& CTestSection::SectionName() const
{
return iSectionName;
}