mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-21 21:38:15 +02:00

- added AssertSame, AssertNotSame, AssertNull, AssertNotNull for pointers - fixed a TTestCase test: thanks to Peter Vreman RTTI method names are not uppercase anymore in 1.9.7
932 lines
24 KiB
ObjectPascal
932 lines
24 KiB
ObjectPascal
{$mode objfpc}
|
|
{$h+}
|
|
{
|
|
$Id$
|
|
This file is part of the Free Component Library (FCL)
|
|
Copyright (c) 2004 by Dean Zobec, Michael Van Canneyt
|
|
|
|
Port to Free Pascal of the JUnit framework.
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
**********************************************************************}
|
|
unit fpcunit;
|
|
|
|
interface
|
|
|
|
{$define SHOWLINEINFO}
|
|
|
|
uses
|
|
{$ifdef SHOWLINEINFO}
|
|
LineInfo,
|
|
{$endif}
|
|
SysUtils, Classes;
|
|
|
|
type
|
|
|
|
EAssertionFailedError = class(Exception)
|
|
constructor Create; overload;
|
|
constructor Create(const msg :string); overload;
|
|
end;
|
|
|
|
TRunMethod = procedure of object;
|
|
|
|
TTestResult = class;
|
|
|
|
{$M+}
|
|
TTest = class(TObject)
|
|
protected
|
|
function GetTestName: string; virtual;
|
|
function GetTestSuiteName: string; virtual;
|
|
procedure SetTestSuiteName(const aName: string); virtual; abstract;
|
|
public
|
|
function CountTestCases: integer; virtual;
|
|
procedure Run(AResult: TTestResult); virtual;
|
|
published
|
|
property TestName: string read GetTestName;
|
|
property TestSuiteName: string read GetTestSuiteName write SetTestSuiteName;
|
|
end;
|
|
{$M-}
|
|
|
|
TAssert = class(TTest)
|
|
public
|
|
class procedure Fail(const AMessage: string);
|
|
class procedure AssertTrue(const AMessage: string; ACondition: boolean); overload;
|
|
class procedure AssertTrue(ACondition: boolean); overload;
|
|
class procedure AssertFalse(const AMessage: string; ACondition: boolean); overload;
|
|
class procedure AssertFalse(ACondition: boolean); overload;
|
|
class procedure AssertEquals(const AMessage: string; Expected, Actual: string); overload;
|
|
class procedure AssertEquals(Expected, Actual: string); overload;
|
|
class procedure AssertEquals(const AMessage: string; Expected, Actual: integer); overload;
|
|
class procedure AssertEquals(Expected, Actual: integer); overload;
|
|
class procedure AssertEquals(const AMessage: string; Expected, Actual: int64); overload;
|
|
class procedure AssertEquals(Expected, Actual: int64); overload;
|
|
class procedure AssertEquals(const AMessage: string; Expected, Actual: currency); overload;
|
|
class procedure AssertEquals(Expected, Actual: currency); overload;
|
|
class procedure AssertEquals(const AMessage: string; Expected, Actual, Delta: double); overload;
|
|
class procedure AssertEquals(Expected, Actual, Delta: double); overload;
|
|
class procedure AssertEquals(const AMessage: string; Expected, Actual: boolean); overload;
|
|
class procedure AssertEquals(Expected, Actual: boolean); overload;
|
|
class procedure AssertEquals(const AMessage: string; Expected, Actual: char); overload;
|
|
class procedure AssertEquals(Expected, Actual: char); overload;
|
|
class procedure AssertEquals(const AMessage: string; Expected, Actual: TClass); overload;
|
|
class procedure AssertEquals(Expected, Actual: TClass); overload;
|
|
class procedure AssertSame(const AMessage: string; Expected, Actual: TObject); overload;
|
|
class procedure AssertSame(Expected, Actual: TObject); overload;
|
|
class procedure AssertSame(const AMessage: string; Expected, Actual: Pointer); overload;
|
|
class procedure AssertSame(Expected, Actual: Pointer); overload;
|
|
class procedure AssertNotSame(const AMessage: string; Expected, Actual: TObject); overload;
|
|
class procedure AssertNotSame(Expected, Actual: TObject); overload;
|
|
class procedure AssertNotSame(const AMessage: string; Expected, Actual: Pointer); overload;
|
|
class procedure AssertNotSame(Expected, Actual: Pointer); overload;
|
|
class procedure AssertNotNull(const AMessage: string; AObject: TObject); overload;
|
|
class procedure AssertNotNull(AObject: TObject); overload;
|
|
class procedure AssertNotNull(const AMessage: string; APointer: Pointer); overload;
|
|
class procedure AssertNotNull(APointer: Pointer); overload;
|
|
class procedure AssertNull(const AMessage: string; AObject: TObject); overload;
|
|
class procedure AssertNull(AObject: TObject); overload;
|
|
class procedure AssertNull(const AMessage: string; APointer: Pointer); overload;
|
|
class procedure AssertNull(APointer: Pointer); overload;
|
|
class procedure AssertNotNull(const AMessage, AString: string); overload;
|
|
class procedure AssertNotNull(const AString: string); overload;
|
|
class procedure AssertException(const AMessage: string; AExceptionClass: ExceptClass; AMethod: TRunMethod); overload;
|
|
class procedure AssertException(AExceptionClass: ExceptClass; AMethod: TRunMethod); overload;
|
|
end;
|
|
|
|
TTestFailure = class(TObject)
|
|
private
|
|
FTestName: string;
|
|
FTestSuiteName: string;
|
|
FLineNumber: longint;
|
|
FMethodName: string;
|
|
FRaisedExceptionClass: TClass;
|
|
FRaisedExceptionMessage: string;
|
|
FSourceUnitName: string;
|
|
function GetAsString: string;
|
|
function GetExceptionMessage: string;
|
|
function GetIsFailure: boolean;
|
|
function GetExceptionClassName: string;
|
|
public
|
|
constructor CreateFailure(ATest: TTest; E: Exception);
|
|
property ExceptionClass: TClass read FRaisedExceptionClass;
|
|
published
|
|
property AsString: string read GetAsString;
|
|
property IsFailure: boolean read GetIsFailure;
|
|
property ExceptionMessage: string read GetExceptionMessage;
|
|
property ExceptionClassName: string read GetExceptionClassName;
|
|
property SourceUnitName: string read FSourceUnitName write FSourceUnitName;
|
|
property LineNumber: longint read FLineNumber write FLineNumber;
|
|
property MethodName: string read FMethodName write FMethodName;
|
|
end;
|
|
|
|
ITestListener = interface
|
|
['{0CE9D3AE-882A-D811-9401-ADEB5E4C7FC1}']
|
|
procedure AddFailure(ATest: TTest; AFailure: TTestFailure);
|
|
procedure AddError(ATest: TTest; AError: TTestFailure);
|
|
procedure StartTest(ATest: TTest);
|
|
procedure EndTest(ATest: TTest);
|
|
end;
|
|
|
|
TTestCase = class(TAssert)
|
|
private
|
|
FName: string;
|
|
FTestSuiteName: string;
|
|
protected
|
|
function CreateResult: TTestResult; virtual;
|
|
procedure SetUp; virtual;
|
|
procedure TearDown; virtual;
|
|
procedure RunTest; virtual;
|
|
function GetTestName: string; override;
|
|
function GetTestSuiteName: string; override;
|
|
procedure SetTestSuiteName(const aName: string); override;
|
|
procedure SetTestName(const Value: string); virtual;
|
|
public
|
|
constructor Create; virtual;
|
|
constructor CreateWith(const AName: string; const ATestSuiteName: string); virtual;
|
|
constructor CreateWithName(const AName: string); virtual;
|
|
function CountTestCases: integer; override;
|
|
function CreateResultAndRun: TTestResult; virtual;
|
|
procedure Run(AResult: TTestResult); override;
|
|
procedure RunBare; virtual;
|
|
function AsString: string;
|
|
property TestSuiteName: string read GetTestSuiteName write SetTestSuiteName;
|
|
published
|
|
property TestName: string read GetTestName write SetTestName;
|
|
end;
|
|
|
|
TTestClass = Class of TTestCase;
|
|
|
|
TTestSuite = class(TTest)
|
|
private
|
|
FTests: TList;
|
|
FName: string;
|
|
FTestSuiteName: string;
|
|
function GetTest(Index: integer): TTest;
|
|
protected
|
|
function GetTestName: string; override;
|
|
function GetTestSuiteName: string; override;
|
|
procedure SetTestSuiteName(const aName: string); override;
|
|
procedure SetTestName(const Value: string); virtual;
|
|
public
|
|
constructor Create(AClass: TClass; AName: string); reintroduce; overload; virtual;
|
|
constructor Create(AClass: TClass); reintroduce; overload; virtual;
|
|
constructor Create(AClassArray: Array of TClass); reintroduce; overload; virtual;
|
|
constructor Create(AName: string); reintroduce; overload; virtual;
|
|
constructor Create; reintroduce; overload; virtual;
|
|
destructor Destroy; override;
|
|
function CountTestCases: integer; override;
|
|
procedure Run(AResult: TTestResult); override;
|
|
procedure RunTest(ATest: TTest; AResult: TTestResult); virtual;
|
|
procedure AddTest(ATest: TTest); overload; virtual;
|
|
procedure AddTestSuiteFromClass(ATestClass: TClass); virtual;
|
|
class function Warning(const aMessage: string): TTestCase;
|
|
property Test[Index: integer]: TTest read GetTest; default;
|
|
property TestSuiteName: string read GetTestSuiteName write SetTestSuiteName;
|
|
property TestName: string read GetTestName write SetTestName;
|
|
property Tests: TList read FTests;
|
|
end;
|
|
|
|
TTestResult = class(TObject)
|
|
private
|
|
protected
|
|
FRunTests: integer;
|
|
FFailures: TList;
|
|
FErrors: TList;
|
|
FListeners: TList;
|
|
function GetNumErrors: integer;
|
|
function GetNumFailures: integer;
|
|
public
|
|
constructor Create; virtual;
|
|
destructor Destroy; override;
|
|
property Listeners: TList read FListeners;
|
|
procedure ClearErrorLists;
|
|
procedure StartTest(ATest: TTest);
|
|
procedure AddFailure(ATest: TTest; E: EAssertionFailedError);
|
|
procedure AddError(ATest: TTest; E: Exception; AUnitName: string;
|
|
AMethodName: string; ALineNumber: longint);
|
|
procedure EndTest(ATest: TTest);
|
|
procedure AddListener(AListener: ITestListener);
|
|
procedure RemoveListener(AListener: ITestListener);
|
|
procedure Run(ATestCase: TTestCase);
|
|
procedure RunProtected(ATestCase: TTestCase);
|
|
function WasSuccessful: boolean;
|
|
published
|
|
property Failures: TList read FFailures;
|
|
property Errors: TList read FErrors;
|
|
property RunTests: integer read FRunTests;
|
|
property NumberOfErrors: integer read GetNumErrors;
|
|
property NumberOfFailures: integer read GetNumFailures;
|
|
end;
|
|
|
|
function ComparisonMsg(const aExpected: string; const aActual: string): string;
|
|
|
|
Resourcestring
|
|
|
|
SCompare = ' expected: <%s> but was: <%s>';
|
|
SExpectedNotSame = 'expected not same';
|
|
SExceptionCompare = 'Exception %s expected but %s was raised';
|
|
SMethodNotFound = 'Method <%s> not found';
|
|
SNoValidInheritance = ' does not inherit from TTestCase';
|
|
SNoValidTests = 'No valid tests found in ';
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
testutils;
|
|
|
|
type
|
|
|
|
TTestWarning = class(TTestCase)
|
|
private
|
|
FMessage: String;
|
|
protected
|
|
procedure RunTest; override;
|
|
end;
|
|
|
|
procedure TTestWarning.RunTest;
|
|
begin
|
|
Fail(FMessage);
|
|
end;
|
|
|
|
function ComparisonMsg(const aExpected: string; const aActual: string): string;
|
|
begin
|
|
Result := format(SCompare, [aExpected, aActual]);
|
|
end;
|
|
|
|
constructor EAssertionFailedError.Create;
|
|
begin
|
|
inherited Create('');
|
|
end;
|
|
|
|
constructor EAssertionFailedError.Create(const msg: string);
|
|
begin
|
|
inherited Create(msg);
|
|
end;
|
|
|
|
constructor TTestFailure.CreateFailure(ATest: TTest; E: Exception);
|
|
begin
|
|
inherited Create;
|
|
FTestName := ATest.GetTestName;
|
|
FTestSuiteName := ATest.GetTestSuiteName;
|
|
FRaisedExceptionClass := E.ClassType;
|
|
FRaisedExceptionMessage := E.Message;
|
|
end;
|
|
|
|
function TTestFailure.GetAsString: string;
|
|
var
|
|
s: string;
|
|
begin
|
|
if FTestSuiteName <> '' then
|
|
s := FTestSuiteName + '.'
|
|
else
|
|
s := '';
|
|
Result := s + FTestName + ': ' + FRaisedExceptionMessage;
|
|
end;
|
|
|
|
function TTestFailure.GetExceptionClassName: string;
|
|
begin
|
|
Result := FRaisedExceptionClass.ClassName;
|
|
end;
|
|
|
|
function TTestFailure.GetExceptionMessage: string;
|
|
begin
|
|
Result := FRaisedExceptionMessage;
|
|
end;
|
|
|
|
function TTestFailure.GetIsFailure: boolean;
|
|
begin
|
|
Result := FRaisedExceptionClass.InheritsFrom(EAssertionFailedError);
|
|
end;
|
|
|
|
{ TTest}
|
|
|
|
function TTest.GetTestName: string;
|
|
begin
|
|
Result := 'TTest';
|
|
end;
|
|
|
|
function TTest.GetTestSuiteName: string;
|
|
begin
|
|
Result := 'TTest';
|
|
end;
|
|
|
|
function TTest.CountTestCases: integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
procedure TTest.Run(AResult: TTestResult);
|
|
begin
|
|
end;
|
|
|
|
{ TAssert }
|
|
|
|
class procedure TAssert.Fail(const AMessage: String);
|
|
begin
|
|
raise EAssertionFailedError.Create(AMessage);
|
|
end;
|
|
|
|
class procedure TAssert.AssertTrue(const AMessage: String; ACondition: Boolean);
|
|
begin
|
|
if (not ACondition) then
|
|
Fail(AMessage);
|
|
end;
|
|
|
|
class procedure TAssert.AssertTrue(ACondition: Boolean);
|
|
begin
|
|
AssertTrue('', ACondition);
|
|
end;
|
|
|
|
class procedure TAssert.AssertFalse(const AMessage: String; ACondition: Boolean);
|
|
begin
|
|
AssertTrue(AMessage, not ACondition);
|
|
end;
|
|
|
|
class procedure TAssert.AssertFalse(ACondition: Boolean);
|
|
begin
|
|
AssertFalse('', ACondition);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(const AMessage: string; Expected, Actual: string);
|
|
begin
|
|
AssertTrue(AMessage + ComparisonMsg(Expected, Actual), AnsiCompareStr(Expected, Actual) = 0);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(Expected, Actual: string);
|
|
begin
|
|
AssertEquals('', Expected, Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotNull(const AString: string);
|
|
begin
|
|
AssertNotNull('', AString);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(const AMessage: string; Expected, Actual: integer);
|
|
begin
|
|
AssertTrue(AMessage + ComparisonMsg(IntToStr(Expected), IntToStr(Actual)), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(Expected, Actual: integer);
|
|
begin
|
|
AssertEquals('', Expected, Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(const AMessage: string; Expected, Actual: int64);
|
|
begin
|
|
AssertTrue(AMessage + ComparisonMsg(IntToStr(Expected), IntToStr(Actual)), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(Expected, Actual: int64);
|
|
begin
|
|
AssertEquals('', Expected, Actual);
|
|
end;
|
|
|
|
|
|
class procedure TAssert.AssertEquals(const AMessage: string; Expected, Actual: currency);
|
|
begin
|
|
AssertTrue(AMessage + ComparisonMsg(FloatToStr(Expected), FloatToStr(Actual)), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(Expected, Actual: currency);
|
|
begin
|
|
AssertEquals('', Expected, Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(const AMessage: string; Expected, Actual, Delta: double);
|
|
begin
|
|
AssertTrue(AMessage + ComparisonMsg(FloatToStr(Expected),FloatToStr(Actual)),
|
|
(Abs(Expected - Actual) <= Delta));
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(Expected, Actual, Delta: double);
|
|
begin
|
|
AssertEquals('', Expected, Actual, Delta);
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotNull(const AMessage, AString: string);
|
|
begin
|
|
AssertTrue(AMessage, AString <> '');
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(const AMessage: string; Expected, Actual: boolean);
|
|
begin
|
|
AssertTrue(AMessage + ComparisonMsg(BoolToStr(Expected), BoolToStr(Actual)), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(Expected, Actual: boolean);
|
|
begin
|
|
AssertEquals('', Expected, Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(const AMessage: string; Expected, Actual: char);
|
|
begin
|
|
AssertTrue(AMessage + ComparisonMsg(Expected, Actual), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(Expected, Actual: char);
|
|
begin
|
|
AssertEquals('', Expected, Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(const AMessage: string; Expected, Actual: TClass);
|
|
begin
|
|
AssertTrue(AMessage + ComparisonMsg(Expected.ClassName, Actual.ClassName), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(Expected, Actual: TClass);
|
|
begin
|
|
AssertEquals('', Expected, Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertSame(const AMessage: string; Expected, Actual: TObject);
|
|
begin
|
|
AssertTrue(AMessage + ComparisonMsg(IntToStr(PtrInt(Expected)), IntToStr(PtrInt(Actual))),
|
|
Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertSame(Expected, Actual: TObject);
|
|
begin
|
|
AssertSame('', Expected, Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertSame(const AMessage: string; Expected, Actual: Pointer);
|
|
begin
|
|
AssertTrue(AMessage + ComparisonMsg(IntToStr(PtrInt(Expected)), IntToStr(PtrInt(Actual))),
|
|
Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertSame(Expected, Actual: Pointer);
|
|
begin
|
|
AssertSame('', Expected, Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotSame(const AMessage: string; Expected, Actual: TObject);
|
|
begin
|
|
AssertFalse(SExpectedNotSame, Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotSame(Expected, Actual: TObject);
|
|
begin
|
|
AssertNotSame('', Expected, Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotSame(const AMessage: string; Expected, Actual: Pointer);
|
|
begin
|
|
AssertFalse(SExpectedNotSame, Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotSame(Expected, Actual: Pointer);
|
|
begin
|
|
AssertNotSame('', Expected, Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotNull(const AMessage: string; AObject: TObject);
|
|
begin
|
|
AssertTrue(AMessage, (AObject <> nil));
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotNull(AObject: TObject);
|
|
begin
|
|
AssertNotNull('', AObject);
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotNull(const AMessage: string; APointer: Pointer);
|
|
begin
|
|
AssertTrue(AMessage, (APointer <> nil));
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotNull(APointer: Pointer);
|
|
begin
|
|
AssertNotNull('', APointer);
|
|
end;
|
|
|
|
class procedure TAssert.AssertNull(const AMessage: string; AObject: TObject);
|
|
begin
|
|
AssertTrue(AMessage, (AObject = nil));
|
|
end;
|
|
|
|
class procedure TAssert.AssertNull(AObject: TObject);
|
|
begin
|
|
AssertNull('', AObject);
|
|
end;
|
|
|
|
class procedure TAssert.AssertNull(const AMessage: string; APointer: Pointer);
|
|
begin
|
|
AssertTrue(AMessage, (APointer = nil));
|
|
end;
|
|
|
|
class procedure TAssert.AssertNull(APointer: Pointer);
|
|
begin
|
|
AssertNull('', APointer);
|
|
end;
|
|
|
|
class procedure TAssert.AssertException(const AMessage: string; AExceptionClass: ExceptClass;
|
|
AMethod: TRunMethod);
|
|
var
|
|
Passed : Boolean;
|
|
ExceptionName: string;
|
|
begin
|
|
Passed := False;
|
|
try
|
|
AMethod;
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
ExceptionName := E.ClassName;
|
|
if E.ClassType.InheritsFrom(AExceptionClass) then
|
|
begin
|
|
Passed := AExceptionClass.ClassName = E.ClassName;
|
|
end;
|
|
end;
|
|
end;
|
|
AssertTrue(Format(SExceptionCompare, [AExceptionClass.ClassName, ExceptionName])+ ': ' + AMessage, Passed);
|
|
end;
|
|
|
|
class procedure TAssert.AssertException(AExceptionClass: ExceptClass;
|
|
AMethod: TRunMethod);
|
|
begin
|
|
AssertException('', AExceptionClass, AMethod);
|
|
end;
|
|
|
|
constructor TTestCase.Create;
|
|
begin
|
|
inherited Create;
|
|
end;
|
|
|
|
constructor TTestCase.CreateWithName(const AName: string);
|
|
begin
|
|
Create;
|
|
FName := AName;
|
|
end;
|
|
|
|
constructor TTestCase.CreateWith(const AName: string; const ATestSuiteName: string);
|
|
begin
|
|
Create;
|
|
FName := AName;
|
|
FTestSuiteName := ATestSuiteName;
|
|
end;
|
|
|
|
function TTestCase.AsString: string;
|
|
begin
|
|
Result := TestName + '(' + ClassName + ')';
|
|
end;
|
|
|
|
function TTestCase.CountTestCases: integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
function TTestCase.CreateResult: TTestResult;
|
|
begin
|
|
Result := TTestResult.Create;
|
|
end;
|
|
|
|
|
|
function TTestCase.GetTestName: string;
|
|
begin
|
|
Result := FName;
|
|
end;
|
|
|
|
function TTestCase.GetTestSuiteName: string;
|
|
begin
|
|
Result := FTestSuiteName;
|
|
end;
|
|
|
|
procedure TTestCase.SetTestSuiteName(const aName: string);
|
|
begin
|
|
if FTestSuiteName <> aName then
|
|
FTestSuiteName := aName;
|
|
end;
|
|
|
|
procedure TTestCase.SetTestName(const Value: string);
|
|
begin
|
|
FName := Value;
|
|
end;
|
|
|
|
function TTestCase.CreateResultAndRun: TTestResult;
|
|
begin
|
|
Result := CreateResult;
|
|
Run(Result);
|
|
end;
|
|
|
|
procedure TTestCase.Run(AResult: TTestResult);
|
|
begin
|
|
(AResult).Run(Self);
|
|
end;
|
|
|
|
procedure TTestCase.RunBare;
|
|
begin
|
|
SetUp;
|
|
try
|
|
RunTest;
|
|
finally
|
|
TearDown;
|
|
end;
|
|
end;
|
|
|
|
procedure TTestCase.RunTest;
|
|
var
|
|
m: TMethod;
|
|
RunMethod: TRunMethod;
|
|
pMethod : Pointer;
|
|
begin
|
|
AssertNotNull(FName);
|
|
pMethod := Self.MethodAddress(FName);
|
|
if (Assigned(pMethod)) then
|
|
begin
|
|
m.Code := pMethod;
|
|
m.Data := self;
|
|
RunMethod := TRunMethod(m);
|
|
RunMethod;
|
|
end
|
|
else
|
|
begin
|
|
Fail(format(SMethodNotFound, [FName]));
|
|
end;
|
|
end;
|
|
|
|
procedure TTestCase.SetUp;
|
|
begin
|
|
|
|
end;
|
|
|
|
procedure TTestCase.TearDown;
|
|
begin
|
|
|
|
end;
|
|
|
|
constructor TTestSuite.Create(AClass: TClass; AName: string);
|
|
begin
|
|
Create(AClass);
|
|
FName := AName;
|
|
end;
|
|
|
|
constructor TTestSuite.Create(AClass: TClass);
|
|
var
|
|
ml: TStringList;
|
|
i: integer;
|
|
tc: TTestClass;
|
|
begin
|
|
Create(AClass.ClassName);
|
|
if AClass.InheritsFrom(TTestCase) then
|
|
begin
|
|
tc := TTestClass(AClass);
|
|
ml := TStringList.Create;
|
|
try
|
|
GetMethodList(AClass, ml);
|
|
for i := 0 to ml.Count -1 do
|
|
begin
|
|
AddTest(tc.CreateWith(ml.Strings[i], tc.ClassName));
|
|
end;
|
|
finally
|
|
ml.Free;
|
|
end;
|
|
end
|
|
else
|
|
AddTest(Warning(AClass.ClassName + SNoValidInheritance));
|
|
if FTests.Count = 0 then
|
|
AddTest(Warning(SNoValidTests + AClass.ClassName));
|
|
end;
|
|
|
|
constructor TTestSuite.Create(AClassArray: Array of TClass);
|
|
var
|
|
i: integer;
|
|
begin
|
|
Create;
|
|
for i := Low(AClassArray) to High(AClassArray) do
|
|
if Assigned(AClassArray[i]) then
|
|
AddTest(TTestSuite.Create(AClassArray[i]));
|
|
end;
|
|
|
|
constructor TTestSuite.Create(AName: string);
|
|
begin
|
|
Create();
|
|
FName := AName;
|
|
end;
|
|
|
|
constructor TTestSuite.Create;
|
|
begin
|
|
inherited Create;
|
|
FTests := TList.Create;
|
|
end;
|
|
|
|
destructor TTestSuite.Destroy;
|
|
begin
|
|
FreeObjects(FTests);
|
|
FTests.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TTestSuite.GetTest(Index: integer): TTest;
|
|
begin
|
|
Result := TTest(FTests[Index]);
|
|
end;
|
|
|
|
function TTestSuite.GetTestName: string;
|
|
begin
|
|
Result := FName;
|
|
end;
|
|
|
|
function TTestSuite.GetTestSuiteName: string;
|
|
begin
|
|
Result := FTestSuiteName;
|
|
end;
|
|
|
|
procedure TTestSuite.SetTestName(const Value: string);
|
|
begin
|
|
FName := Value;
|
|
end;
|
|
|
|
procedure TTestSuite.SetTestSuiteName(const aName: string);
|
|
begin
|
|
if FTestSuiteName <> aName then
|
|
FTestSuiteName := aName;
|
|
end;
|
|
|
|
function TTestSuite.CountTestCases: integer;
|
|
var
|
|
i: integer;
|
|
begin
|
|
Result := 0;
|
|
for i := 0 to FTests.Count - 1 do
|
|
begin
|
|
Result := Result + TTest(FTests[i]).CountTestCases;
|
|
end;
|
|
end;
|
|
|
|
procedure TTestSuite.Run(AResult: TTestResult);
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := 0 to FTests.Count - 1 do
|
|
RunTest(TTest(FTests[i]), AResult);
|
|
end;
|
|
|
|
procedure TTestSuite.RunTest(ATest: TTest; AResult: TTestResult);
|
|
begin
|
|
ATest.Run(AResult);
|
|
end;
|
|
|
|
procedure TTestSuite.AddTest(ATest: TTest);
|
|
begin
|
|
FTests.Add(ATest);
|
|
if ATest.TestSuiteName = '' then
|
|
ATest.TestSuiteName := Self.TestName;
|
|
end;
|
|
|
|
procedure TTestSuite.AddTestSuiteFromClass(ATestClass: TClass);
|
|
begin
|
|
AddTest(TTestSuite.Create(ATestClass));
|
|
end;
|
|
|
|
class function TTestSuite.Warning(const aMessage: string): TTestCase;
|
|
var
|
|
w: TTestWarning;
|
|
begin
|
|
w := TTestWarning.Create;
|
|
w.FMessage := aMessage;
|
|
Result := w;
|
|
end;
|
|
|
|
constructor TTestResult.Create;
|
|
begin
|
|
inherited Create;
|
|
FFailures := TList.Create;
|
|
FErrors := TList.Create;
|
|
FListeners := TList.Create;
|
|
end;
|
|
|
|
destructor TTestResult.Destroy;
|
|
begin
|
|
FreeObjects(FFailures);
|
|
FFailures.Free;
|
|
FreeObjects(FErrors);
|
|
FErrors.Free;
|
|
FListeners.Free;
|
|
end;
|
|
|
|
procedure TTestResult.ClearErrorLists;
|
|
begin
|
|
FreeObjects(FFailures);
|
|
FFailures.Clear;
|
|
FreeObjects(FErrors);
|
|
FErrors.Clear;
|
|
end;
|
|
|
|
function TTestResult.GetNumErrors: integer;
|
|
begin
|
|
Result := FErrors.Count;
|
|
end;
|
|
|
|
function TTestResult.GetNumFailures: integer;
|
|
begin
|
|
Result := FFailures.Count;
|
|
end;
|
|
|
|
procedure TTestResult.AddListener(AListener: ITestListener);
|
|
begin
|
|
FListeners.Add(pointer(AListener));
|
|
end;
|
|
|
|
procedure TTestResult.RemoveListener(AListener: ITestListener);
|
|
begin
|
|
FListeners.Remove(pointer(AListener));
|
|
end;
|
|
|
|
procedure TTestResult.AddFailure(ATest: TTest; E: EAssertionFailedError);
|
|
var
|
|
i: integer;
|
|
f: TTestFailure;
|
|
begin
|
|
//lock mutex
|
|
f := TTestFailure.CreateFailure(ATest, E);
|
|
FFailures.Add(f);
|
|
for i := 0 to FListeners.Count - 1 do
|
|
ITestListener(FListeners[i]).AddFailure(ATest, f);
|
|
//unlock mutex
|
|
end;
|
|
|
|
procedure TTestResult.AddError(ATest: TTest; E: Exception;
|
|
AUnitName: string; AMethodName: string; ALineNumber: longint);
|
|
var
|
|
i: integer;
|
|
f: TTestFailure;
|
|
begin
|
|
//lock mutex
|
|
f := TTestFailure.CreateFailure(ATest, E);
|
|
f.SourceUnitName := AUnitName;
|
|
f.MethodName := AMethodName;
|
|
f.LineNumber := ALineNumber;
|
|
FErrors.Add(f);
|
|
for i := 0 to FListeners.Count - 1 do
|
|
ITestListener(FListeners[i]).AddError(ATest, f);
|
|
//unlock mutex
|
|
end;
|
|
|
|
procedure TTestResult.EndTest(ATest: TTest);
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := 0 to FListeners.Count - 1 do
|
|
ITestListener(FListeners[i]).EndTest(ATest);
|
|
end;
|
|
|
|
|
|
procedure TTestResult.Run(ATestCase: TTestCase);
|
|
begin
|
|
StartTest(ATestCase);
|
|
RunProtected(ATestCase);
|
|
EndTest(ATestCase);
|
|
end;
|
|
|
|
procedure TTestResult.RunProtected(ATestCase: TTestCase);
|
|
var
|
|
func, source: shortstring;
|
|
line: longint;
|
|
begin
|
|
func := '';
|
|
source := '';
|
|
line := 0;
|
|
try
|
|
ATestCase.RunBare;
|
|
except
|
|
on E: EAssertionFailedError do AddFailure(ATestCase, E);
|
|
on E: Exception do
|
|
begin
|
|
{$ifdef SHOWLINEINFO}
|
|
GetLineInfo(LongWord(ExceptAddr), func, source, line);
|
|
{$endif}
|
|
AddError(ATestCase, E, source, func, line);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TTestResult.StartTest(ATest: TTest);
|
|
var
|
|
count: integer;
|
|
i: integer;
|
|
begin
|
|
count := ATest.CountTestCases;
|
|
//lock mutex
|
|
FRunTests := FRunTests + count;
|
|
for i := 0 to FListeners.Count - 1 do
|
|
ITestListener(FListeners[i]).StartTest(ATest);
|
|
//unlock mutex
|
|
end;
|
|
|
|
function TTestResult.WasSuccessful: boolean;
|
|
begin
|
|
//lock mutex
|
|
Result := (FErrors.Count = 0) and (FFailures.Count = 0);
|
|
//unlock mutex
|
|
end;
|
|
|
|
end.
|