fpcunit.pas 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 2004 by Dean Zobec, Michael Van Canneyt
  4. Port to Free Pascal of the JUnit framework.
  5. Port to Pas2JS by Mattias Gaertner in 2017.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit FPCUnit;
  13. {$mode objfpc}
  14. interface
  15. uses
  16. Classes, SysUtils, JS, TypInfo;
  17. type
  18. EAssertionFailedError = class(Exception);
  19. EIgnoredTest = class(EAssertionFailedError);
  20. TTestStep = (stSetUp, stRunTest, stTearDown, stNothing);
  21. TRunMethod = procedure of object;
  22. TTestResult = class;
  23. TTestSuite = class;
  24. { TTest }
  25. TTest = class(TObject)
  26. protected
  27. FLastStep: TTestStep;
  28. function GetTestName: string; virtual;
  29. function GetTestSuiteName: string; virtual;
  30. function GetEnableIgnores: boolean; virtual;
  31. procedure SetTestSuiteName(const aName: string); virtual; abstract;
  32. procedure SetEnableIgnores(Value: boolean); virtual; abstract;
  33. public
  34. function CountTestCases: integer; virtual;
  35. Function GetChildTestCount : Integer; virtual;
  36. Function GetChildTest(AIndex : Integer) : TTest; virtual;
  37. function FindChildTest(const AName: String): TTest;
  38. Function FindTest(Const AName : String) : TTest;
  39. procedure Run(AResult: TTestResult); virtual;
  40. procedure Ignore(const AMessage: string);
  41. published
  42. property TestName: string read GetTestName;
  43. property TestSuiteName: string read GetTestSuiteName write SetTestSuiteName;
  44. property LastStep: TTestStep read FLastStep;
  45. property EnableIgnores: boolean read GetEnableIgnores write SetEnableIgnores;
  46. end;
  47. { TAssert }
  48. TAssert = class(TTest)
  49. protected
  50. Class var AssertCount : Integer;
  51. public
  52. class procedure Fail(const AMessage: string);
  53. class procedure Fail(const AFmt: string; Args : Array of const);
  54. class procedure FailEquals(const expected, actual: string; const ErrorMsg: string = '');
  55. class procedure FailNotEquals(const expected, actual: string; const ErrorMsg: string = '');
  56. class procedure AssertTrue(const AMessage: string; ACondition: boolean); overload;
  57. class procedure AssertTrue(ACondition: boolean); overload;
  58. class procedure AssertFalse(const AMessage: string; ACondition: boolean); overload;
  59. class procedure AssertFalse(ACondition: boolean); overload;
  60. class procedure AssertEquals(const AMessage: string; Expected, Actual: string); overload;
  61. class procedure AssertEquals(Expected, Actual: string); overload;
  62. class procedure AssertEquals(const AMessage: string; Expected, Actual: NativeInt); overload;
  63. class procedure AssertEquals(Expected, Actual: NativeInt); overload;
  64. class procedure AssertEquals(const AMessage: string; Expected, Actual, Delta: double); overload;
  65. class procedure AssertEquals(Expected, Actual, Delta: double); overload;
  66. class procedure AssertEquals(const AMessage: string; Expected, Actual: boolean); overload;
  67. class procedure AssertEquals(Expected, Actual: boolean); overload;
  68. class procedure AssertEquals(const AMessage: string; Expected, Actual: char); overload;
  69. class procedure AssertEquals(Expected, Actual: char); overload;
  70. class procedure AssertEquals(const AMessage: string; Expected, Actual: TClass); overload;
  71. class procedure AssertEquals(Expected, Actual: TClass); overload;
  72. class procedure AssertSame(const AMessage: string; Expected, Actual: TObject); overload;
  73. class procedure AssertSame(Expected, Actual: TObject); overload;
  74. class procedure AssertSame(const AMessage: string; Expected, Actual: Pointer); overload;
  75. class procedure AssertSame(Expected, Actual: Pointer); overload;
  76. class procedure AssertNotSame(const AMessage: string; Expected, Actual: TObject); overload;
  77. class procedure AssertNotSame(Expected, Actual: TObject); overload;
  78. class procedure AssertNotSame(const AMessage: string; Expected, Actual: Pointer); overload;
  79. class procedure AssertNotSame(Expected, Actual: Pointer); overload;
  80. class procedure AssertNotNull(const AMessage: string; AObject: TObject); overload;
  81. class procedure AssertNotNull(AObject: TObject); overload;
  82. //class procedure AssertNotNullIntf(const AMessage: string; AInterface: IInterface); overload;
  83. //class procedure AssertNotNullIntf(AInterface: IInterface); overload;
  84. class procedure AssertNotNull(const AMessage: string; APointer: Pointer); overload;
  85. class procedure AssertNotNull(APointer: Pointer); overload;
  86. class procedure AssertNull(const AMessage: string; AObject: TObject); overload;
  87. class procedure AssertNull(AObject: TObject); overload;
  88. //class procedure AssertNullIntf(const AMessage: string; AInterface: IInterface); overload;
  89. //class procedure AssertNullIntf(AInterface: IInterface); overload;
  90. class procedure AssertNull(const AMessage: string; APointer: Pointer); overload;
  91. class procedure AssertNull(APointer: Pointer); overload;
  92. class procedure AssertNotNull(const AMessage, AString: string); overload;
  93. class procedure AssertNotNull(const AString: string); overload;
  94. class procedure AssertException(const AMessage: string;
  95. AExceptionClass: ExceptClass; const AMethod: TRunMethod;
  96. const AExceptionMessage : String = ''; AExceptionContext : Integer = 0); overload;
  97. class procedure AssertException(AExceptionClass: ExceptClass;
  98. const AMethod: TRunMethod; const AExceptionMessage : String = '';
  99. AExceptionContext : Integer = 0); overload;
  100. // DUnit compatible methods
  101. class procedure Check(pValue: boolean; pMessage: string = '');
  102. class procedure CheckEquals(expected, actual: double; msg: string = ''); overload;
  103. class procedure CheckEquals(expected, actual: double; delta: double; msg: string = ''); overload;
  104. class procedure CheckEquals(expected, actual: string; msg: string = ''); overload;
  105. class procedure CheckEquals(expected, actual: integer; msg: string = ''); overload;
  106. class procedure CheckEquals(expected, actual: boolean; msg: string = ''); overload;
  107. class procedure CheckEquals(expected, actual: TClass; msg: string = ''); overload;
  108. class procedure CheckNotEquals(expected, actual: string; msg: string = ''); overload;
  109. class procedure CheckNotEquals(expected, actual: integer; msg: string = ''); overload; virtual;
  110. class procedure CheckNotEquals(expected, actual: boolean; msg: string = ''); overload; virtual;
  111. class procedure CheckNotEquals(expected, actual: double; delta: double = 0; msg: string = ''); overload; virtual;
  112. //class procedure CheckNull(obj: IUnknown; msg: string = ''); overload;
  113. class procedure CheckNull(obj: TObject; msg: string = ''); overload;
  114. class procedure CheckNotNull(obj: TObject; msg: string = ''); overload;
  115. //class procedure CheckNotNull(obj: IUnknown; msg: string = ''); overload; virtual;
  116. class procedure CheckIs(obj :TObject; pClass: TClass; msg: string = ''); overload;
  117. class procedure CheckSame(expected, actual: TObject; msg: string = ''); overload;
  118. class procedure CheckTrue(condition: Boolean; msg: string = '');
  119. class procedure CheckFalse(condition: Boolean; msg: string = '');
  120. class procedure CheckException(const AMethod: TRunMethod; AExceptionClass: ExceptClass; msg: string = '');
  121. class function EqualsErrorMessage(const expected, actual: string; const ErrorMsg: string): string;
  122. class function NotEqualsErrorMessage(const expected, actual: string; const ErrorMsg: string): string;
  123. class function Suite: TTest;
  124. end;
  125. { TTestFailure }
  126. TTestFailure = class(TObject)
  127. private
  128. FTestName: string;
  129. FTestSuiteName: string;
  130. FLineNumber: longint;
  131. FFailedMethodName: string;
  132. FRaisedExceptionClass: TClass;
  133. FRaisedExceptionMessage: string;
  134. FSourceUnitName: string;
  135. //FThrownExceptionAddress: Pointer;
  136. FTestLastStep: TTestStep;
  137. function GetAsString: string;
  138. function GetExceptionMessage: string;
  139. function GetIsFailure: boolean;
  140. function GetIsIgnoredTest: boolean;
  141. function GetExceptionClassName: string;
  142. //function GetLocationInfo: string;
  143. procedure SetTestLastStep(const Value: TTestStep);
  144. public
  145. constructor CreateFailure(ATest: TTest; E: Exception; LastStep: TTestStep);
  146. property ExceptionClass: TClass read FRaisedExceptionClass;
  147. published
  148. property AsString: string read GetAsString;
  149. property IsFailure: boolean read GetIsFailure;
  150. property IsIgnoredTest: boolean read GetIsIgnoredTest;
  151. property ExceptionMessage: string read GetExceptionMessage;
  152. property ExceptionClassName: string read GetExceptionClassName;
  153. property SourceUnitName: string read FSourceUnitName write FSourceUnitName;
  154. property LineNumber: longint read FLineNumber write FLineNumber;
  155. //property LocationInfo: string read GetLocationInfo;
  156. property FailedMethodName: string read FFailedMethodName write FFailedMethodName;
  157. property TestLastStep: TTestStep read FTestLastStep write SetTestLastStep;
  158. end;
  159. // ToDo convert to ITestListener = interface
  160. ITestListener = class
  161. public
  162. //['{0CE9D3AE-882A-D811-9401-ADEB5E4C7FC1}']
  163. procedure AddFailure(ATest: TTest; AFailure: TTestFailure); virtual; abstract;
  164. procedure AddError(ATest: TTest; AError: TTestFailure); virtual; abstract;
  165. procedure StartTest(ATest: TTest); virtual; abstract;
  166. procedure EndTest(ATest: TTest); virtual; abstract;
  167. procedure StartTestSuite(ATestSuite: TTestSuite); virtual; abstract;
  168. procedure EndTestSuite(ATestSuite: TTestSuite); virtual; abstract;
  169. end;
  170. { TTestCase }
  171. TTestCase = class(TAssert)
  172. private
  173. FName: string;
  174. FTestSuiteName: string;
  175. FEnableIgnores: boolean;
  176. FExpectedExceptionFailMessage : String;
  177. FExpectedException : TClass;
  178. FExpectedExceptionMessage: String;
  179. FExpectedExceptionContext: Integer;
  180. //FExpectedExceptionCaller : Pointer;
  181. protected
  182. function CreateResult: TTestResult; virtual;
  183. procedure SetUp; virtual;
  184. procedure TearDown; virtual;
  185. procedure RunTest; virtual;
  186. function GetTestName: string; override;
  187. function GetTestSuiteName: string; override;
  188. function GetEnableIgnores: boolean; override;
  189. procedure SetTestSuiteName(const aName: string); override;
  190. procedure SetTestName(const Value: string); virtual;
  191. procedure SetEnableIgnores(Value: boolean); override;
  192. procedure RunBare; virtual;
  193. Class function SingleInstanceForSuite : Boolean; virtual;
  194. Public
  195. Class Var CheckAssertCalled : Boolean;
  196. public
  197. constructor Create; virtual; reintroduce;
  198. constructor CreateWith(const ATestName: string; const ATestSuiteName: string); virtual;
  199. constructor CreateWithName(const AName: string); virtual;
  200. procedure ExpectException(AExceptionClass: TClass; AExceptionMessage: string=''; AExceptionHelpContext: Integer=0);
  201. procedure ExpectException(const Msg: String; AExceptionClass: TClass; AExceptionMessage: string=''; AExceptionHelpContext: Integer=0);
  202. function CountTestCases: integer; override;
  203. function CreateResultAndRun: TTestResult; virtual;
  204. procedure Run(AResult: TTestResult); override;
  205. function AsString: string;
  206. property TestSuiteName: string read GetTestSuiteName write SetTestSuiteName;
  207. Property ExpectedExceptionFailMessage : String Read FExpectedExceptionFailMessage;
  208. Property ExpectedException : TClass Read FExpectedException;
  209. Property ExpectedExceptionMessage : String Read FExpectedExceptionMessage;
  210. Property ExpectedExceptionContext: Integer Read FExpectedExceptionContext;
  211. published
  212. property TestName: string read GetTestName write SetTestName;
  213. end;
  214. TTestCaseClass = class of TTestCase;
  215. { TTestSuite }
  216. TTestSuite = class(TTest)
  217. private
  218. FTests: TFPList;
  219. FName: string;
  220. FTestSuiteName: string;
  221. FEnableIgnores: boolean;
  222. protected
  223. procedure ClearTests;
  224. function DoAddTest(ATest: TTest): Integer;
  225. function GetTestName: string; override;
  226. function GetTestSuiteName: string; override;
  227. function GetEnableIgnores: boolean; override;
  228. procedure SetTestSuiteName(const aName: string); override;
  229. procedure SetTestName(const Value: string); virtual;
  230. procedure SetEnableIgnores(Value: boolean); override;
  231. public
  232. constructor Create(AClass: TClass; AName: string); reintroduce; overload; virtual;
  233. constructor Create(AClass: TClass); reintroduce; overload; virtual;
  234. constructor Create(AClassArray: Array of TClass); reintroduce; overload; virtual;
  235. constructor Create(AName: string); reintroduce; overload; virtual;
  236. constructor Create; reintroduce; overload; virtual;
  237. destructor Destroy; override;
  238. function CountTestCases: integer; override;
  239. Function GetChildTestCount : Integer; override;
  240. Function GetChildTest(AIndex : Integer) : TTest; override;
  241. procedure Run(AResult: TTestResult); override;
  242. procedure RunTest(ATest: TTest; AResult: TTestResult); virtual;
  243. procedure AddTest(ATest: TTest); overload; virtual;
  244. procedure AddTestSuiteFromClass(ATestClass: TClass); virtual;
  245. class function Warning(const aMessage: string): TTestCase;
  246. property Test[Index: integer]: TTest read GetChildTest; default;
  247. Property ChildTestCount : Integer Read GetChildTestCount;
  248. property TestSuiteName: string read GetTestSuiteName write SetTestSuiteName;
  249. property TestName: string read GetTestName write SetTestName;
  250. end;
  251. TProtect = procedure(aTest: TTest; aResult: TTestResult);
  252. { TTestResult }
  253. TTestResult = class(TObject)
  254. protected
  255. FRunTests: integer;
  256. FFailures: TFPList;
  257. FIgnoredTests: TFPList;
  258. FErrors: TFPList;
  259. FListeners: TFPList; // list of ITestListener
  260. FSkippedTests: TFPList;
  261. FStartingTime: TDateTime;
  262. function GetNumErrors: integer;
  263. function GetNumFailures: integer;
  264. function GetNumIgnoredTests: integer;
  265. function GetNumSkipped: integer;
  266. public
  267. constructor Create; virtual; reintroduce;
  268. destructor Destroy; override;
  269. procedure ClearErrorLists;
  270. procedure StartTest(ATest: TTest);
  271. procedure AddFailure(ATest: TTest; E: EAssertionFailedError; aFailureList: TFPList{; AThrownExceptionAdrs: Pointer});
  272. procedure AddError(ATest: TTest; E: Exception{; AThrownExceptionAdrs: Pointer});
  273. procedure EndTest(ATest: TTest);
  274. procedure AddListener(AListener: ITestListener);
  275. procedure RemoveListener(AListener: ITestListener);
  276. procedure Run(ATestCase: TTestCase);
  277. procedure RunProtected(ATestCase: TTest; protect: TProtect);
  278. function WasSuccessful: boolean;
  279. function SkipTest(ATestCase: TTestCase): boolean;
  280. procedure AddToSkipList(ATestCase: TTestCase);
  281. procedure RemoveFromSkipList(ATestCase: TTestCase);
  282. procedure StartTestSuite(ATestSuite: TTestSuite);
  283. procedure EndTestSuite(ATestSuite: TTestSuite);
  284. published
  285. property Listeners: TFPList read FListeners;
  286. property Failures: TFPList read FFailures;
  287. property IgnoredTests: TFPList read FIgnoredTests;
  288. property Errors: TFPList read FErrors;
  289. property RunTests: integer read FRunTests;
  290. property NumberOfErrors: integer read GetNumErrors;
  291. property NumberOfFailures: integer read GetNumFailures;
  292. property NumberOfIgnoredTests: integer read GetNumIgnoredTests;
  293. property NumberOfSkippedTests: integer read GetNumSkipped;
  294. property StartingTime: TDateTime read FStartingTime;
  295. end;
  296. function ComparisonMsg(const aExpected, aActual: string; const aCheckEqual: boolean=true): string; overload;
  297. function ComparisonMsg(const aMsg, aExpected, aActual: string; const aCheckEqual: boolean=true): string; overload;
  298. const
  299. SCompare: String = ' expected: <%s> but was: <%s>';
  300. SCompareNotEqual: String = ' expected: not equal to <%s> but was: <%s>';
  301. SExpectedNotSame: String = 'expected not same';
  302. SExceptionCompare: String = 'Exception %s expected but %s was raised';
  303. SExceptionMessageCompare: String = 'Exception raised but exception property Message differs: ';
  304. SExceptionHelpContextCompare: String = 'Exception raised but exception property HelpContext differs: ';
  305. SMethodNotFound: String = 'Method <%s> not found';
  306. SNoValidInheritance: String = ' does not inherit from TTestCase';
  307. SNoValidTests: String = 'No valid tests found in ';
  308. SNoException: String = 'no exception';
  309. SAssertNotCalled: String = 'Assert not called during test.';
  310. procedure FreeObjects(List: TFPList);
  311. procedure GetMethodList(AObject: TObject; AList: TStrings); overload;
  312. implementation
  313. Const
  314. sExpectedButWasFmt = 'Expected:' + LineEnding + '"%s"' + LineEnding + 'But was:' + LineEnding + '"%s"';
  315. sExpectedButWasAndMessageFmt = '%s' + LineEnding + sExpectedButWasFmt;
  316. // Get the ClassName of C
  317. function GetN(C : TClass) : string;
  318. begin
  319. if C=Nil then
  320. Result:='<NIL>'
  321. else
  322. Result:=C.ClassName;
  323. end;
  324. // Get the name of o
  325. function GetN(o : TObject) : string;
  326. begin
  327. if o=Nil then
  328. Result:='<NIL>'
  329. else begin
  330. Result:=o.ClassName;
  331. if o is TComponent then
  332. Result:=TComponent(o).Name+':'+Result;
  333. end;
  334. end;
  335. // Get the name of p
  336. function GetPtrN(p : Pointer) : string;
  337. begin
  338. Result:=jsTypeOf(p);
  339. if isObject(p) then
  340. begin
  341. if isClassInstance(p) then
  342. exit(GetN(TObject(p)));
  343. if hasString(TJSObject(p)['name']) then
  344. Result:=String(TJSObject(p)['name'])+':'+Result
  345. else if hasString(TJSObject(p)['Name']) then
  346. Result:=String(TJSObject(p)['Name'])+':'+Result
  347. else if hasString(TJSObject(p)['$name']) then
  348. Result:=String(TJSObject(p)['$name'])+':'+Result;
  349. end;
  350. end;
  351. function ComparisonMsg(const aExpected, aActual: string;
  352. const aCheckEqual: boolean): string;
  353. // aCheckEqual=false gives the error message if the test does *not* expect
  354. // the results to be the same.
  355. begin
  356. if aCheckEqual then
  357. Result := format(SCompare, [aExpected, aActual])
  358. else {check unequal requires opposite error message}
  359. Result := format(SCompareNotEqual, [aExpected, aActual]);
  360. end;
  361. function ComparisonMsg(const aMsg, aExpected, aActual: string;
  362. const aCheckEqual: boolean): string;
  363. begin
  364. Result := '"' + aMsg + '"' + ComparisonMsg(aExpected, aActual, aCheckEqual);
  365. end;
  366. procedure FreeObjects(List: TFPList);
  367. var
  368. i: integer;
  369. begin
  370. for i:=0 to List.Count - 1 do
  371. TObject(List.Items[i]).Destroy;
  372. List.Clear;
  373. end;
  374. procedure GetMethodList(AObject: TObject; AList: TStrings);
  375. var
  376. Methods: TTypeMemberMethodDynArray;
  377. i: Integer;
  378. m: TTypeMemberMethod;
  379. begin
  380. Methods:=GetClassMethods(TypeInfo(AObject.ClassType));
  381. for i:=0 to length(Methods)-1 do
  382. begin
  383. m:=Methods[i];
  384. if AList.IndexOf(m.Name)>=0 then continue;
  385. AList.AddObject(m.Name,TObject(GetInstanceMethod(AObject,m.Name)));
  386. end;
  387. end;
  388. { TTestResult }
  389. function TTestResult.GetNumErrors: integer;
  390. begin
  391. Result := FErrors.Count;
  392. end;
  393. function TTestResult.GetNumFailures: integer;
  394. begin
  395. Result := FFailures.Count;
  396. end;
  397. function TTestResult.GetNumIgnoredTests: integer;
  398. begin
  399. Result := FIgnoredTests.Count;
  400. end;
  401. function TTestResult.GetNumSkipped: integer;
  402. begin
  403. Result := FSkippedTests.Count;
  404. end;
  405. constructor TTestResult.Create;
  406. begin
  407. inherited Create;
  408. FFailures := TFPList.Create;
  409. FIgnoredTests := TFPList.Create;
  410. FErrors := TFPList.Create;
  411. FListeners := TFPList.Create;
  412. FSkippedTests := TFPList.Create;
  413. FStartingTime := Now;
  414. end;
  415. destructor TTestResult.Destroy;
  416. begin
  417. FreeObjects(FFailures);
  418. FreeAndNil(FFailures);
  419. FreeObjects(FIgnoredTests);
  420. FreeAndNil(FIgnoredTests);
  421. FreeObjects(FErrors);
  422. FreeAndNil(FErrors);
  423. FreeAndNil(FListeners);
  424. FreeAndNil(FSkippedTests);
  425. end;
  426. procedure TTestResult.ClearErrorLists;
  427. begin
  428. FreeObjects(FFailures);
  429. FFailures.Clear;
  430. FreeObjects(FIgnoredTests);
  431. FIgnoredTests.Clear;
  432. FreeObjects(FErrors);
  433. FreeAndNil(FErrors);
  434. end;
  435. procedure TTestResult.StartTest(ATest: TTest);
  436. var
  437. count, i: integer;
  438. begin
  439. count := ATest.CountTestCases;
  440. //lock mutex
  441. FRunTests := FRunTests + count;
  442. for i := 0 to FListeners.Count - 1 do
  443. ITestListener(FListeners[i]).StartTest(ATest);
  444. //unlock mutex
  445. end;
  446. procedure TTestResult.AddFailure(ATest: TTest; E: EAssertionFailedError;
  447. aFailureList: TFPList);
  448. var
  449. f: TTestFailure;
  450. i: Integer;
  451. begin
  452. //lock mutex
  453. f := TTestFailure.CreateFailure(ATest, E, ATest.LastStep{, AThrownExceptionAdrs});
  454. aFailureList.Add(f);
  455. for i := 0 to FListeners.Count - 1 do
  456. ITestListener(FListeners[i]).AddFailure(ATest, f);
  457. //unlock mutex
  458. end;
  459. procedure TTestResult.AddError(ATest: TTest; E: Exception);
  460. var
  461. f: TTestFailure;
  462. i: Integer;
  463. begin
  464. //lock mutex
  465. f := TTestFailure.CreateFailure(ATest, E, ATest.LastStep{, AThrownExceptionAdrs});
  466. FErrors.Add(f);
  467. for i := 0 to FListeners.Count - 1 do
  468. ITestListener(FListeners[i]).AddError(ATest, f);
  469. //unlock mutex
  470. end;
  471. procedure TTestResult.EndTest(ATest: TTest);
  472. var
  473. i: integer;
  474. begin
  475. for i := 0 to FListeners.Count - 1 do
  476. ITestListener(FListeners[i]).EndTest(ATest);
  477. end;
  478. procedure TTestResult.AddListener(AListener: ITestListener);
  479. begin
  480. FListeners.Add(AListener);
  481. end;
  482. procedure TTestResult.RemoveListener(AListener: ITestListener);
  483. begin
  484. FListeners.Remove(AListener);
  485. end;
  486. procedure ProtectTest(aTest: TTest; aResult: TTestResult);
  487. begin
  488. if aResult=nil then ;
  489. TTestCase(aTest).RunBare;
  490. end;
  491. procedure TTestResult.Run(ATestCase: TTestCase);
  492. begin
  493. if not SkipTest(ATestCase) then
  494. begin
  495. StartTest(ATestCase);
  496. RunProtected(ATestCase, @ProtectTest);
  497. EndTest(ATestCase);
  498. end;
  499. end;
  500. procedure TTestResult.RunProtected(ATestCase: TTest; protect: TProtect);
  501. begin
  502. try
  503. protect(ATestCase, Self);
  504. except
  505. on E: EIgnoredTest do
  506. AddFailure(ATestCase, E, FIgnoredTests{, ExceptAddr});
  507. on E: EAssertionFailedError do
  508. AddFailure(ATestCase, E, FFailures{, ExceptAddr});
  509. on E: Exception do
  510. begin
  511. AddError(ATestCase, E{, ExceptAddr});
  512. end;
  513. end;
  514. end;
  515. function TTestResult.WasSuccessful: boolean;
  516. begin
  517. //lock mutex
  518. Result := (FErrors.Count = 0) and (FFailures.Count = 0);
  519. //unlock mutex
  520. end;
  521. function TTestResult.SkipTest(ATestCase: TTestCase): boolean;
  522. var
  523. i: integer;
  524. begin
  525. Result := false;
  526. if FSkippedTests.Count = 0 then
  527. begin
  528. result := false;
  529. Exit;
  530. end
  531. else
  532. for i := 0 to FSkippedTests.Count - 1 do
  533. begin
  534. if FSkippedTests[i] = ATestCase then
  535. begin
  536. Result := true;
  537. Exit;
  538. end;
  539. end;
  540. end;
  541. procedure TTestResult.AddToSkipList(ATestCase: TTestCase);
  542. begin
  543. FSkippedTests.Add(ATestCase);
  544. end;
  545. procedure TTestResult.RemoveFromSkipList(ATestCase: TTestCase);
  546. begin
  547. FSkippedTests.Remove(ATestCase);
  548. end;
  549. procedure TTestResult.StartTestSuite(ATestSuite: TTestSuite);
  550. var
  551. i: integer;
  552. begin
  553. for i := 0 to FListeners.Count - 1 do
  554. ITestListener(FListeners[i]).StartTestSuite(ATestSuite);
  555. end;
  556. procedure TTestResult.EndTestSuite(ATestSuite: TTestSuite);
  557. var
  558. i: integer;
  559. begin
  560. for i := 0 to FListeners.Count - 1 do
  561. ITestListener(FListeners[i]).EndTestSuite(ATestSuite);
  562. end;
  563. type
  564. { TTestItem }
  565. TTestItem = Class(TObject)
  566. private
  567. FName: String;
  568. FOwnsTest: Boolean;
  569. FTest: TTest;
  570. public
  571. Constructor Create(T : TTest); reintroduce;
  572. Destructor Destroy; override;
  573. Property Test : TTest Read FTest;
  574. Property TestName : String Read FName;
  575. Property OwnsTest : Boolean Read FOwnsTest Write FOwnstest;
  576. end;
  577. constructor TTestItem.Create(T: TTest);
  578. begin
  579. FTest:=T;
  580. FName:=T.TestName;
  581. FOwnsTest:=True;
  582. end;
  583. destructor TTestItem.Destroy;
  584. begin
  585. if OwnsTest then
  586. FreeAndNil(FTest);
  587. inherited Destroy;
  588. end;
  589. { TTestSuite }
  590. procedure TTestSuite.ClearTests;
  591. begin
  592. FTests.Clear;
  593. end;
  594. function TTestSuite.DoAddTest(ATest: TTest): Integer;
  595. begin
  596. Result:=FTests.Add(TTestItem.Create(ATest));
  597. if ATest.TestSuiteName = '' then
  598. ATest.TestSuiteName := Self.TestName;
  599. ATest.EnableIgnores := Self.EnableIgnores;
  600. end;
  601. function TTestSuite.GetTestName: string;
  602. begin
  603. Result := FName;
  604. end;
  605. function TTestSuite.GetTestSuiteName: string;
  606. begin
  607. Result := FTestSuiteName;
  608. end;
  609. function TTestSuite.GetEnableIgnores: boolean;
  610. begin
  611. Result := FEnableIgnores;
  612. end;
  613. procedure TTestSuite.SetTestSuiteName(const aName: string);
  614. begin
  615. if FTestSuiteName <> aName then
  616. FTestSuiteName := aName;
  617. end;
  618. procedure TTestSuite.SetTestName(const Value: string);
  619. begin
  620. FName := Value;
  621. end;
  622. procedure TTestSuite.SetEnableIgnores(Value: boolean);
  623. var
  624. i: integer;
  625. begin
  626. if FEnableIgnores <> Value then
  627. begin
  628. FEnableIgnores := Value;
  629. for i := 0 to FTests.Count - 1 do
  630. TTestItem(FTests[i]).Test.EnableIgnores := Value;
  631. end
  632. end;
  633. constructor TTestSuite.Create(AClass: TClass; AName: string);
  634. begin
  635. Create(AClass);
  636. FName := AName;
  637. end;
  638. constructor TTestSuite.Create(AClass: TClass);
  639. var
  640. i,j: integer;
  641. tc: TTestCaseClass;
  642. C : TTestCase;
  643. SN : String;
  644. ml: TTypeMemberMethodDynArray;
  645. begin
  646. TAssert.AssertNotNull(AClass);
  647. Create(AClass.ClassName);
  648. if AClass.InheritsFrom(TTestCase) then
  649. begin
  650. tc := TTestCaseClass(AClass);
  651. ml:=GetClassMethods(TypeInfo(AClass));
  652. SN:=tc.ClassName;
  653. if tc.SingleInstanceForSuite then
  654. begin
  655. c:=tc.CreateWith('',SN);
  656. for i := 0 to length(ml) -1 do
  657. begin
  658. C.TestName:=ml[i].Name;
  659. J:=DoAddTest(C);
  660. TTestItem(FTests[J]).OwnsTest:=(I=0);
  661. end;
  662. end
  663. else
  664. for i := 0 to length(ml) -1 do
  665. AddTest(tc.CreateWith(ml[i].Name, SN));
  666. end
  667. else
  668. AddTest(Warning(AClass.ClassName + SNoValidInheritance));
  669. if FTests.Count = 0 then
  670. AddTest(Warning(SNoValidTests + AClass.ClassName));
  671. end;
  672. constructor TTestSuite.Create(AClassArray: array of TClass);
  673. var
  674. i: integer;
  675. begin
  676. Create;
  677. for i := Low(AClassArray) to High(AClassArray) do
  678. if Assigned(AClassArray[i]) then
  679. AddTest(TTestSuite.Create(AClassArray[i]));
  680. end;
  681. constructor TTestSuite.Create(AName: string);
  682. begin
  683. Create();
  684. FName := AName;
  685. end;
  686. constructor TTestSuite.Create;
  687. begin
  688. inherited Create;
  689. FTests := TFPList.Create;
  690. FEnableIgnores := True;
  691. end;
  692. destructor TTestSuite.Destroy;
  693. begin
  694. FreeObjects(FTests);
  695. FreeAndNil(FTests);
  696. inherited Destroy;
  697. end;
  698. function TTestSuite.CountTestCases: integer;
  699. var
  700. i: integer;
  701. begin
  702. Result := 0;
  703. for i := 0 to FTests.Count - 1 do
  704. begin
  705. Result := Result + TTestItem(FTests[i]).Test.CountTestCases;
  706. end;
  707. end;
  708. function TTestSuite.GetChildTestCount: Integer;
  709. begin
  710. Result:=FTests.Count;
  711. end;
  712. function TTestSuite.GetChildTest(AIndex: Integer): TTest;
  713. begin
  714. Result := TTestItem(FTests[AIndex]).Test;
  715. end;
  716. procedure TTestSuite.Run(AResult: TTestResult);
  717. var
  718. i: integer;
  719. ti : TTestItem;
  720. begin
  721. if FTests.Count > 0 then
  722. AResult.StartTestSuite(self);
  723. for i := 0 to FTests.Count - 1 do
  724. begin
  725. ti:=TTestItem(FTests[i]);
  726. if Ti.Test.InheritsFrom(TTestCase) and TTestCase(Ti.Test).SingleInstanceForSuite then
  727. TTestCase(Ti.Test).SetTestName(Ti.TestName);
  728. RunTest(TI.Test, AResult);
  729. end;
  730. if FTests.Count > 0 then
  731. AResult.EndTestSuite(self);
  732. end;
  733. procedure TTestSuite.RunTest(ATest: TTest; AResult: TTestResult);
  734. begin
  735. ATest.Run(AResult);
  736. end;
  737. procedure TTestSuite.AddTest(ATest: TTest);
  738. begin
  739. DoAddTest(ATest);
  740. end;
  741. procedure TTestSuite.AddTestSuiteFromClass(ATestClass: TClass);
  742. begin
  743. AddTest(TTestSuite.Create(ATestClass));
  744. end;
  745. type
  746. TTestWarning = class(TTestCase)
  747. private
  748. FMessage: String;
  749. protected
  750. procedure RunTest; override;
  751. end;
  752. procedure TTestWarning.RunTest;
  753. begin
  754. Fail(FMessage);
  755. end;
  756. class function TTestSuite.Warning(const aMessage: string): TTestCase;
  757. var
  758. w: TTestWarning;
  759. begin
  760. w := TTestWarning.Create;
  761. w.FMessage := aMessage;
  762. Result := w;
  763. end;
  764. { TTestCase }
  765. function TTestCase.CreateResult: TTestResult;
  766. begin
  767. Result := TTestResult.Create;
  768. end;
  769. procedure TTestCase.SetUp;
  770. begin
  771. { do nothing }
  772. end;
  773. procedure TTestCase.TearDown;
  774. begin
  775. { do nothing }
  776. end;
  777. procedure TTestCase.RunTest;
  778. var
  779. RunMethod: TRunMethod;
  780. FailMessage : String;
  781. begin
  782. AssertNotNull('name of the test not assigned', FName);
  783. RunMethod:=TRunMethod(GetInstanceMethod(Self,FName));
  784. if Assigned(RunMethod) then
  785. begin
  786. ExpectException('',Nil,'',0);
  787. try
  788. AssertCount:=0;
  789. FailMessage:='';
  790. RunMethod;
  791. if (FExpectedException<>Nil) then
  792. FailMessage:=Format(SExceptionCompare, [FExpectedException.ClassName, SNoException]);
  793. if CheckAssertCalled and (AssertCount=0) then
  794. FailMessage:=SAssertNotCalled;
  795. except
  796. On E : Exception do
  797. begin
  798. if FExpectedException=Nil then
  799. Raise;
  800. If not (E is FExpectedException) then
  801. FailMessage:=Format(SExceptionCompare, [FExpectedException.ClassName, E.ClassName]);
  802. if (FExpectedExceptionMessage<>'') then
  803. if (FExpectedExceptionMessage<>E.Message) then
  804. FailMessage:=Format(SExceptionmessageCompare+SCompare, [FExpectedExceptionMessage,E.Message]);
  805. if (FExpectedExceptionContext<>0) then
  806. if (FExpectedExceptionContext<>E.HelpContext) then
  807. FailMessage:=Format(SExceptionHelpContextCompare+SCompare, [IntToStr(FExpectedExceptionContext),IntToStr(E.HelpContext)])
  808. end;
  809. end;
  810. if (FailMessage<>'') then
  811. begin
  812. if (FExpectedExceptionFailMessage<>'') then
  813. FailMessage:=' : '+FailMessage;
  814. Fail(FExpectedExceptionFailMessage+FailMessage{,FExpectedExceptionCaller});
  815. end;
  816. end
  817. else
  818. begin
  819. Fail(format(SMethodNotFound, [FName]));
  820. end;
  821. end;
  822. function TTestCase.GetTestName: string;
  823. begin
  824. Result := FName;
  825. end;
  826. function TTestCase.GetTestSuiteName: string;
  827. begin
  828. Result := FTestSuiteName;
  829. end;
  830. function TTestCase.GetEnableIgnores: boolean;
  831. begin
  832. Result := FEnableIgnores;
  833. end;
  834. procedure TTestCase.SetTestSuiteName(const aName: string);
  835. begin
  836. if FTestSuiteName <> aName then
  837. FTestSuiteName := aName;
  838. end;
  839. procedure TTestCase.SetTestName(const Value: string);
  840. begin
  841. FName := Value;
  842. end;
  843. procedure TTestCase.SetEnableIgnores(Value: boolean);
  844. begin
  845. FEnableIgnores := Value;
  846. end;
  847. procedure TTestCase.RunBare;
  848. begin
  849. FLastStep := stSetUp;
  850. SetUp;
  851. try
  852. FLastStep := stRunTest;
  853. RunTest;
  854. FLastStep := stTearDown;
  855. finally
  856. TearDown;
  857. end;
  858. FLastStep := stNothing;
  859. end;
  860. class function TTestCase.SingleInstanceForSuite: Boolean;
  861. begin
  862. Result:=False;
  863. end;
  864. constructor TTestCase.Create;
  865. begin
  866. inherited Create;
  867. FEnableIgnores := True;
  868. end;
  869. constructor TTestCase.CreateWith(const ATestName: string;
  870. const ATestSuiteName: string);
  871. begin
  872. Create;
  873. FName := ATestName;
  874. FTestSuiteName := ATestSuiteName;
  875. end;
  876. constructor TTestCase.CreateWithName(const AName: string);
  877. begin
  878. Create;
  879. FName := AName;
  880. end;
  881. procedure TTestCase.ExpectException(AExceptionClass: TClass;
  882. AExceptionMessage: string; AExceptionHelpContext: Integer);
  883. begin
  884. FExpectedExceptionFailMessage:='';
  885. FExpectedException:=AExceptionClass;
  886. FExpectedExceptionMessage:=AExceptionMessage;
  887. FExpectedExceptionContext:=AExceptionHelpContext;
  888. //FExpectedExceptionCaller:=CallerAddr;
  889. end;
  890. procedure TTestCase.ExpectException(const Msg: String; AExceptionClass: TClass;
  891. AExceptionMessage: string; AExceptionHelpContext: Integer);
  892. begin
  893. FExpectedExceptionFailMessage:=Msg;
  894. FExpectedException:=AExceptionClass;
  895. FExpectedExceptionMessage:=AExceptionMessage;
  896. FExpectedExceptionContext:=AExceptionHelpContext;
  897. // FExpectedExceptionCaller:=CallerAddr;
  898. end;
  899. function TTestCase.CountTestCases: integer;
  900. begin
  901. Result := 1;
  902. end;
  903. function TTestCase.CreateResultAndRun: TTestResult;
  904. begin
  905. Result := CreateResult;
  906. Run(Result);
  907. end;
  908. procedure TTestCase.Run(AResult: TTestResult);
  909. begin
  910. AResult.Run(Self);
  911. end;
  912. function TTestCase.AsString: string;
  913. begin
  914. Result := TestName + '(' + ClassName + ')';
  915. end;
  916. { TTestFailure }
  917. function TTestFailure.GetAsString: string;
  918. var
  919. s: string;
  920. begin
  921. if FTestSuiteName <> '' then
  922. s := FTestSuiteName + '.'
  923. else
  924. s := '';
  925. Result := s + FTestName + ': ' + FRaisedExceptionMessage;
  926. end;
  927. function TTestFailure.GetExceptionMessage: string;
  928. begin
  929. Result := FRaisedExceptionMessage;
  930. if TestLastStep = stSetUp then
  931. Result := '[SETUP] ' + Result
  932. else if TestLastStep = stTearDown then
  933. Result := '[TEARDOWN] ' + Result;
  934. end;
  935. function TTestFailure.GetIsFailure: boolean;
  936. begin
  937. Result := FRaisedExceptionClass.InheritsFrom(EAssertionFailedError);
  938. end;
  939. function TTestFailure.GetIsIgnoredTest: boolean;
  940. begin
  941. Result := FRaisedExceptionClass.InheritsFrom(EIgnoredTest);
  942. end;
  943. function TTestFailure.GetExceptionClassName: string;
  944. begin
  945. if Assigned(FRaisedExceptionClass) then
  946. Result := FRaisedExceptionClass.ClassName
  947. else
  948. Result := '<NIL>'
  949. end;
  950. procedure TTestFailure.SetTestLastStep(const Value: TTestStep);
  951. begin
  952. FTestLastStep := Value;
  953. end;
  954. constructor TTestFailure.CreateFailure(ATest: TTest; E: Exception;
  955. LastStep: TTestStep);
  956. begin
  957. inherited Create;
  958. FTestName := ATest.GetTestName;
  959. FTestSuiteName := ATest.GetTestSuiteName;
  960. FRaisedExceptionClass := E.ClassType;
  961. FRaisedExceptionMessage := E.Message;
  962. //FThrownExceptionAddress := ThrownExceptionAddrs;
  963. FTestLastStep := LastStep;
  964. end;
  965. { TAssert }
  966. class procedure TAssert.Fail(const AMessage: string);
  967. begin
  968. Inc(AssertCount);
  969. raise EAssertionFailedError.Create(AMessage);
  970. end;
  971. class procedure TAssert.Fail(const AFmt: string; Args: array of Const);
  972. begin
  973. Inc(AssertCount);
  974. raise EAssertionFailedError.CreateFmt(AFmt,Args);
  975. end;
  976. class procedure TAssert.FailEquals(const expected, actual: string;
  977. const ErrorMsg: string);
  978. begin
  979. Fail(EqualsErrorMessage(expected, actual, ErrorMsg));
  980. end;
  981. class procedure TAssert.FailNotEquals(const expected, actual: string;
  982. const ErrorMsg: string);
  983. begin
  984. Fail(NotEqualsErrorMessage(expected, actual, ErrorMsg));
  985. end;
  986. class procedure TAssert.AssertTrue(const AMessage: string; ACondition: boolean);
  987. begin
  988. if (not ACondition) then
  989. Fail(AMessage)
  990. else
  991. Inc(AssertCount); // Fail will increae AssertCount
  992. end;
  993. class procedure TAssert.AssertTrue(ACondition: boolean);
  994. begin
  995. AssertTrue('', ACondition);
  996. end;
  997. class procedure TAssert.AssertFalse(const AMessage: string; ACondition: boolean
  998. );
  999. begin
  1000. AssertTrue(AMessage, not ACondition);
  1001. end;
  1002. class procedure TAssert.AssertFalse(ACondition: boolean);
  1003. begin
  1004. AssertFalse('', ACondition);
  1005. end;
  1006. class procedure TAssert.AssertEquals(const AMessage: string; Expected,
  1007. Actual: string);
  1008. begin
  1009. AssertTrue(ComparisonMsg(AMessage, Expected, Actual), Expected=Actual);
  1010. end;
  1011. class procedure TAssert.AssertEquals(Expected, Actual: string);
  1012. begin
  1013. AssertTrue(ComparisonMsg(Expected, Actual), Expected=Actual);
  1014. end;
  1015. class procedure TAssert.AssertEquals(const AMessage: string; Expected,
  1016. Actual: NativeInt);
  1017. begin
  1018. AssertTrue(ComparisonMsg(AMessage,IntToStr(Expected), IntToStr(Actual)), Expected = Actual);
  1019. end;
  1020. class procedure TAssert.AssertEquals(Expected, Actual: NativeInt);
  1021. begin
  1022. AssertTrue(ComparisonMsg(IntToStr(Expected), IntToStr(Actual)), Expected = Actual);
  1023. end;
  1024. class procedure TAssert.AssertEquals(const AMessage: string; Expected, Actual,
  1025. Delta: double);
  1026. begin
  1027. AssertTrue(ComparisonMsg(AMessage,FloatToStr(Expected),FloatToStr(Actual)),
  1028. (Abs(Expected - Actual) <= Delta));
  1029. end;
  1030. class procedure TAssert.AssertEquals(Expected, Actual, Delta: double);
  1031. begin
  1032. AssertTrue(ComparisonMsg(FloatToStr(Expected),FloatToStr(Actual)),
  1033. (Abs(Expected - Actual) <= Delta));
  1034. end;
  1035. class procedure TAssert.AssertEquals(const AMessage: string; Expected,
  1036. Actual: boolean);
  1037. begin
  1038. AssertTrue(ComparisonMsg(AMessage,BoolToStr(Expected, true), BoolToStr(Actual, true)),
  1039. Expected = Actual);
  1040. end;
  1041. class procedure TAssert.AssertEquals(Expected, Actual: boolean);
  1042. begin
  1043. AssertTrue(ComparisonMsg(BoolToStr(Expected, true), BoolToStr(Actual, true)),
  1044. Expected = Actual);
  1045. end;
  1046. class procedure TAssert.AssertEquals(const AMessage: string; Expected,
  1047. Actual: char);
  1048. begin
  1049. AssertTrue(ComparisonMsg(AMessage,Expected, Actual), Expected = Actual);
  1050. end;
  1051. class procedure TAssert.AssertEquals(Expected, Actual: char);
  1052. begin
  1053. AssertTrue(ComparisonMsg(Expected, Actual), Expected = Actual);
  1054. end;
  1055. class procedure TAssert.AssertEquals(const AMessage: string; Expected,
  1056. Actual: TClass);
  1057. begin
  1058. AssertTrue(ComparisonMsg(AMessage,GetN(Expected), GetN(Actual)), Expected = Actual);
  1059. end;
  1060. class procedure TAssert.AssertEquals(Expected, Actual: TClass);
  1061. begin
  1062. AssertTrue(ComparisonMsg(GetN(Expected), GetN(Actual)), Expected = Actual);
  1063. end;
  1064. class procedure TAssert.AssertSame(const AMessage: string; Expected,
  1065. Actual: TObject);
  1066. begin
  1067. AssertTrue(ComparisonMsg(AMessage,GetN(Expected), GetN(Actual)), Expected = Actual);
  1068. end;
  1069. class procedure TAssert.AssertSame(Expected, Actual: TObject);
  1070. begin
  1071. AssertTrue(ComparisonMsg(GetN(Expected), GetN(Actual)), Expected = Actual);
  1072. end;
  1073. class procedure TAssert.AssertSame(const AMessage: string; Expected,
  1074. Actual: Pointer);
  1075. begin
  1076. AssertTrue(ComparisonMsg(AMessage,GetPtrN(Expected), GetPtrN(Actual)), Expected = Actual);
  1077. end;
  1078. class procedure TAssert.AssertSame(Expected, Actual: Pointer);
  1079. begin
  1080. AssertTrue(ComparisonMsg(GetPtrN(Expected), GetPtrN(Actual)), Expected = Actual);
  1081. end;
  1082. class procedure TAssert.AssertNotSame(const AMessage: string; Expected,
  1083. Actual: TObject);
  1084. begin
  1085. AssertFalse('"' + aMessage + '"' + SExpectedNotSame, Expected = Actual);
  1086. end;
  1087. class procedure TAssert.AssertNotSame(Expected, Actual: TObject);
  1088. begin
  1089. AssertFalse(SExpectedNotSame, Expected = Actual);
  1090. end;
  1091. class procedure TAssert.AssertNotSame(const AMessage: string; Expected,
  1092. Actual: Pointer);
  1093. begin
  1094. AssertFalse('"' + aMessage + '"' + SExpectedNotSame, Expected = Actual);
  1095. end;
  1096. class procedure TAssert.AssertNotSame(Expected, Actual: Pointer);
  1097. begin
  1098. AssertFalse(SExpectedNotSame, Expected = Actual);
  1099. end;
  1100. class procedure TAssert.AssertNotNull(const AMessage: string; AObject: TObject);
  1101. begin
  1102. AssertTrue(AMessage, (AObject <> nil));
  1103. end;
  1104. class procedure TAssert.AssertNotNull(AObject: TObject);
  1105. begin
  1106. AssertTrue('',(AObject <> nil));
  1107. end;
  1108. class procedure TAssert.AssertNotNull(const AMessage: string; APointer: Pointer
  1109. );
  1110. begin
  1111. AssertTrue(AMessage, (APointer <> nil));
  1112. end;
  1113. class procedure TAssert.AssertNotNull(APointer: Pointer);
  1114. begin
  1115. AssertTrue('', (APointer <> nil));
  1116. end;
  1117. class procedure TAssert.AssertNull(const AMessage: string; AObject: TObject);
  1118. begin
  1119. AssertTrue(AMessage, (AObject = nil));
  1120. end;
  1121. class procedure TAssert.AssertNull(AObject: TObject);
  1122. begin
  1123. AssertTrue('',(AObject = nil));
  1124. end;
  1125. class procedure TAssert.AssertNull(const AMessage: string; APointer: Pointer);
  1126. begin
  1127. AssertTrue(AMessage, (APointer = nil));
  1128. end;
  1129. class procedure TAssert.AssertNull(APointer: Pointer);
  1130. begin
  1131. AssertTrue('', (APointer = nil));
  1132. end;
  1133. class procedure TAssert.AssertNotNull(const AMessage, AString: string);
  1134. begin
  1135. AssertTrue(AMessage, AString <> '');
  1136. end;
  1137. class procedure TAssert.AssertNotNull(const AString: string);
  1138. begin
  1139. AssertNotNull('', AString);
  1140. end;
  1141. class procedure TAssert.AssertException(const AMessage: string;
  1142. AExceptionClass: ExceptClass; const AMethod: TRunMethod;
  1143. const AExceptionMessage: String; AExceptionContext: Integer);
  1144. Function MisMatch (AClassName : String) : String;
  1145. begin
  1146. Result:=Format(SExceptionCompare,[AExceptionClass.ClassName, AClassName])
  1147. end;
  1148. var
  1149. FailMsg : string;
  1150. begin
  1151. FailMsg:='';
  1152. try
  1153. AMethod;
  1154. FailMsg:=MisMatch(SNoException);
  1155. except
  1156. on E: Exception do
  1157. begin
  1158. if Not E.ClassType.InheritsFrom(AExceptionClass) then
  1159. FailMsg:=MisMatch(E.ClassName)
  1160. else if not (AExceptionClass.ClassName = E.ClassName) then
  1161. FailMsg:=MisMatch(E.ClassName)
  1162. else if (AExceptionMessage<>'') and (AExceptionMessage<>E.Message) then
  1163. FailMsg:=ComparisonMsg(SExceptionMessageCompare,AExceptionMessage,E.Message)
  1164. else if (AExceptionContext<>0) and (AExceptionContext<>E.HelpContext) then
  1165. FailMsg:=ComparisonMsg(SExceptionHelpContextCompare,IntToStr(AExceptionContext),IntToStr(E.HelpContext))
  1166. end;
  1167. end;
  1168. AssertTrue(AMessage + FailMsg, FailMsg='');
  1169. end;
  1170. class procedure TAssert.AssertException(AExceptionClass: ExceptClass;
  1171. const AMethod: TRunMethod; const AExceptionMessage: String;
  1172. AExceptionContext: Integer);
  1173. begin
  1174. AssertException('', AExceptionClass, AMethod, AExceptionMessage, AExceptionContext);
  1175. end;
  1176. class procedure TAssert.Check(pValue: boolean; pMessage: string);
  1177. begin
  1178. AssertTrue(pMessage, pValue);
  1179. end;
  1180. class procedure TAssert.CheckEquals(expected, actual: double; msg: string);
  1181. begin
  1182. CheckEquals(expected, actual, 0, msg);
  1183. end;
  1184. class procedure TAssert.CheckEquals(expected, actual: double; delta: double;
  1185. msg: string);
  1186. begin
  1187. AssertEquals(msg, expected, actual, delta);
  1188. end;
  1189. class procedure TAssert.CheckEquals(expected, actual: string; msg: string);
  1190. begin
  1191. AssertEquals(msg, expected, actual);
  1192. end;
  1193. class procedure TAssert.CheckEquals(expected, actual: integer; msg: string);
  1194. begin
  1195. AssertEquals(msg, expected, actual);
  1196. end;
  1197. class procedure TAssert.CheckEquals(expected, actual: boolean; msg: string);
  1198. begin
  1199. AssertEquals(msg, expected, actual);
  1200. end;
  1201. class procedure TAssert.CheckEquals(expected, actual: TClass; msg: string);
  1202. begin
  1203. AssertEquals(msg, expected, actual);
  1204. end;
  1205. class procedure TAssert.CheckNotEquals(expected, actual: string; msg: string);
  1206. begin
  1207. if Expected=Actual then
  1208. Fail(msg + ComparisonMsg(Expected, Actual, false));
  1209. end;
  1210. class procedure TAssert.CheckNotEquals(expected, actual: integer; msg: string);
  1211. begin
  1212. if (expected = actual) then
  1213. Fail(msg + ComparisonMsg(IntToStr(expected), IntToStr(actual), false));
  1214. end;
  1215. class procedure TAssert.CheckNotEquals(expected, actual: boolean; msg: string);
  1216. begin
  1217. if (expected = actual) then
  1218. Fail(msg + ComparisonMsg(BoolToStr(expected), BoolToStr(actual), false));
  1219. end;
  1220. class procedure TAssert.CheckNotEquals(expected, actual: double; delta: double;
  1221. msg: string);
  1222. begin
  1223. if (abs(expected-actual) <= delta) then
  1224. FailNotEquals(FloatToStr(expected), FloatToStr(actual), msg);
  1225. end;
  1226. class procedure TAssert.CheckNull(obj: TObject; msg: string);
  1227. begin
  1228. AssertNull(msg, obj);
  1229. end;
  1230. class procedure TAssert.CheckNotNull(obj: TObject; msg: string);
  1231. begin
  1232. AssertNotNull(msg, obj);
  1233. end;
  1234. class procedure TAssert.CheckIs(obj: TObject; pClass: TClass; msg: string);
  1235. begin
  1236. if pClass=nil then
  1237. Fail('TAssert.CheckIs pClass=nil');
  1238. if obj = nil then
  1239. Fail(ComparisonMsg(msg,pClass.ClassName, 'nil'))
  1240. else if not obj.ClassType.InheritsFrom(pClass) then
  1241. Fail(ComparisonMsg(msg,pClass.ClassName, obj.ClassName));
  1242. end;
  1243. class procedure TAssert.CheckSame(expected, actual: TObject; msg: string);
  1244. begin
  1245. AssertSame(msg, expected, actual);
  1246. end;
  1247. class procedure TAssert.CheckTrue(condition: Boolean; msg: string);
  1248. begin
  1249. if (not condition) then
  1250. FailNotEquals(BoolToStr(true, true), BoolToStr(false, true), msg);
  1251. end;
  1252. class procedure TAssert.CheckFalse(condition: Boolean; msg: string);
  1253. begin
  1254. if (condition) then
  1255. FailNotEquals(BoolToStr(false, true), BoolToStr(true, true), msg);
  1256. end;
  1257. class procedure TAssert.CheckException(const AMethod: TRunMethod;
  1258. AExceptionClass: ExceptClass; msg: string);
  1259. begin
  1260. AssertException(msg, AExceptionClass, AMethod);
  1261. end;
  1262. class function TAssert.EqualsErrorMessage(const expected, actual: string;
  1263. const ErrorMsg: string): string;
  1264. begin
  1265. if (ErrorMsg <> '') then
  1266. Result := Format(sExpectedButWasAndMessageFmt, [ErrorMsg + ', ', expected, actual])
  1267. else
  1268. Result := Format(sExpectedButWasFmt, [expected, actual])
  1269. end;
  1270. class function TAssert.NotEqualsErrorMessage(const expected, actual: string;
  1271. const ErrorMsg: string): string;
  1272. begin
  1273. if (ErrorMsg <> '') then
  1274. Result := Format(sExpectedButWasAndMessageFmt, [ErrorMsg, expected, actual])
  1275. else
  1276. Result := Format(sExpectedButWasFmt, [expected, actual]);
  1277. end;
  1278. class function TAssert.Suite: TTest;
  1279. begin
  1280. Result := TTestSuite.Create(Self);
  1281. end;
  1282. { TTest }
  1283. function TTest.GetTestName: string;
  1284. begin
  1285. Result := 'TTest';
  1286. end;
  1287. function TTest.GetTestSuiteName: string;
  1288. begin
  1289. Result := 'TTest';
  1290. end;
  1291. function TTest.GetEnableIgnores: boolean;
  1292. begin
  1293. Result := True;
  1294. end;
  1295. function TTest.CountTestCases: integer;
  1296. begin
  1297. Result := 0;
  1298. end;
  1299. function TTest.GetChildTestCount: Integer;
  1300. begin
  1301. Result:=0;
  1302. end;
  1303. function TTest.GetChildTest(AIndex: Integer): TTest;
  1304. begin
  1305. Result:=Nil;
  1306. if AIndex=0 then ;
  1307. end;
  1308. function TTest.FindChildTest(const AName: String): TTest;
  1309. Var
  1310. I : Integer;
  1311. begin
  1312. Result:=Nil;
  1313. I:=GetChildTestCount-1;
  1314. While (Result=Nil) and (I>=0) do
  1315. begin
  1316. Result:=GetChildTest(I);
  1317. if CompareText(Result.TestName,AName)<>0 then
  1318. Result:=Nil;
  1319. Dec(I);
  1320. end;
  1321. end;
  1322. function TTest.FindTest(const AName: String): TTest;
  1323. Var
  1324. S : String;
  1325. I,P : Integer;
  1326. begin
  1327. Result:=Nil;
  1328. S:=AName;
  1329. if S='' then exit;
  1330. P:=Pos('.',S);
  1331. If (P=0) then
  1332. P:=Length(S)+1;
  1333. Result:=FindChildTest(Copy(S,1,P-1));
  1334. if (Result<>Nil) then
  1335. begin
  1336. Delete(S,1,P);
  1337. If (S<>'') then
  1338. Result:=Result.FindTest(S);
  1339. end
  1340. else
  1341. begin
  1342. P:=GetChildTestCount;
  1343. I:=0;
  1344. While (Result=Nil) and (I<P) do
  1345. begin
  1346. Result:=GetChildTest(I).FindTest(Aname);
  1347. Inc(I);
  1348. end;
  1349. end;
  1350. end;
  1351. procedure TTest.Run(AResult: TTestResult);
  1352. begin
  1353. { do nothing }
  1354. if AResult=nil then ;
  1355. end;
  1356. procedure TTest.Ignore(const AMessage: string);
  1357. begin
  1358. if EnableIgnores then raise EIgnoredTest.Create(AMessage);
  1359. end;
  1360. end.