fpcunitreport.pp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. {$mode objfpc}
  2. {$h+}
  3. {
  4. This file is part of the Free Component Library (FCL)
  5. Copyright (c) 2006 by Dean Zobec
  6. common base classes for FPCUnit test reports
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. unit fpcunitreport;
  14. interface
  15. uses
  16. classes, sysutils, fpcunit;
  17. type
  18. TWriteTestHeaderEvent = procedure(Sender: TObject; ATest: TTest;
  19. ALevel: integer; ACount: integer) of object;
  20. TWriteTestFooterEvent = procedure(Sender: TObject; ATest: TTest;
  21. ALevel: integer; ATiming: TDateTime) of object;
  22. TTestNameEvent = procedure(Sender: TObject; const AName: string) of object;
  23. TFailureEvent = procedure(Sender: TObject; ATest: TTest; AFailure: TTestFailure) of object;
  24. TTestEvent = procedure(Sender: TObject; ATest: TTest) of object;
  25. TWriteTestSuiteHeaderEvent = procedure(Sender: TObject; ATestSuite: TTestSuite;
  26. ALevel: integer) of object;
  27. TWriteTestSuiteFooterEvent = procedure(Sender: TObject; ATestSuite: TTestSuite;
  28. ALevel: integer; ATiming: TDateTime; ANumRuns: integer; ANumErrors: integer;
  29. ANumFailures: integer; ANumIgnores: integer) of object;
  30. TSuiteResults = class(TObject)
  31. private
  32. FRuns: integer;
  33. FErrors: integer;
  34. FFailures: integer;
  35. FIgnores: integer;
  36. FStartTime: TDateTime;
  37. public
  38. property Runs: integer read FRuns write FRuns;
  39. property Ignores: integer read FIgnores write FIgnores;
  40. property Errors: integer read FErrors write FErrors;
  41. property Failures: integer read FFailures write FFailures;
  42. property StartTime: TDateTime read FStartTime write FStartTime;
  43. end;
  44. TSuiteResultsStack = class(TObject)
  45. private
  46. FResultsList: TFPList;
  47. public
  48. constructor Create;
  49. destructor Destroy; override;
  50. function Last: TSuiteResults;
  51. procedure RemoveLast;
  52. procedure Add;
  53. procedure IncrementRuns;
  54. procedure IncrementFailures;
  55. procedure IncrementErrors;
  56. procedure IncrementIgnores;
  57. end;
  58. TCustomResultsWriter = class(TComponent, ITestListener)
  59. private
  60. FLevel: integer;
  61. FCount: integer;
  62. FTestTime: TDateTime;
  63. FFileName: string;
  64. FSuiteResultsStack : TSuiteResultsStack;
  65. FOnWriteSuiteHeader: TWriteTestSuiteHeaderEvent;
  66. FOnWriteSuiteFooter: TWriteTestSuiteFooterEvent;
  67. FOnWriteTestHeader: TWriteTestHeaderEvent;
  68. FOnWriteTestFooter: TWriteTestFooterEvent;
  69. FOnAddFailure: TFailureEvent;
  70. FOnAddError: TFailureEvent;
  71. FOnStartTest: TTestEvent;
  72. FOnEndTest: TTestEvent;
  73. FOnStartTestSuite: TTestEvent;
  74. FOnEndTestSuite: TTestEvent;
  75. protected
  76. procedure WriteTestHeader(ATest: TTest; ALevel: integer; ACount: integer); virtual;
  77. procedure WriteTestFooter(ATest: TTest; ALevel: integer; ATiming: TDateTime); virtual;
  78. procedure WriteSuiteHeader(ATestSuite: TTestSuite; ALevel: integer); virtual;
  79. procedure WriteSuiteFooter(ATestSuite: TTestSuite; ALevel: integer;
  80. ATiming: TDateTime; ANumRuns: integer; ANumErrors: integer; aNumFailures: integer;
  81. ANumIgnores: integer); virtual;
  82. procedure WriteHeader; virtual;
  83. procedure WriteFooter; virtual;
  84. public
  85. {ITestListener}
  86. procedure AddFailure(ATest: TTest; AFailure: TTestFailure); virtual;
  87. procedure AddError(ATest: TTest; AError: TTestFailure); virtual;
  88. procedure StartTest(ATest: TTest); virtual;
  89. procedure EndTest(ATest: TTest); virtual;
  90. procedure StartTestSuite(ATestSuite: TTestSuite); virtual;
  91. procedure EndTestSuite(ATestSuite: TTestSuite); virtual;
  92. constructor Create(AOwner: TComponent); override;
  93. destructor Destroy; override;
  94. procedure AfterConstruction; override;
  95. procedure BeforeDestruction; override;
  96. procedure WriteResult(aResult: TTestResult); virtual;
  97. published
  98. property FileName: string read FFileName write FFileName;
  99. property OnWriteSuiteHeader: TWriteTestSuiteHeaderEvent read FOnWriteSuiteHeader
  100. write FOnWriteSuiteHeader;
  101. property OnWriteSuiteFooter: TWriteTestSuiteFooterEvent read FOnWriteSuiteFooter
  102. write FOnWriteSuiteFooter;
  103. property OnWriteTestHeader: TWriteTestHeaderEvent read FOnWriteTestHeader
  104. write FOnWriteTestHeader;
  105. property OnWriteTestFooter: TWriteTestFooterEvent read FOnWriteTestFooter
  106. write FOnWriteTestFooter;
  107. property OnAddFailure: TFailureEvent read FOnAddFailure write FOnAddFailure;
  108. property OnAddError: TFailureEvent read FOnAddError write FOnAddError;
  109. property OnStartTest: TTestEvent read FOnStartTest write FOnStartTest;
  110. property OnEndTest: TTestEvent read FOnEndTest write FOnEndTest;
  111. property OnStartTestSuite: TTestEvent read FOnStartTestSuite write FOnStartTestSuite;
  112. property OnEndTestSuite: TTestEvent read FOnEndTestSuite write FOnEndTestSuite;
  113. end;
  114. implementation
  115. constructor TSuiteResultsStack.Create;
  116. begin
  117. FResultsList := TFPList.Create;
  118. end;
  119. destructor TSuiteResultsStack.Destroy;
  120. var
  121. i: integer;
  122. begin
  123. for i := 0 to FResultsList.Count -1 do
  124. TObject(FResultsList[i]).Free;
  125. FResultsList.Free;
  126. inherited Destroy;
  127. end;
  128. function TSuiteResultsStack.Last: TSuiteResults;
  129. begin
  130. Result := TSuiteResults(FResultsList[FResultsList.Count -1]);
  131. end;
  132. procedure TSuiteResultsStack.RemoveLast;
  133. begin
  134. TObject(FResultsList[FResultsList.Count - 1]).Free;
  135. FResultsList.Delete(FResultsList.Count - 1);
  136. end;
  137. procedure TSuiteResultsStack.Add;
  138. begin
  139. FResultsList.Add(TSuiteResults.Create);
  140. end;
  141. procedure TSuiteResultsStack.IncrementRuns;
  142. var
  143. i: integer;
  144. begin
  145. for i := 0 to FResultsList.Count -1 do
  146. Inc(TSuiteResults(FResultsList[i]).Runs);
  147. end;
  148. procedure TSuiteResultsStack.IncrementFailures;
  149. var
  150. i: integer;
  151. begin
  152. for i := 0 to FResultsList.Count -1 do
  153. Inc(TSuiteResults(FResultsList[i]).Failures);
  154. end;
  155. procedure TSuiteResultsStack.IncrementErrors;
  156. var
  157. i: integer;
  158. begin
  159. for i := 0 to FResultsList.Count -1 do
  160. Inc(TSuiteResults(FResultsList[i]).Errors);
  161. end;
  162. procedure TSuiteResultsStack.IncrementIgnores;
  163. var
  164. i: integer;
  165. begin
  166. for i := 0 to FResultsList.Count -1 do
  167. Inc(TSuiteResults(FResultsList[i]).Ignores);
  168. end;
  169. constructor TCustomResultsWriter.Create(AOwner: TComponent);
  170. begin
  171. inherited Create(AOwner);
  172. FLevel := -1;
  173. FCount := 1;
  174. FSuiteResultsStack := TSuiteResultsStack.Create;
  175. end;
  176. destructor TCustomResultsWriter.Destroy;
  177. begin
  178. FSuiteResultsStack.Free;
  179. inherited Destroy
  180. end;
  181. procedure TCustomResultsWriter.AfterConstruction;
  182. begin
  183. WriteHeader;
  184. end;
  185. procedure TCustomResultsWriter.BeforeDestruction;
  186. begin
  187. WriteFooter;
  188. end;
  189. procedure TCustomResultsWriter.StartTest(ATest: TTest);
  190. begin
  191. WriteTestHeader(ATest, FLevel, FCount);
  192. if Assigned(FOnStartTest) then
  193. FOnStartTest(Self, ATest);
  194. FTestTime := Now;
  195. end;
  196. procedure TCustomResultsWriter.EndTest(ATest: TTest);
  197. begin
  198. Inc(FCount);
  199. FTestTime := Now - FTestTime;
  200. FSuiteResultsStack.IncrementRuns;
  201. WriteTestFooter(ATest, FLevel, FTestTime);
  202. if Assigned(FOnEndTest) then
  203. FOnEndTest(Self, ATest);
  204. end;
  205. procedure TCustomResultsWriter.StartTestSuite(ATestSuite: TTestSuite);
  206. begin
  207. inc(FLevel);
  208. WriteSuiteHeader(ATestSuite, FLevel);
  209. if Assigned(FOnStartTestSuite) then
  210. FOnStartTestSuite(Self, ATestSuite);
  211. FSuiteResultsStack.Add;
  212. FSuiteResultsStack.Last.StartTime := now;
  213. end;
  214. procedure TCustomResultsWriter.EndTestSuite(ATestSuite: TTestSuite);
  215. begin
  216. with FSuiteResultsStack.Last do
  217. begin
  218. WriteSuiteFooter(ATestSuite, FLevel, Now - StartTime,
  219. Runs, Errors, Failures, Ignores);
  220. end;
  221. FSuiteResultsStack.RemoveLast;
  222. dec(FLevel);
  223. if Assigned(FOnEndTestSuite) then
  224. FOnEndTestSuite(Self, ATestSuite);
  225. end;
  226. procedure TCustomResultsWriter.AddFailure(ATest: TTest; AFailure: TTestFailure);
  227. begin
  228. if AFailure.IsIgnoredTest then
  229. FSuiteResultsStack.IncrementIgnores
  230. else
  231. FSuiteResultsStack.IncrementFailures;
  232. if Assigned(FOnAddFailure) then
  233. FOnAddFailure(Self, ATest, AFailure);
  234. end;
  235. procedure TCustomResultsWriter.AddError(ATest: TTest; AError: TTestFailure);
  236. begin
  237. FSuiteResultsStack.IncrementErrors;
  238. if Assigned(FOnAddError) then
  239. FOnAddError(Self, ATest, AError);
  240. end;
  241. procedure TCustomResultsWriter.WriteTestHeader(ATest: TTest; ALevel: integer; ACount: integer);
  242. begin
  243. if Assigned(FOnWriteTestHeader) then
  244. FOnWriteTestHeader(Self, ATest, ALevel, ACount);
  245. end;
  246. procedure TCustomResultsWriter.WriteTestFooter(ATest: TTest; ALevel: integer;
  247. ATiming: TDateTime);
  248. begin
  249. if Assigned(FOnWriteTestFooter) then
  250. FOnWriteTestFooter(Self, ATest, ALevel, ATiming);
  251. end;
  252. procedure TCustomResultsWriter.WriteSuiteHeader(ATestSuite: TTestSuite; ALevel: integer);
  253. begin
  254. if Assigned(FOnWriteSuiteHeader) then
  255. FOnWriteSuiteHeader(Self, ATestSuite, ALevel);
  256. end;
  257. procedure TCustomResultsWriter.WriteSuiteFooter(ATestSuite: TTestSuite; ALevel: integer;
  258. ATiming: TDateTime; ANumRuns: integer; ANumErrors: integer; ANumFailures: integer;
  259. ANumIgnores: integer);
  260. begin
  261. if Assigned(FOnWriteSuiteFooter) then
  262. FOnWriteSuiteFooter(Self, ATestSuite, ALevel, ATiming, ANumRuns, ANumErrors,
  263. aNumFailures, ANumIgnores);
  264. end;
  265. procedure TCustomResultsWriter.WriteHeader;
  266. begin
  267. // do nothing
  268. end;
  269. procedure TCustomResultsWriter.WriteFooter;
  270. begin
  271. // do nothing
  272. end;
  273. procedure TCustomResultsWriter.WriteResult(aResult: TTestResult);
  274. begin
  275. // do nothing
  276. end;
  277. end.