mirror of
https://gitlab.com/freepascal.org/fpc/pas2js.git
synced 2025-04-07 14:37:47 +02:00
1569 lines
45 KiB
ObjectPascal
1569 lines
45 KiB
ObjectPascal
{
|
|
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.
|
|
Port to Pas2JS by Mattias Gaertner in 2017.
|
|
|
|
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;
|
|
|
|
{$mode objfpc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, JS, TypInfo;
|
|
|
|
type
|
|
EAssertionFailedError = class(Exception);
|
|
EIgnoredTest = class(EAssertionFailedError);
|
|
|
|
TTestStep = (stSetUp, stRunTest, stTearDown, stNothing);
|
|
|
|
TRunMethod = procedure of object;
|
|
|
|
TTestResult = class;
|
|
TTestSuite = class;
|
|
|
|
{ TTest }
|
|
|
|
TTest = class(TObject)
|
|
protected
|
|
FLastStep: TTestStep;
|
|
function GetTestName: string; virtual;
|
|
function GetTestSuiteName: string; virtual;
|
|
function GetEnableIgnores: boolean; virtual;
|
|
procedure SetTestSuiteName(const aName: string); virtual; abstract;
|
|
procedure SetEnableIgnores(Value: boolean); virtual; abstract;
|
|
public
|
|
function CountTestCases: integer; virtual;
|
|
Function GetChildTestCount : Integer; virtual;
|
|
Function GetChildTest(AIndex : Integer) : TTest; virtual;
|
|
function FindChildTest(const AName: String): TTest;
|
|
Function FindTest(Const AName : String) : TTest;
|
|
procedure Run(AResult: TTestResult); virtual;
|
|
procedure Ignore(const AMessage: string);
|
|
published
|
|
property TestName: string read GetTestName;
|
|
property TestSuiteName: string read GetTestSuiteName write SetTestSuiteName;
|
|
property LastStep: TTestStep read FLastStep;
|
|
property EnableIgnores: boolean read GetEnableIgnores write SetEnableIgnores;
|
|
end;
|
|
|
|
{ TAssert }
|
|
|
|
TAssert = class(TTest)
|
|
protected
|
|
Class var AssertCount : Integer;
|
|
public
|
|
class procedure Fail(const AMessage: string);
|
|
class procedure Fail(const AFmt: string; Args : Array of const);
|
|
class procedure FailEquals(const expected, actual: string; const ErrorMsg: string = '');
|
|
class procedure FailNotEquals(const expected, actual: string; const ErrorMsg: 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: NativeInt); overload;
|
|
class procedure AssertEquals(Expected, Actual: NativeInt); 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 AssertNotNullIntf(const AMessage: string; AInterface: IInterface); overload;
|
|
//class procedure AssertNotNullIntf(AInterface: IInterface); 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 AssertNullIntf(const AMessage: string; AInterface: IInterface); overload;
|
|
//class procedure AssertNullIntf(AInterface: IInterface); 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; const AMethod: TRunMethod;
|
|
const AExceptionMessage : String = ''; AExceptionContext : Integer = 0); overload;
|
|
class procedure AssertException(AExceptionClass: ExceptClass;
|
|
const AMethod: TRunMethod; const AExceptionMessage : String = '';
|
|
AExceptionContext : Integer = 0); overload;
|
|
|
|
// DUnit compatible methods
|
|
class procedure Check(pValue: boolean; pMessage: string = '');
|
|
class procedure CheckEquals(expected, actual: double; msg: string = ''); overload;
|
|
class procedure CheckEquals(expected, actual: double; delta: double; msg: string = ''); overload;
|
|
class procedure CheckEquals(expected, actual: string; msg: string = ''); overload;
|
|
class procedure CheckEquals(expected, actual: integer; msg: string = ''); overload;
|
|
class procedure CheckEquals(expected, actual: boolean; msg: string = ''); overload;
|
|
class procedure CheckEquals(expected, actual: TClass; msg: string = ''); overload;
|
|
class procedure CheckNotEquals(expected, actual: string; msg: string = ''); overload;
|
|
class procedure CheckNotEquals(expected, actual: integer; msg: string = ''); overload; virtual;
|
|
class procedure CheckNotEquals(expected, actual: boolean; msg: string = ''); overload; virtual;
|
|
class procedure CheckNotEquals(expected, actual: double; delta: double = 0; msg: string = ''); overload; virtual;
|
|
//class procedure CheckNull(obj: IUnknown; msg: string = ''); overload;
|
|
class procedure CheckNull(obj: TObject; msg: string = ''); overload;
|
|
class procedure CheckNotNull(obj: TObject; msg: string = ''); overload;
|
|
//class procedure CheckNotNull(obj: IUnknown; msg: string = ''); overload; virtual;
|
|
class procedure CheckIs(obj :TObject; pClass: TClass; msg: string = ''); overload;
|
|
class procedure CheckSame(expected, actual: TObject; msg: string = ''); overload;
|
|
class procedure CheckTrue(condition: Boolean; msg: string = '');
|
|
class procedure CheckFalse(condition: Boolean; msg: string = '');
|
|
class procedure CheckException(const AMethod: TRunMethod; AExceptionClass: ExceptClass; msg: string = '');
|
|
class function EqualsErrorMessage(const expected, actual: string; const ErrorMsg: string): string;
|
|
class function NotEqualsErrorMessage(const expected, actual: string; const ErrorMsg: string): string;
|
|
|
|
class function Suite: TTest;
|
|
end;
|
|
|
|
{ TTestFailure }
|
|
|
|
TTestFailure = class(TObject)
|
|
private
|
|
FTestName: string;
|
|
FTestSuiteName: string;
|
|
FLineNumber: longint;
|
|
FFailedMethodName: string;
|
|
FRaisedExceptionClass: TClass;
|
|
FRaisedExceptionMessage: string;
|
|
FSourceUnitName: string;
|
|
//FThrownExceptionAddress: Pointer;
|
|
FTestLastStep: TTestStep;
|
|
function GetAsString: string;
|
|
function GetExceptionMessage: string;
|
|
function GetIsFailure: boolean;
|
|
function GetIsIgnoredTest: boolean;
|
|
function GetExceptionClassName: string;
|
|
//function GetLocationInfo: string;
|
|
procedure SetTestLastStep(const Value: TTestStep);
|
|
public
|
|
constructor CreateFailure(ATest: TTest; E: Exception; LastStep: TTestStep);
|
|
property ExceptionClass: TClass read FRaisedExceptionClass;
|
|
published
|
|
property AsString: string read GetAsString;
|
|
property IsFailure: boolean read GetIsFailure;
|
|
property IsIgnoredTest: boolean read GetIsIgnoredTest;
|
|
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 LocationInfo: string read GetLocationInfo;
|
|
property FailedMethodName: string read FFailedMethodName write FFailedMethodName;
|
|
property TestLastStep: TTestStep read FTestLastStep write SetTestLastStep;
|
|
end;
|
|
|
|
// ToDo convert to ITestListener = interface
|
|
|
|
ITestListener = class
|
|
public
|
|
//['{0CE9D3AE-882A-D811-9401-ADEB5E4C7FC1}']
|
|
procedure AddFailure(ATest: TTest; AFailure: TTestFailure); virtual; abstract;
|
|
procedure AddError(ATest: TTest; AError: TTestFailure); virtual; abstract;
|
|
procedure StartTest(ATest: TTest); virtual; abstract;
|
|
procedure EndTest(ATest: TTest); virtual; abstract;
|
|
procedure StartTestSuite(ATestSuite: TTestSuite); virtual; abstract;
|
|
procedure EndTestSuite(ATestSuite: TTestSuite); virtual; abstract;
|
|
end;
|
|
|
|
{ TTestCase }
|
|
|
|
TTestCase = class(TAssert)
|
|
private
|
|
FName: string;
|
|
FTestSuiteName: string;
|
|
FEnableIgnores: boolean;
|
|
FExpectedExceptionFailMessage : String;
|
|
FExpectedException : TClass;
|
|
FExpectedExceptionMessage: String;
|
|
FExpectedExceptionContext: Integer;
|
|
//FExpectedExceptionCaller : Pointer;
|
|
protected
|
|
function CreateResult: TTestResult; virtual;
|
|
procedure SetUp; virtual;
|
|
procedure TearDown; virtual;
|
|
procedure RunTest; virtual;
|
|
function GetTestName: string; override;
|
|
function GetTestSuiteName: string; override;
|
|
function GetEnableIgnores: boolean; override;
|
|
procedure SetTestSuiteName(const aName: string); override;
|
|
procedure SetTestName(const Value: string); virtual;
|
|
procedure SetEnableIgnores(Value: boolean); override;
|
|
procedure RunBare; virtual;
|
|
Class function SingleInstanceForSuite : Boolean; virtual;
|
|
Public
|
|
Class Var CheckAssertCalled : Boolean;
|
|
public
|
|
constructor Create; virtual; reintroduce;
|
|
constructor CreateWith(const ATestName: string; const ATestSuiteName: string); virtual;
|
|
constructor CreateWithName(const AName: string); virtual;
|
|
procedure ExpectException(AExceptionClass: TClass; AExceptionMessage: string=''; AExceptionHelpContext: Integer=0);
|
|
procedure ExpectException(const Msg: String; AExceptionClass: TClass; AExceptionMessage: string=''; AExceptionHelpContext: Integer=0);
|
|
function CountTestCases: integer; override;
|
|
function CreateResultAndRun: TTestResult; virtual;
|
|
procedure Run(AResult: TTestResult); override;
|
|
function AsString: string;
|
|
property TestSuiteName: string read GetTestSuiteName write SetTestSuiteName;
|
|
Property ExpectedExceptionFailMessage : String Read FExpectedExceptionFailMessage;
|
|
Property ExpectedException : TClass Read FExpectedException;
|
|
Property ExpectedExceptionMessage : String Read FExpectedExceptionMessage;
|
|
Property ExpectedExceptionContext: Integer Read FExpectedExceptionContext;
|
|
published
|
|
property TestName: string read GetTestName write SetTestName;
|
|
end;
|
|
|
|
TTestCaseClass = class of TTestCase;
|
|
|
|
{ TTestSuite }
|
|
|
|
TTestSuite = class(TTest)
|
|
private
|
|
FTests: TFPList;
|
|
FName: string;
|
|
FTestSuiteName: string;
|
|
FEnableIgnores: boolean;
|
|
protected
|
|
procedure ClearTests;
|
|
function DoAddTest(ATest: TTest): Integer;
|
|
function GetTestName: string; override;
|
|
function GetTestSuiteName: string; override;
|
|
function GetEnableIgnores: boolean; override;
|
|
procedure SetTestSuiteName(const aName: string); override;
|
|
procedure SetTestName(const Value: string); virtual;
|
|
procedure SetEnableIgnores(Value: boolean); override;
|
|
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;
|
|
Function GetChildTestCount : Integer; override;
|
|
Function GetChildTest(AIndex : Integer) : TTest; 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 GetChildTest; default;
|
|
Property ChildTestCount : Integer Read GetChildTestCount;
|
|
property TestSuiteName: string read GetTestSuiteName write SetTestSuiteName;
|
|
property TestName: string read GetTestName write SetTestName;
|
|
end;
|
|
|
|
TProtect = procedure(aTest: TTest; aResult: TTestResult);
|
|
|
|
{ TTestResult }
|
|
|
|
TTestResult = class(TObject)
|
|
protected
|
|
FRunTests: integer;
|
|
FFailures: TFPList;
|
|
FIgnoredTests: TFPList;
|
|
FErrors: TFPList;
|
|
FListeners: TFPList; // list of ITestListener
|
|
FSkippedTests: TFPList;
|
|
FStartingTime: TDateTime;
|
|
function GetNumErrors: integer;
|
|
function GetNumFailures: integer;
|
|
function GetNumIgnoredTests: integer;
|
|
function GetNumSkipped: integer;
|
|
public
|
|
constructor Create; virtual; reintroduce;
|
|
destructor Destroy; override;
|
|
procedure ClearErrorLists;
|
|
procedure StartTest(ATest: TTest);
|
|
procedure AddFailure(ATest: TTest; E: EAssertionFailedError; aFailureList: TFPList{; AThrownExceptionAdrs: Pointer});
|
|
procedure AddError(ATest: TTest; E: Exception{; AThrownExceptionAdrs: Pointer});
|
|
procedure EndTest(ATest: TTest);
|
|
procedure AddListener(AListener: ITestListener);
|
|
procedure RemoveListener(AListener: ITestListener);
|
|
procedure Run(ATestCase: TTestCase);
|
|
procedure RunProtected(ATestCase: TTest; protect: TProtect);
|
|
function WasSuccessful: boolean;
|
|
function SkipTest(ATestCase: TTestCase): boolean;
|
|
procedure AddToSkipList(ATestCase: TTestCase);
|
|
procedure RemoveFromSkipList(ATestCase: TTestCase);
|
|
procedure StartTestSuite(ATestSuite: TTestSuite);
|
|
procedure EndTestSuite(ATestSuite: TTestSuite);
|
|
published
|
|
property Listeners: TFPList read FListeners;
|
|
property Failures: TFPList read FFailures;
|
|
property IgnoredTests: TFPList read FIgnoredTests;
|
|
property Errors: TFPList read FErrors;
|
|
property RunTests: integer read FRunTests;
|
|
property NumberOfErrors: integer read GetNumErrors;
|
|
property NumberOfFailures: integer read GetNumFailures;
|
|
property NumberOfIgnoredTests: integer read GetNumIgnoredTests;
|
|
property NumberOfSkippedTests: integer read GetNumSkipped;
|
|
property StartingTime: TDateTime read FStartingTime;
|
|
end;
|
|
|
|
function ComparisonMsg(const aExpected, aActual: string; const aCheckEqual: boolean=true): string; overload;
|
|
function ComparisonMsg(const aMsg, aExpected, aActual: string; const aCheckEqual: boolean=true): string; overload;
|
|
|
|
const
|
|
SCompare: String = ' expected: <%s> but was: <%s>';
|
|
SCompareNotEqual: String = ' expected: not equal to <%s> but was: <%s>';
|
|
SExpectedNotSame: String = 'expected not same';
|
|
SExceptionCompare: String = 'Exception %s expected but %s was raised';
|
|
SExceptionMessageCompare: String = 'Exception raised but exception property Message differs: ';
|
|
SExceptionHelpContextCompare: String = 'Exception raised but exception property HelpContext differs: ';
|
|
SMethodNotFound: String = 'Method <%s> not found';
|
|
SNoValidInheritance: String = ' does not inherit from TTestCase';
|
|
SNoValidTests: String = 'No valid tests found in ';
|
|
SNoException: String = 'no exception';
|
|
SAssertNotCalled: String = 'Assert not called during test.';
|
|
|
|
procedure FreeObjects(List: TFPList);
|
|
procedure GetMethodList(AObject: TObject; AList: TStrings); overload;
|
|
|
|
implementation
|
|
|
|
Const
|
|
sExpectedButWasFmt = 'Expected:' + LineEnding + '"%s"' + LineEnding + 'But was:' + LineEnding + '"%s"';
|
|
sExpectedButWasAndMessageFmt = '%s' + LineEnding + sExpectedButWasFmt;
|
|
|
|
// Get the ClassName of C
|
|
function GetN(C : TClass) : string;
|
|
begin
|
|
if C=Nil then
|
|
Result:='<NIL>'
|
|
else
|
|
Result:=C.ClassName;
|
|
end;
|
|
|
|
// Get the name of o
|
|
function GetN(o : TObject) : string;
|
|
begin
|
|
if o=Nil then
|
|
Result:='<NIL>'
|
|
else begin
|
|
Result:=o.ClassName;
|
|
if o is TComponent then
|
|
Result:=TComponent(o).Name+':'+Result;
|
|
end;
|
|
end;
|
|
|
|
// Get the name of p
|
|
function GetPtrN(p : Pointer) : string;
|
|
begin
|
|
Result:=jsTypeOf(p);
|
|
if isObject(p) then
|
|
begin
|
|
if isClassInstance(p) then
|
|
exit(GetN(TObject(p)));
|
|
if hasString(TJSObject(p)['name']) then
|
|
Result:=String(TJSObject(p)['name'])+':'+Result
|
|
else if hasString(TJSObject(p)['Name']) then
|
|
Result:=String(TJSObject(p)['Name'])+':'+Result
|
|
else if hasString(TJSObject(p)['$name']) then
|
|
Result:=String(TJSObject(p)['$name'])+':'+Result;
|
|
end;
|
|
end;
|
|
|
|
function ComparisonMsg(const aExpected, aActual: string;
|
|
const aCheckEqual: boolean): string;
|
|
// aCheckEqual=false gives the error message if the test does *not* expect
|
|
// the results to be the same.
|
|
begin
|
|
if aCheckEqual then
|
|
Result := format(SCompare, [aExpected, aActual])
|
|
else {check unequal requires opposite error message}
|
|
Result := format(SCompareNotEqual, [aExpected, aActual]);
|
|
end;
|
|
|
|
function ComparisonMsg(const aMsg, aExpected, aActual: string;
|
|
const aCheckEqual: boolean): string;
|
|
begin
|
|
Result := '"' + aMsg + '"' + ComparisonMsg(aExpected, aActual, aCheckEqual);
|
|
end;
|
|
|
|
procedure FreeObjects(List: TFPList);
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i:=0 to List.Count - 1 do
|
|
TObject(List.Items[i]).Destroy;
|
|
List.Clear;
|
|
end;
|
|
|
|
procedure GetMethodList(AObject: TObject; AList: TStrings);
|
|
var
|
|
Methods: TTypeMemberMethodDynArray;
|
|
i: Integer;
|
|
m: TTypeMemberMethod;
|
|
begin
|
|
Methods:=GetClassMethods(TypeInfo(AObject.ClassType));
|
|
for i:=0 to length(Methods)-1 do
|
|
begin
|
|
m:=Methods[i];
|
|
if AList.IndexOf(m.Name)>=0 then continue;
|
|
AList.AddObject(m.Name,TObject(GetInstanceMethod(AObject,m.Name)));
|
|
end;
|
|
end;
|
|
|
|
{ TTestResult }
|
|
|
|
function TTestResult.GetNumErrors: integer;
|
|
begin
|
|
Result := FErrors.Count;
|
|
end;
|
|
|
|
function TTestResult.GetNumFailures: integer;
|
|
begin
|
|
Result := FFailures.Count;
|
|
end;
|
|
|
|
function TTestResult.GetNumIgnoredTests: integer;
|
|
begin
|
|
Result := FIgnoredTests.Count;
|
|
end;
|
|
|
|
function TTestResult.GetNumSkipped: integer;
|
|
begin
|
|
Result := FSkippedTests.Count;
|
|
end;
|
|
|
|
constructor TTestResult.Create;
|
|
begin
|
|
inherited Create;
|
|
FFailures := TFPList.Create;
|
|
FIgnoredTests := TFPList.Create;
|
|
FErrors := TFPList.Create;
|
|
FListeners := TFPList.Create;
|
|
FSkippedTests := TFPList.Create;
|
|
FStartingTime := Now;
|
|
end;
|
|
|
|
destructor TTestResult.Destroy;
|
|
begin
|
|
FreeObjects(FFailures);
|
|
FreeAndNil(FFailures);
|
|
FreeObjects(FIgnoredTests);
|
|
FreeAndNil(FIgnoredTests);
|
|
FreeObjects(FErrors);
|
|
FreeAndNil(FErrors);
|
|
FreeAndNil(FListeners);
|
|
FreeAndNil(FSkippedTests);
|
|
end;
|
|
|
|
procedure TTestResult.ClearErrorLists;
|
|
begin
|
|
FreeObjects(FFailures);
|
|
FFailures.Clear;
|
|
FreeObjects(FIgnoredTests);
|
|
FIgnoredTests.Clear;
|
|
FreeObjects(FErrors);
|
|
FreeAndNil(FErrors);
|
|
end;
|
|
|
|
procedure TTestResult.StartTest(ATest: TTest);
|
|
var
|
|
count, 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;
|
|
|
|
procedure TTestResult.AddFailure(ATest: TTest; E: EAssertionFailedError;
|
|
aFailureList: TFPList);
|
|
var
|
|
f: TTestFailure;
|
|
i: Integer;
|
|
begin
|
|
//lock mutex
|
|
f := TTestFailure.CreateFailure(ATest, E, ATest.LastStep{, AThrownExceptionAdrs});
|
|
aFailureList.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);
|
|
var
|
|
f: TTestFailure;
|
|
i: Integer;
|
|
begin
|
|
//lock mutex
|
|
f := TTestFailure.CreateFailure(ATest, E, ATest.LastStep{, AThrownExceptionAdrs});
|
|
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.AddListener(AListener: ITestListener);
|
|
begin
|
|
FListeners.Add(AListener);
|
|
end;
|
|
|
|
procedure TTestResult.RemoveListener(AListener: ITestListener);
|
|
begin
|
|
FListeners.Remove(AListener);
|
|
end;
|
|
|
|
procedure ProtectTest(aTest: TTest; aResult: TTestResult);
|
|
begin
|
|
if aResult=nil then ;
|
|
TTestCase(aTest).RunBare;
|
|
end;
|
|
|
|
procedure TTestResult.Run(ATestCase: TTestCase);
|
|
begin
|
|
if not SkipTest(ATestCase) then
|
|
begin
|
|
StartTest(ATestCase);
|
|
RunProtected(ATestCase, @ProtectTest);
|
|
EndTest(ATestCase);
|
|
end;
|
|
end;
|
|
|
|
procedure TTestResult.RunProtected(ATestCase: TTest; protect: TProtect);
|
|
begin
|
|
try
|
|
protect(ATestCase, Self);
|
|
except
|
|
on E: EIgnoredTest do
|
|
AddFailure(ATestCase, E, FIgnoredTests{, ExceptAddr});
|
|
on E: EAssertionFailedError do
|
|
AddFailure(ATestCase, E, FFailures{, ExceptAddr});
|
|
on E: Exception do
|
|
begin
|
|
AddError(ATestCase, E{, ExceptAddr});
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TTestResult.WasSuccessful: boolean;
|
|
begin
|
|
//lock mutex
|
|
Result := (FErrors.Count = 0) and (FFailures.Count = 0);
|
|
//unlock mutex
|
|
end;
|
|
|
|
function TTestResult.SkipTest(ATestCase: TTestCase): boolean;
|
|
var
|
|
i: integer;
|
|
begin
|
|
Result := false;
|
|
if FSkippedTests.Count = 0 then
|
|
begin
|
|
result := false;
|
|
Exit;
|
|
end
|
|
else
|
|
for i := 0 to FSkippedTests.Count - 1 do
|
|
begin
|
|
if FSkippedTests[i] = ATestCase then
|
|
begin
|
|
Result := true;
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TTestResult.AddToSkipList(ATestCase: TTestCase);
|
|
begin
|
|
FSkippedTests.Add(ATestCase);
|
|
end;
|
|
|
|
procedure TTestResult.RemoveFromSkipList(ATestCase: TTestCase);
|
|
begin
|
|
FSkippedTests.Remove(ATestCase);
|
|
end;
|
|
|
|
procedure TTestResult.StartTestSuite(ATestSuite: TTestSuite);
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := 0 to FListeners.Count - 1 do
|
|
ITestListener(FListeners[i]).StartTestSuite(ATestSuite);
|
|
end;
|
|
|
|
procedure TTestResult.EndTestSuite(ATestSuite: TTestSuite);
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := 0 to FListeners.Count - 1 do
|
|
ITestListener(FListeners[i]).EndTestSuite(ATestSuite);
|
|
end;
|
|
|
|
type
|
|
{ TTestItem }
|
|
|
|
TTestItem = Class(TObject)
|
|
private
|
|
FName: String;
|
|
FOwnsTest: Boolean;
|
|
FTest: TTest;
|
|
public
|
|
Constructor Create(T : TTest); reintroduce;
|
|
Destructor Destroy; override;
|
|
Property Test : TTest Read FTest;
|
|
Property TestName : String Read FName;
|
|
Property OwnsTest : Boolean Read FOwnsTest Write FOwnstest;
|
|
end;
|
|
|
|
constructor TTestItem.Create(T: TTest);
|
|
begin
|
|
FTest:=T;
|
|
FName:=T.TestName;
|
|
FOwnsTest:=True;
|
|
end;
|
|
|
|
destructor TTestItem.Destroy;
|
|
begin
|
|
if OwnsTest then
|
|
FreeAndNil(FTest);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{ TTestSuite }
|
|
|
|
procedure TTestSuite.ClearTests;
|
|
begin
|
|
FTests.Clear;
|
|
end;
|
|
|
|
function TTestSuite.DoAddTest(ATest: TTest): Integer;
|
|
begin
|
|
Result:=FTests.Add(TTestItem.Create(ATest));
|
|
if ATest.TestSuiteName = '' then
|
|
ATest.TestSuiteName := Self.TestName;
|
|
ATest.EnableIgnores := Self.EnableIgnores;
|
|
end;
|
|
|
|
function TTestSuite.GetTestName: string;
|
|
begin
|
|
Result := FName;
|
|
end;
|
|
|
|
function TTestSuite.GetTestSuiteName: string;
|
|
begin
|
|
Result := FTestSuiteName;
|
|
end;
|
|
|
|
function TTestSuite.GetEnableIgnores: boolean;
|
|
begin
|
|
Result := FEnableIgnores;
|
|
end;
|
|
|
|
procedure TTestSuite.SetTestSuiteName(const aName: string);
|
|
begin
|
|
if FTestSuiteName <> aName then
|
|
FTestSuiteName := aName;
|
|
end;
|
|
|
|
procedure TTestSuite.SetTestName(const Value: string);
|
|
begin
|
|
FName := Value;
|
|
end;
|
|
|
|
procedure TTestSuite.SetEnableIgnores(Value: boolean);
|
|
var
|
|
i: integer;
|
|
begin
|
|
if FEnableIgnores <> Value then
|
|
begin
|
|
FEnableIgnores := Value;
|
|
for i := 0 to FTests.Count - 1 do
|
|
TTestItem(FTests[i]).Test.EnableIgnores := Value;
|
|
end
|
|
end;
|
|
|
|
constructor TTestSuite.Create(AClass: TClass; AName: string);
|
|
begin
|
|
Create(AClass);
|
|
FName := AName;
|
|
end;
|
|
|
|
constructor TTestSuite.Create(AClass: TClass);
|
|
var
|
|
i,j: integer;
|
|
tc: TTestCaseClass;
|
|
C : TTestCase;
|
|
SN : String;
|
|
ml: TTypeMemberMethodDynArray;
|
|
|
|
begin
|
|
TAssert.AssertNotNull(AClass);
|
|
Create(AClass.ClassName);
|
|
if AClass.InheritsFrom(TTestCase) then
|
|
begin
|
|
tc := TTestCaseClass(AClass);
|
|
ml:=GetClassMethods(TypeInfo(AClass));
|
|
SN:=tc.ClassName;
|
|
if tc.SingleInstanceForSuite then
|
|
begin
|
|
c:=tc.CreateWith('',SN);
|
|
for i := 0 to length(ml) -1 do
|
|
begin
|
|
C.TestName:=ml[i].Name;
|
|
J:=DoAddTest(C);
|
|
TTestItem(FTests[J]).OwnsTest:=(I=0);
|
|
end;
|
|
end
|
|
else
|
|
for i := 0 to length(ml) -1 do
|
|
AddTest(tc.CreateWith(ml[i].Name, SN));
|
|
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 := TFPList.Create;
|
|
FEnableIgnores := True;
|
|
end;
|
|
|
|
destructor TTestSuite.Destroy;
|
|
begin
|
|
FreeObjects(FTests);
|
|
FreeAndNil(FTests);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TTestSuite.CountTestCases: integer;
|
|
var
|
|
i: integer;
|
|
begin
|
|
Result := 0;
|
|
for i := 0 to FTests.Count - 1 do
|
|
begin
|
|
Result := Result + TTestItem(FTests[i]).Test.CountTestCases;
|
|
end;
|
|
end;
|
|
|
|
function TTestSuite.GetChildTestCount: Integer;
|
|
begin
|
|
Result:=FTests.Count;
|
|
end;
|
|
|
|
function TTestSuite.GetChildTest(AIndex: Integer): TTest;
|
|
begin
|
|
Result := TTestItem(FTests[AIndex]).Test;
|
|
end;
|
|
|
|
procedure TTestSuite.Run(AResult: TTestResult);
|
|
var
|
|
i: integer;
|
|
ti : TTestItem;
|
|
|
|
begin
|
|
if FTests.Count > 0 then
|
|
AResult.StartTestSuite(self);
|
|
|
|
for i := 0 to FTests.Count - 1 do
|
|
begin
|
|
ti:=TTestItem(FTests[i]);
|
|
if Ti.Test.InheritsFrom(TTestCase) and TTestCase(Ti.Test).SingleInstanceForSuite then
|
|
TTestCase(Ti.Test).SetTestName(Ti.TestName);
|
|
RunTest(TI.Test, AResult);
|
|
end;
|
|
|
|
if FTests.Count > 0 then
|
|
AResult.EndTestSuite(self);
|
|
end;
|
|
|
|
procedure TTestSuite.RunTest(ATest: TTest; AResult: TTestResult);
|
|
begin
|
|
ATest.Run(AResult);
|
|
end;
|
|
|
|
procedure TTestSuite.AddTest(ATest: TTest);
|
|
begin
|
|
DoAddTest(ATest);
|
|
end;
|
|
|
|
procedure TTestSuite.AddTestSuiteFromClass(ATestClass: TClass);
|
|
begin
|
|
AddTest(TTestSuite.Create(ATestClass));
|
|
end;
|
|
|
|
type
|
|
TTestWarning = class(TTestCase)
|
|
private
|
|
FMessage: String;
|
|
protected
|
|
procedure RunTest; override;
|
|
end;
|
|
|
|
procedure TTestWarning.RunTest;
|
|
begin
|
|
Fail(FMessage);
|
|
end;
|
|
|
|
class function TTestSuite.Warning(const aMessage: string): TTestCase;
|
|
var
|
|
w: TTestWarning;
|
|
begin
|
|
w := TTestWarning.Create;
|
|
w.FMessage := aMessage;
|
|
Result := w;
|
|
end;
|
|
|
|
{ TTestCase }
|
|
|
|
function TTestCase.CreateResult: TTestResult;
|
|
begin
|
|
Result := TTestResult.Create;
|
|
end;
|
|
|
|
procedure TTestCase.SetUp;
|
|
begin
|
|
{ do nothing }
|
|
end;
|
|
|
|
procedure TTestCase.TearDown;
|
|
begin
|
|
{ do nothing }
|
|
end;
|
|
|
|
procedure TTestCase.RunTest;
|
|
var
|
|
RunMethod: TRunMethod;
|
|
FailMessage : String;
|
|
begin
|
|
AssertNotNull('name of the test not assigned', FName);
|
|
RunMethod:=TRunMethod(GetInstanceMethod(Self,FName));
|
|
if Assigned(RunMethod) then
|
|
begin
|
|
ExpectException('',Nil,'',0);
|
|
try
|
|
AssertCount:=0;
|
|
FailMessage:='';
|
|
RunMethod;
|
|
if (FExpectedException<>Nil) then
|
|
FailMessage:=Format(SExceptionCompare, [FExpectedException.ClassName, SNoException]);
|
|
if CheckAssertCalled and (AssertCount=0) then
|
|
FailMessage:=SAssertNotCalled;
|
|
except
|
|
On E : Exception do
|
|
begin
|
|
if FExpectedException=Nil then
|
|
Raise;
|
|
If not (E is FExpectedException) then
|
|
FailMessage:=Format(SExceptionCompare, [FExpectedException.ClassName, E.ClassName]);
|
|
if (FExpectedExceptionMessage<>'') then
|
|
if (FExpectedExceptionMessage<>E.Message) then
|
|
FailMessage:=Format(SExceptionmessageCompare+SCompare, [FExpectedExceptionMessage,E.Message]);
|
|
if (FExpectedExceptionContext<>0) then
|
|
if (FExpectedExceptionContext<>E.HelpContext) then
|
|
FailMessage:=Format(SExceptionHelpContextCompare+SCompare, [IntToStr(FExpectedExceptionContext),IntToStr(E.HelpContext)])
|
|
end;
|
|
end;
|
|
if (FailMessage<>'') then
|
|
begin
|
|
if (FExpectedExceptionFailMessage<>'') then
|
|
FailMessage:=' : '+FailMessage;
|
|
Fail(FExpectedExceptionFailMessage+FailMessage{,FExpectedExceptionCaller});
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
Fail(format(SMethodNotFound, [FName]));
|
|
end;
|
|
end;
|
|
|
|
function TTestCase.GetTestName: string;
|
|
begin
|
|
Result := FName;
|
|
end;
|
|
|
|
function TTestCase.GetTestSuiteName: string;
|
|
begin
|
|
Result := FTestSuiteName;
|
|
end;
|
|
|
|
function TTestCase.GetEnableIgnores: boolean;
|
|
begin
|
|
Result := FEnableIgnores;
|
|
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;
|
|
|
|
procedure TTestCase.SetEnableIgnores(Value: boolean);
|
|
begin
|
|
FEnableIgnores := Value;
|
|
end;
|
|
|
|
procedure TTestCase.RunBare;
|
|
begin
|
|
FLastStep := stSetUp;
|
|
SetUp;
|
|
try
|
|
FLastStep := stRunTest;
|
|
RunTest;
|
|
FLastStep := stTearDown;
|
|
finally
|
|
TearDown;
|
|
end;
|
|
FLastStep := stNothing;
|
|
end;
|
|
|
|
class function TTestCase.SingleInstanceForSuite: Boolean;
|
|
begin
|
|
Result:=False;
|
|
end;
|
|
|
|
constructor TTestCase.Create;
|
|
begin
|
|
inherited Create;
|
|
FEnableIgnores := True;
|
|
end;
|
|
|
|
constructor TTestCase.CreateWith(const ATestName: string;
|
|
const ATestSuiteName: string);
|
|
begin
|
|
Create;
|
|
FName := ATestName;
|
|
FTestSuiteName := ATestSuiteName;
|
|
end;
|
|
|
|
constructor TTestCase.CreateWithName(const AName: string);
|
|
begin
|
|
Create;
|
|
FName := AName;
|
|
end;
|
|
|
|
procedure TTestCase.ExpectException(AExceptionClass: TClass;
|
|
AExceptionMessage: string; AExceptionHelpContext: Integer);
|
|
begin
|
|
FExpectedExceptionFailMessage:='';
|
|
FExpectedException:=AExceptionClass;
|
|
FExpectedExceptionMessage:=AExceptionMessage;
|
|
FExpectedExceptionContext:=AExceptionHelpContext;
|
|
//FExpectedExceptionCaller:=CallerAddr;
|
|
end;
|
|
|
|
procedure TTestCase.ExpectException(const Msg: String; AExceptionClass: TClass;
|
|
AExceptionMessage: string; AExceptionHelpContext: Integer);
|
|
begin
|
|
FExpectedExceptionFailMessage:=Msg;
|
|
FExpectedException:=AExceptionClass;
|
|
FExpectedExceptionMessage:=AExceptionMessage;
|
|
FExpectedExceptionContext:=AExceptionHelpContext;
|
|
// FExpectedExceptionCaller:=CallerAddr;
|
|
end;
|
|
|
|
function TTestCase.CountTestCases: integer;
|
|
begin
|
|
Result := 1;
|
|
end;
|
|
|
|
function TTestCase.CreateResultAndRun: TTestResult;
|
|
begin
|
|
Result := CreateResult;
|
|
Run(Result);
|
|
end;
|
|
|
|
procedure TTestCase.Run(AResult: TTestResult);
|
|
begin
|
|
AResult.Run(Self);
|
|
end;
|
|
|
|
function TTestCase.AsString: string;
|
|
begin
|
|
Result := TestName + '(' + ClassName + ')';
|
|
end;
|
|
|
|
{ TTestFailure }
|
|
|
|
function TTestFailure.GetAsString: string;
|
|
var
|
|
s: string;
|
|
begin
|
|
if FTestSuiteName <> '' then
|
|
s := FTestSuiteName + '.'
|
|
else
|
|
s := '';
|
|
Result := s + FTestName + ': ' + FRaisedExceptionMessage;
|
|
end;
|
|
|
|
function TTestFailure.GetExceptionMessage: string;
|
|
begin
|
|
Result := FRaisedExceptionMessage;
|
|
if TestLastStep = stSetUp then
|
|
Result := '[SETUP] ' + Result
|
|
else if TestLastStep = stTearDown then
|
|
Result := '[TEARDOWN] ' + Result;
|
|
end;
|
|
|
|
function TTestFailure.GetIsFailure: boolean;
|
|
begin
|
|
Result := FRaisedExceptionClass.InheritsFrom(EAssertionFailedError);
|
|
end;
|
|
|
|
function TTestFailure.GetIsIgnoredTest: boolean;
|
|
begin
|
|
Result := FRaisedExceptionClass.InheritsFrom(EIgnoredTest);
|
|
end;
|
|
|
|
function TTestFailure.GetExceptionClassName: string;
|
|
begin
|
|
if Assigned(FRaisedExceptionClass) then
|
|
Result := FRaisedExceptionClass.ClassName
|
|
else
|
|
Result := '<NIL>'
|
|
end;
|
|
|
|
procedure TTestFailure.SetTestLastStep(const Value: TTestStep);
|
|
begin
|
|
FTestLastStep := Value;
|
|
end;
|
|
|
|
constructor TTestFailure.CreateFailure(ATest: TTest; E: Exception;
|
|
LastStep: TTestStep);
|
|
begin
|
|
inherited Create;
|
|
FTestName := ATest.GetTestName;
|
|
FTestSuiteName := ATest.GetTestSuiteName;
|
|
FRaisedExceptionClass := E.ClassType;
|
|
FRaisedExceptionMessage := E.Message;
|
|
//FThrownExceptionAddress := ThrownExceptionAddrs;
|
|
FTestLastStep := LastStep;
|
|
end;
|
|
|
|
{ TAssert }
|
|
|
|
class procedure TAssert.Fail(const AMessage: string);
|
|
begin
|
|
Inc(AssertCount);
|
|
raise EAssertionFailedError.Create(AMessage);
|
|
end;
|
|
|
|
class procedure TAssert.Fail(const AFmt: string; Args: array of Const);
|
|
begin
|
|
Inc(AssertCount);
|
|
raise EAssertionFailedError.CreateFmt(AFmt,Args);
|
|
end;
|
|
|
|
class procedure TAssert.FailEquals(const expected, actual: string;
|
|
const ErrorMsg: string);
|
|
begin
|
|
Fail(EqualsErrorMessage(expected, actual, ErrorMsg));
|
|
end;
|
|
|
|
class procedure TAssert.FailNotEquals(const expected, actual: string;
|
|
const ErrorMsg: string);
|
|
begin
|
|
Fail(NotEqualsErrorMessage(expected, actual, ErrorMsg));
|
|
end;
|
|
|
|
class procedure TAssert.AssertTrue(const AMessage: string; ACondition: boolean);
|
|
begin
|
|
if (not ACondition) then
|
|
Fail(AMessage)
|
|
else
|
|
Inc(AssertCount); // Fail will increae AssertCount
|
|
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(ComparisonMsg(AMessage, Expected, Actual), Expected=Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(Expected, Actual: string);
|
|
begin
|
|
AssertTrue(ComparisonMsg(Expected, Actual), Expected=Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(const AMessage: string; Expected,
|
|
Actual: NativeInt);
|
|
begin
|
|
AssertTrue(ComparisonMsg(AMessage,IntToStr(Expected), IntToStr(Actual)), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(Expected, Actual: NativeInt);
|
|
begin
|
|
AssertTrue(ComparisonMsg(IntToStr(Expected), IntToStr(Actual)), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(const AMessage: string; Expected, Actual,
|
|
Delta: double);
|
|
begin
|
|
AssertTrue(ComparisonMsg(AMessage,FloatToStr(Expected),FloatToStr(Actual)),
|
|
(Abs(Expected - Actual) <= Delta));
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(Expected, Actual, Delta: double);
|
|
begin
|
|
AssertTrue(ComparisonMsg(FloatToStr(Expected),FloatToStr(Actual)),
|
|
(Abs(Expected - Actual) <= Delta));
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(const AMessage: string; Expected,
|
|
Actual: boolean);
|
|
begin
|
|
AssertTrue(ComparisonMsg(AMessage,BoolToStr(Expected, true), BoolToStr(Actual, true)),
|
|
Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(Expected, Actual: boolean);
|
|
begin
|
|
AssertTrue(ComparisonMsg(BoolToStr(Expected, true), BoolToStr(Actual, true)),
|
|
Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(const AMessage: string; Expected,
|
|
Actual: char);
|
|
begin
|
|
AssertTrue(ComparisonMsg(AMessage,Expected, Actual), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(Expected, Actual: char);
|
|
begin
|
|
AssertTrue(ComparisonMsg(Expected, Actual), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(const AMessage: string; Expected,
|
|
Actual: TClass);
|
|
begin
|
|
AssertTrue(ComparisonMsg(AMessage,GetN(Expected), GetN(Actual)), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertEquals(Expected, Actual: TClass);
|
|
begin
|
|
AssertTrue(ComparisonMsg(GetN(Expected), GetN(Actual)), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertSame(const AMessage: string; Expected,
|
|
Actual: TObject);
|
|
begin
|
|
AssertTrue(ComparisonMsg(AMessage,GetN(Expected), GetN(Actual)), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertSame(Expected, Actual: TObject);
|
|
begin
|
|
AssertTrue(ComparisonMsg(GetN(Expected), GetN(Actual)), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertSame(const AMessage: string; Expected,
|
|
Actual: Pointer);
|
|
begin
|
|
AssertTrue(ComparisonMsg(AMessage,GetPtrN(Expected), GetPtrN(Actual)), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertSame(Expected, Actual: Pointer);
|
|
begin
|
|
AssertTrue(ComparisonMsg(GetPtrN(Expected), GetPtrN(Actual)), Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotSame(const AMessage: string; Expected,
|
|
Actual: TObject);
|
|
begin
|
|
AssertFalse('"' + aMessage + '"' + SExpectedNotSame, Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotSame(Expected, Actual: TObject);
|
|
begin
|
|
AssertFalse(SExpectedNotSame, Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotSame(const AMessage: string; Expected,
|
|
Actual: Pointer);
|
|
begin
|
|
AssertFalse('"' + aMessage + '"' + SExpectedNotSame, Expected = Actual);
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotSame(Expected, Actual: Pointer);
|
|
begin
|
|
AssertFalse(SExpectedNotSame, 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
|
|
AssertTrue('',(AObject <> nil));
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotNull(const AMessage: string; APointer: Pointer
|
|
);
|
|
begin
|
|
AssertTrue(AMessage, (APointer <> nil));
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotNull(APointer: Pointer);
|
|
begin
|
|
AssertTrue('', (APointer <> nil));
|
|
end;
|
|
|
|
class procedure TAssert.AssertNull(const AMessage: string; AObject: TObject);
|
|
begin
|
|
AssertTrue(AMessage, (AObject = nil));
|
|
end;
|
|
|
|
class procedure TAssert.AssertNull(AObject: TObject);
|
|
begin
|
|
AssertTrue('',(AObject = nil));
|
|
end;
|
|
|
|
class procedure TAssert.AssertNull(const AMessage: string; APointer: Pointer);
|
|
begin
|
|
AssertTrue(AMessage, (APointer = nil));
|
|
end;
|
|
|
|
class procedure TAssert.AssertNull(APointer: Pointer);
|
|
begin
|
|
AssertTrue('', (APointer = nil));
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotNull(const AMessage, AString: string);
|
|
begin
|
|
AssertTrue(AMessage, AString <> '');
|
|
end;
|
|
|
|
class procedure TAssert.AssertNotNull(const AString: string);
|
|
begin
|
|
AssertNotNull('', AString);
|
|
end;
|
|
|
|
class procedure TAssert.AssertException(const AMessage: string;
|
|
AExceptionClass: ExceptClass; const AMethod: TRunMethod;
|
|
const AExceptionMessage: String; AExceptionContext: Integer);
|
|
|
|
Function MisMatch (AClassName : String) : String;
|
|
|
|
begin
|
|
Result:=Format(SExceptionCompare,[AExceptionClass.ClassName, AClassName])
|
|
end;
|
|
|
|
var
|
|
FailMsg : string;
|
|
begin
|
|
FailMsg:='';
|
|
try
|
|
AMethod;
|
|
FailMsg:=MisMatch(SNoException);
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
if Not E.ClassType.InheritsFrom(AExceptionClass) then
|
|
FailMsg:=MisMatch(E.ClassName)
|
|
else if not (AExceptionClass.ClassName = E.ClassName) then
|
|
FailMsg:=MisMatch(E.ClassName)
|
|
else if (AExceptionMessage<>'') and (AExceptionMessage<>E.Message) then
|
|
FailMsg:=ComparisonMsg(SExceptionMessageCompare,AExceptionMessage,E.Message)
|
|
else if (AExceptionContext<>0) and (AExceptionContext<>E.HelpContext) then
|
|
FailMsg:=ComparisonMsg(SExceptionHelpContextCompare,IntToStr(AExceptionContext),IntToStr(E.HelpContext))
|
|
end;
|
|
end;
|
|
AssertTrue(AMessage + FailMsg, FailMsg='');
|
|
end;
|
|
|
|
class procedure TAssert.AssertException(AExceptionClass: ExceptClass;
|
|
const AMethod: TRunMethod; const AExceptionMessage: String;
|
|
AExceptionContext: Integer);
|
|
begin
|
|
AssertException('', AExceptionClass, AMethod, AExceptionMessage, AExceptionContext);
|
|
end;
|
|
|
|
class procedure TAssert.Check(pValue: boolean; pMessage: string);
|
|
begin
|
|
AssertTrue(pMessage, pValue);
|
|
end;
|
|
|
|
class procedure TAssert.CheckEquals(expected, actual: double; msg: string);
|
|
begin
|
|
CheckEquals(expected, actual, 0, msg);
|
|
end;
|
|
|
|
class procedure TAssert.CheckEquals(expected, actual: double; delta: double;
|
|
msg: string);
|
|
begin
|
|
AssertEquals(msg, expected, actual, delta);
|
|
end;
|
|
|
|
class procedure TAssert.CheckEquals(expected, actual: string; msg: string);
|
|
begin
|
|
AssertEquals(msg, expected, actual);
|
|
end;
|
|
|
|
class procedure TAssert.CheckEquals(expected, actual: integer; msg: string);
|
|
begin
|
|
AssertEquals(msg, expected, actual);
|
|
end;
|
|
|
|
class procedure TAssert.CheckEquals(expected, actual: boolean; msg: string);
|
|
begin
|
|
AssertEquals(msg, expected, actual);
|
|
end;
|
|
|
|
class procedure TAssert.CheckEquals(expected, actual: TClass; msg: string);
|
|
begin
|
|
AssertEquals(msg, expected, actual);
|
|
end;
|
|
|
|
class procedure TAssert.CheckNotEquals(expected, actual: string; msg: string);
|
|
begin
|
|
if Expected=Actual then
|
|
Fail(msg + ComparisonMsg(Expected, Actual, false));
|
|
end;
|
|
|
|
class procedure TAssert.CheckNotEquals(expected, actual: integer; msg: string);
|
|
begin
|
|
if (expected = actual) then
|
|
Fail(msg + ComparisonMsg(IntToStr(expected), IntToStr(actual), false));
|
|
end;
|
|
|
|
class procedure TAssert.CheckNotEquals(expected, actual: boolean; msg: string);
|
|
begin
|
|
if (expected = actual) then
|
|
Fail(msg + ComparisonMsg(BoolToStr(expected), BoolToStr(actual), false));
|
|
end;
|
|
|
|
class procedure TAssert.CheckNotEquals(expected, actual: double; delta: double;
|
|
msg: string);
|
|
begin
|
|
if (abs(expected-actual) <= delta) then
|
|
FailNotEquals(FloatToStr(expected), FloatToStr(actual), msg);
|
|
end;
|
|
|
|
class procedure TAssert.CheckNull(obj: TObject; msg: string);
|
|
begin
|
|
AssertNull(msg, obj);
|
|
end;
|
|
|
|
class procedure TAssert.CheckNotNull(obj: TObject; msg: string);
|
|
begin
|
|
AssertNotNull(msg, obj);
|
|
end;
|
|
|
|
class procedure TAssert.CheckIs(obj: TObject; pClass: TClass; msg: string);
|
|
begin
|
|
if pClass=nil then
|
|
Fail('TAssert.CheckIs pClass=nil');
|
|
if obj = nil then
|
|
Fail(ComparisonMsg(msg,pClass.ClassName, 'nil'))
|
|
else if not obj.ClassType.InheritsFrom(pClass) then
|
|
Fail(ComparisonMsg(msg,pClass.ClassName, obj.ClassName));
|
|
end;
|
|
|
|
class procedure TAssert.CheckSame(expected, actual: TObject; msg: string);
|
|
begin
|
|
AssertSame(msg, expected, actual);
|
|
end;
|
|
|
|
class procedure TAssert.CheckTrue(condition: Boolean; msg: string);
|
|
begin
|
|
if (not condition) then
|
|
FailNotEquals(BoolToStr(true, true), BoolToStr(false, true), msg);
|
|
end;
|
|
|
|
class procedure TAssert.CheckFalse(condition: Boolean; msg: string);
|
|
begin
|
|
if (condition) then
|
|
FailNotEquals(BoolToStr(false, true), BoolToStr(true, true), msg);
|
|
end;
|
|
|
|
class procedure TAssert.CheckException(const AMethod: TRunMethod;
|
|
AExceptionClass: ExceptClass; msg: string);
|
|
begin
|
|
AssertException(msg, AExceptionClass, AMethod);
|
|
end;
|
|
|
|
class function TAssert.EqualsErrorMessage(const expected, actual: string;
|
|
const ErrorMsg: string): string;
|
|
begin
|
|
if (ErrorMsg <> '') then
|
|
Result := Format(sExpectedButWasAndMessageFmt, [ErrorMsg + ', ', expected, actual])
|
|
else
|
|
Result := Format(sExpectedButWasFmt, [expected, actual])
|
|
end;
|
|
|
|
class function TAssert.NotEqualsErrorMessage(const expected, actual: string;
|
|
const ErrorMsg: string): string;
|
|
begin
|
|
if (ErrorMsg <> '') then
|
|
Result := Format(sExpectedButWasAndMessageFmt, [ErrorMsg, expected, actual])
|
|
else
|
|
Result := Format(sExpectedButWasFmt, [expected, actual]);
|
|
end;
|
|
|
|
class function TAssert.Suite: TTest;
|
|
begin
|
|
Result := TTestSuite.Create(Self);
|
|
end;
|
|
|
|
{ TTest }
|
|
|
|
function TTest.GetTestName: string;
|
|
begin
|
|
Result := 'TTest';
|
|
end;
|
|
|
|
function TTest.GetTestSuiteName: string;
|
|
begin
|
|
Result := 'TTest';
|
|
end;
|
|
|
|
function TTest.GetEnableIgnores: boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
function TTest.CountTestCases: integer;
|
|
begin
|
|
Result := 0;
|
|
end;
|
|
|
|
function TTest.GetChildTestCount: Integer;
|
|
begin
|
|
Result:=0;
|
|
end;
|
|
|
|
function TTest.GetChildTest(AIndex: Integer): TTest;
|
|
begin
|
|
Result:=Nil;
|
|
if AIndex=0 then ;
|
|
end;
|
|
|
|
function TTest.FindChildTest(const AName: String): TTest;
|
|
Var
|
|
I : Integer;
|
|
|
|
begin
|
|
Result:=Nil;
|
|
I:=GetChildTestCount-1;
|
|
While (Result=Nil) and (I>=0) do
|
|
begin
|
|
Result:=GetChildTest(I);
|
|
if CompareText(Result.TestName,AName)<>0 then
|
|
Result:=Nil;
|
|
Dec(I);
|
|
end;
|
|
end;
|
|
|
|
function TTest.FindTest(const AName: String): TTest;
|
|
Var
|
|
S : String;
|
|
I,P : Integer;
|
|
|
|
begin
|
|
Result:=Nil;
|
|
S:=AName;
|
|
if S='' then exit;
|
|
P:=Pos('.',S);
|
|
If (P=0) then
|
|
P:=Length(S)+1;
|
|
Result:=FindChildTest(Copy(S,1,P-1));
|
|
if (Result<>Nil) then
|
|
begin
|
|
Delete(S,1,P);
|
|
If (S<>'') then
|
|
Result:=Result.FindTest(S);
|
|
end
|
|
else
|
|
begin
|
|
P:=GetChildTestCount;
|
|
I:=0;
|
|
While (Result=Nil) and (I<P) do
|
|
begin
|
|
Result:=GetChildTest(I).FindTest(Aname);
|
|
Inc(I);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TTest.Run(AResult: TTestResult);
|
|
begin
|
|
{ do nothing }
|
|
if AResult=nil then ;
|
|
end;
|
|
|
|
procedure TTest.Ignore(const AMessage: string);
|
|
begin
|
|
if EnableIgnores then raise EIgnoredTest.Create(AMessage);
|
|
end;
|
|
|
|
end.
|
|
|