2
0

tshtml.pas 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. unit tshtml;
  2. {$mode ObjFPC}
  3. {$h+}
  4. interface
  5. uses
  6. Classes, SysUtils, wformat, dbwhtml, whtml, sqldb, tsdb, tsconsts, tssql, tsutils, tstypes;
  7. var
  8. TestsuiteCGIURL : string;
  9. Type
  10. { TTestSuiteHTMLWriter }
  11. TTestSuiteHTMLWriter = class(THTMLWriter)
  12. Private
  13. FNeedEnd : Boolean;
  14. FSQL : TTestSQL;
  15. FComboBoxProducer:TComboBoxProducer;
  16. FVars : TQueryData;
  17. Public
  18. constructor create(aStream : TStream; aSQL: TTestSQL; aVars : TQueryData); reintroduce;
  19. destructor destroy; override;
  20. // Create HTML from SQL
  21. Procedure ComboBoxFromQuery(Const ComboName,Qry : String);
  22. Procedure ComboBoxFromQuery(Const ComboName,Qry,Value : String);
  23. Procedure ComboBoxFromQuery(Const ComboName,Qry : String; Value : integer);
  24. function CreateTableProducer(DS: TSQLQuery): TTableProducer;
  25. procedure DefaultTableFromQuery(Qry, ALink: String; IncludeRecordCount: Boolean);
  26. // Formatting things
  27. function FormatDetailURL(const RunIdStr, CellData: String): string;
  28. procedure FormatFailedOverview(Sender: TObject; var CellData: String);
  29. procedure FormatTestRunOverview(Sender: TObject; var CellData: String);
  30. procedure FormatSVN(Sender: TObject; var CellData: String);
  31. procedure FormatSVNData(var CellData: String);
  32. procedure FormatFileDetails(Sender: TObject; var CellData: String);
  33. procedure FormatFileIDDetails(Sender: TObject; var CellData: String);
  34. procedure FormatTestResult(Sender: TObject; var CellData: String);
  35. // reate Html
  36. procedure EmitHiddenVar(const Name: String; aValue: Int64); overload;
  37. procedure EmitDocType;
  38. procedure EmitTitle(ATitle: String);
  39. procedure EmitPieImage(aOKCount, aFailedCount, aSkipCount: integer);
  40. procedure EmitHistoryForm(aTitle: String);
  41. procedure EmitOverviewForm(aTitle: string);
  42. procedure DumpTestInfo(aInfo: TTestInfo);
  43. procedure EmitEnd;
  44. // In 3.2.2 the htmlwriter uses shortstring for Dumpln.
  45. // LDump cuts string into 255 char pieces and writes them one by one
  46. Procedure LDump(Const St : String);
  47. Procedure LDumpLn(Const St : String);
  48. procedure HandleVerbose(lvl: TVerboseLevel; const aMsg: String);
  49. end;
  50. implementation
  51. { TTestSuiteHTMLWriter }
  52. constructor TTestSuiteHTMLWriter.create(aStream: TStream; aSQL: TTestSQL; aVars: TQueryData);
  53. begin
  54. Inherited Create(aStream);
  55. FSQL:=ASQL;
  56. FComboBoxProducer:=TComboBoxProducer.Create(Nil);
  57. FVars:=aVars;
  58. end;
  59. destructor TTestSuiteHTMLWriter.destroy;
  60. begin
  61. FreeAndNil(FComboBoxProducer);
  62. inherited destroy;
  63. end;
  64. procedure TTestSuiteHTMLWriter.ComboBoxFromQuery(const ComboName, Qry: String);
  65. begin
  66. ComboBoxFromQuery(ComboName,Qry,'')
  67. end;
  68. procedure TTestSuiteHTMLWriter.ComboBoxFromQuery(const ComboName, Qry, Value: String);
  69. Var
  70. Q : TSQLQuery;
  71. begin
  72. Q:=FSQL.CreateQuery(Qry);
  73. try
  74. Q.Open;
  75. FComboboxProducer.Dataset:=Q;
  76. FComboBoxProducer.ValueField:=Q.Fields[0].FieldName;
  77. FComboBoxProducer.DataField:=Q.Fields[1].FieldName;
  78. FComboBoxProducer.Value:=Value;
  79. FComboBoxProducer.InputName:=ComboName;
  80. FComboBoxProducer.CreateComboBox(Stream);
  81. Finally
  82. Q.Free;
  83. end;
  84. end;
  85. procedure TTestSuiteHTMLWriter.ComboBoxFromQuery(const ComboName, Qry: String; Value: integer);
  86. begin
  87. ComboBoxFromQuery(ComboName,Qry,IntToStr(Value))
  88. end;
  89. procedure TTestSuiteHTMLWriter.FormatFailedOverview(Sender: TObject; var CellData: String);
  90. Var
  91. S: String;
  92. P : TTableProducer;
  93. begin
  94. P:=(Sender as TTableProducer);
  95. S:=Format(SDetailsURL,[P.DataSet.FieldByName('ID').AsString]);
  96. S:=S+'&failedonly=1&noskipped=1';
  97. CellData:=Format('<A HREF="%s">%s</A>',[S,CellData]);
  98. end;
  99. function TTestSuiteHTMLWriter.FormatDetailURL(const RunIdStr, CellData : String) : string;
  100. Var
  101. S : String;
  102. begin
  103. S:=Format(SDetailsURL,[RunIdStr]);
  104. if FVars.OnlyFailed then
  105. S:=S+'&amp;failedonly=1';
  106. if FVars.NoSkipped then
  107. S:=S+'&amp;noskipped=1';
  108. Result:=Format('<A HREF="%s">%s</A>',[S,CellData]);
  109. end;
  110. procedure TTestSuiteHTMLWriter.FormatTestRunOverview(Sender: TObject; var CellData: String);
  111. Var
  112. S: String;
  113. P : TTableProducer;
  114. begin
  115. P:=(Sender as TTableProducer);
  116. S:=Format(SDetailsURL,[P.DataSet.FieldByName('RUN').AsString]);
  117. if FVars.OnlyFailed then
  118. S:=S+'&amp;failedonly=1';
  119. if FVars.NoSkipped then
  120. S:=S+'&amp;noskipped=1';
  121. CellData:=Format('<A HREF="%s">%s</A>',[S,CellData]);
  122. end;
  123. procedure TTestSuiteHTMLWriter.FormatSVN(Sender: TObject; var CellData: String);
  124. begin
  125. FormatSVNData(CellData);
  126. end;
  127. procedure TTestSuiteHTMLWriter.FormatSVNData(var CellData: String);
  128. Var
  129. S, Rev, SubStr, Remaining : String;
  130. pos_colon, pos_sep : longint;
  131. begin
  132. if CellData='' then
  133. exit;
  134. pos_sep:=pos('/', CellData);
  135. if pos_sep=0 then
  136. begin
  137. pos_colon:=pos(':',CellData);
  138. S:=ViewGitHashURL+copy(CellData,pos_colon+1,length(CellData));
  139. CellData:=Format('<A HREF="%s" target="_blank">%s</A>',[S,CellData]);
  140. end
  141. else
  142. begin
  143. SubStr:=Copy(CellData,1,pos_sep-1);
  144. Remaining:=Copy(CellData,pos_sep+1,length(CellData));
  145. CellData:='';
  146. while SubStr<>'' do
  147. begin
  148. pos_colon:=pos(':',SubStr);
  149. Rev:=copy(SubStr,pos_colon+1,length(SubStr));
  150. { Remove suffix like M for modified...}
  151. while (length(Rev)>0) and (not (Rev[length(Rev)] in ['0'..'9','a'..'f','A'..'F'])) do
  152. Rev:=Copy(Rev,1,length(Rev)-1);
  153. S:=ViewGitHashURL+Rev;
  154. CellData:=CellData+Format('<A HREF="%s" target="_blank">%s</A>',[S,SubStr]);
  155. if Remaining='' then
  156. SubStr:=''
  157. else
  158. begin
  159. pos_sep:=pos('/',Remaining);
  160. if pos_sep=0 then
  161. pos_sep:=length(Remaining)+1;
  162. CellData:=CellData+':';
  163. SubStr:=Copy(Remaining,1,pos_sep-1);
  164. Remaining:=Copy(Remaining,pos_sep+1,length(Remaining));
  165. end;
  166. end;
  167. end;
  168. end;
  169. procedure TTestSuiteHTMLWriter.EmitHiddenVar(const Name: String; aValue: Int64);
  170. begin
  171. if (aValue<>-1) then
  172. EmitHiddenVar(Name,IntToStr(aValue));
  173. end;
  174. procedure TTestSuiteHTMLWriter.FormatFileIDDetails(Sender: TObject; var CellData: String);
  175. Var
  176. S: String;
  177. P : TTableProducer;
  178. begin
  179. P:=(Sender as TTableProducer);
  180. if FVars.VersionID<>-1 then
  181. S:=Format(TestSuiteCGIURL + '?action=%d&amp;version=%d&amp;testfileid=%d',
  182. [faction_show_history,FVars.VersionID,P.DataSet.FieldByName('Id').AsInteger])
  183. else
  184. S:=Format(TestSuiteCGIURL + '?action=%d&amp;testfileid=%s',
  185. [faction_show_history,P.DataSet.FieldByName('Id').AsString]);
  186. CellData:=Format('<A HREF="%s">%s</A>',[S,CellData]);
  187. end;
  188. procedure TTestSuiteHTMLWriter.FormatFileDetails(Sender: TObject; var CellData: String);
  189. Var
  190. S: String;
  191. P : TTableProducer;
  192. begin
  193. P:=(Sender as TTableProducer);
  194. if FVars.CompareRunID<>-1 then
  195. S:=Format(TestSuiteCGIURL + '?action=%d&amp;run1id=%d&amp;run2id=%d&amp;testfileid=%s',
  196. [faction_show_one_test,FVars.RunID,FVars.CompareRunID,P.DataSet.FieldByName('Id').AsString])
  197. else
  198. S:=Format(TestSuiteCGIURL + '?action=%d&amp;run1id=%d&amp;testfileid=%s',
  199. [faction_show_one_test,FVars.RunID,P.DataSet.FieldByName('Id').AsString]);
  200. CellData:=Format('<A HREF="%s">%s</A>',[S,CellData]);
  201. end;
  202. procedure TTestSuiteHTMLWriter.FormatTestResult(Sender: TObject; var CellData: String);
  203. Var
  204. Res : longint;
  205. Error:word;
  206. TS : TTestStatus;
  207. begin
  208. Val(CellData,Res,Error);
  209. if (Error=0) and (Res>=longint(FirstStatus)) and
  210. (Res<=longint(LastStatus)) then
  211. begin
  212. TS:=TTestStatus(Res);
  213. CellData:=StatusText[TS];
  214. end;
  215. end;
  216. procedure TTestSuiteHTMLWriter.EmitTitle(ATitle: String);
  217. begin
  218. if FNeedEnd then
  219. exit;
  220. DumpLn('<HTML>');
  221. DumpLn('<HEAD>');
  222. DumpLn('<TITLE>'+ATitle+'</TITLE>');
  223. Dumpln('<STYLE>');
  224. Dumpln('.logNormal { color: green; }');
  225. Dumpln('.logAbort { color: red; }');
  226. Dumpln('.logError { color: red; }');
  227. Dumpln('.logWarning { color: orange; }');
  228. Dumpln('.logSQL { color: darkblue; font-size: small; }');
  229. Dumpln('.logDebug { color: darkblue; font-size: small; }');
  230. Dumpln('</STYLE>');
  231. DumpLn('</HEAD>');
  232. DumpLn('<BODY>');
  233. FNeedEnd:=true;
  234. end;
  235. procedure TTestSuiteHTMLWriter.EmitDocType;
  236. begin
  237. if FNeedEnd then
  238. exit;
  239. DumpLn('<!DOCTYPE html>');
  240. end;
  241. function TTestSuiteHTMLWriter.CreateTableProducer(DS: TSQLQuery): TTableProducer;
  242. begin
  243. Result:=TTableProducer.Create(Nil);
  244. Result.Dataset:=DS;
  245. end;
  246. procedure TTestSuiteHTMLWriter.DefaultTableFromQuery(Qry, ALink: String; IncludeRecordCount: Boolean);
  247. Var
  248. Q : TSQLQuery;
  249. lTable : TTableProducer;
  250. begin
  251. If FVars.Debug then
  252. Writeln('Query : '+Qry);
  253. lTable:=Nil;
  254. Q:=FSQL.CreateQuery(Qry);
  255. try
  256. Q.Open;
  257. lTable:=CreateTableProducer(Q);
  258. lTable.Border:=True;
  259. If (Alink<>'') then
  260. begin
  261. lTable.CreateColumns(Nil);
  262. If lTable.TableColumns.Count>0 then
  263. (lTable.TableColumns.Items[0] as TTableColumn).ActionURL:=ALink;
  264. end;
  265. lTable.CreateTable(Stream);
  266. If IncludeRecordCount then
  267. DumpLn(Format('<p>Record count: %d </p>',[Q.RecordCount]));
  268. finally
  269. lTable.Free;
  270. Q.Free;
  271. end;
  272. end;
  273. procedure TTestSuiteHTMLWriter.EmitPieImage(aOKCount,aFailedCount,aSkipCount : integer);
  274. const
  275. sLink = 'Src="%s?action=2&amp;pietotal=%d&amp;piefailed=%d&amp;pieskipped=%d"'+
  276. ' ALT="total=%d, failed=%d, skipped=%d"';
  277. begin
  278. ParaGraphStart;
  279. TagStart('IMG',Format(SLink,[TestsuiteCGIURL,
  280. aOKCount,aFailedCount,aSkipCount,
  281. aOKCount,aFailedCount,aSkipCount
  282. ]));
  283. end;
  284. procedure TTestSuiteHTMLWriter.EmitHistoryForm(aTitle : String);
  285. begin
  286. EmitDocType;
  287. EmitTitle(aTitle);
  288. HeaderStart(1);
  289. DumpLn('View Test suite results');
  290. HeaderEnd(1);
  291. DumpLn('Please specify search criteria:');
  292. FormStart(TestsuiteCGIURL,'');
  293. if FVars.Debug then
  294. EmitHiddenVar('DEBUGCGI', '1');
  295. EmitHiddenVar('action',IntToStr(faction_show_history));
  296. TableStart(2,true);
  297. RowStart;
  298. CellStart;
  299. DumpLn('File:');
  300. CellNext;
  301. EmitInput('testfilename',FVars.Testfilename);
  302. CellEnd;
  303. RowNext;
  304. CellStart;
  305. DumpLn('Operating system:');
  306. CellNext;
  307. ComboBoxFromQuery('os','SELECT TO_ID,TO_NAME FROM TESTOS ORDER BY TO_NAME',IntToStr(FVars.OSID));
  308. CellEnd;
  309. RowNext;
  310. CellStart;
  311. DumpLn('Processor:');
  312. CellNext;
  313. ComboBoxFromQuery('cpu','SELECT TC_ID,TC_NAME FROM TESTCPU ORDER BY TC_NAME',FVars.CPUID);
  314. CellEnd;
  315. RowNext;
  316. CellStart;
  317. DumpLn('Version');
  318. CellNext;
  319. ComboBoxFromQuery('version','SELECT TV_ID,TV_VERSION FROM TESTVERSION ORDER BY TV_VERSION DESC',FVars.VERSIONID);
  320. CellEnd;
  321. RowNext;
  322. CellStart;
  323. DumpLn('Date');
  324. CellNext;
  325. If (FVars.Date=0) then
  326. EmitInput('date','')
  327. else
  328. EmitInput('date',DateToStr(FVars.Date));
  329. CellEnd;
  330. RowNext;
  331. CellStart;
  332. DumpLn('Submitter');
  333. CellNext;
  334. If (FVars.Submitter='') then
  335. EmitInput('submitter','')
  336. else
  337. EmitInput('submitter',FVars.Submitter);
  338. CellEnd;
  339. RowNext;
  340. CellStart;
  341. DumpLn('Machine');
  342. CellNext;
  343. If (FVars.Machine='') then
  344. EmitInput('machine','')
  345. else
  346. EmitInput('machine',FVars.Machine);
  347. CellEnd;
  348. RowNext;
  349. CellStart;
  350. DumpLn('Config');
  351. CellNext;
  352. If (FVars.Config='') then
  353. EmitInput('config','')
  354. else
  355. EmitInput('config',FVars.Config);
  356. CellEnd;
  357. RowNext;
  358. CellStart;
  359. DumpLn('Limit');
  360. CellNext;
  361. EmitInput('limit',IntToStr(FVars.Limit));
  362. CellEnd;
  363. RowNext;
  364. CellStart;
  365. DumpLn('Cond');
  366. CellNext;
  367. If (FVars.Cond='') then
  368. EmitInput('cond','')
  369. else
  370. EmitInput('cond',FVars.Cond);
  371. CellEnd;
  372. RowNext;
  373. CellStart;
  374. DumpLn('Category');
  375. CellNext;
  376. ComboBoxFromQuery('Category','SELECT TA_ID,TA_NAME FROM TESTCATEGORY ORDER BY TA_NAME',FVars.CategoryID);
  377. CellEnd;
  378. RowNext;
  379. CellStart;
  380. DumpLn('Only failed tests');
  381. CellNext;
  382. EmitCheckBox('failedonly','1',FVars.onlyFailed);
  383. CellEnd;
  384. RowNext;
  385. CellStart;
  386. DumpLn('Hide skipped tests');
  387. CellNext;
  388. EmitCheckBox('noskipped','1',FVars.NoSkipped);
  389. CellEnd;
  390. RowNext;
  391. CellStart;
  392. DumpLn('List all tests');
  393. CellNext;
  394. EmitCheckBox('listall','1',FVars.ListAll);
  395. CellEnd;
  396. RowEnd;
  397. TableEnd;
  398. ParaGraphStart;
  399. if FVars.Debug then
  400. EmitHiddenVar('DEBUGCGI', '1');
  401. EmitSubmitButton('','Search');
  402. EmitResetButton('','Reset form');
  403. FormEnd;
  404. end;
  405. procedure TTestSuiteHTMLWriter.EmitOverviewForm(aTitle : string);
  406. begin
  407. EmitDocType;
  408. EmitTitle(aTitle);
  409. HeaderStart(1);
  410. DumpLn('View Test suite results');
  411. HeaderEnd(1);
  412. DumpLn('Please specify search criteria:');
  413. FormStart(TestsuiteCGIURL,'');
  414. if FVars.Debug then
  415. EmitHiddenVar('DEBUGCGI', '1');
  416. TableStart(2,true);
  417. RowStart;
  418. CellStart;
  419. DumpLn('Operating system:');
  420. CellNext;
  421. ComboBoxFromQuery('os','SELECT TO_ID,TO_NAME FROM TESTOS ORDER BY TO_NAME',FVars.OSID);
  422. CellEnd;
  423. RowNext;
  424. CellStart;
  425. DumpLn('Processor:');
  426. CellNext;
  427. ComboBoxFromQuery('cpu','SELECT TC_ID,TC_NAME FROM TESTCPU ORDER BY TC_NAME',FVars.CPUID);
  428. CellEnd;
  429. RowNext;
  430. CellStart;
  431. DumpLn('Version');
  432. CellNext;
  433. ComboBoxFromQuery('version','SELECT TV_ID,TV_VERSION FROM TESTVERSION ORDER BY TV_VERSION DESC',FVars.VERSIONID);
  434. CellEnd;
  435. RowNext;
  436. CellStart;
  437. DumpLn('Date');
  438. CellNext;
  439. If (FVars.Date=0) then
  440. EmitInput('date','')
  441. else
  442. EmitInput('date',DateToStr(FVars.Date));
  443. CellEnd;
  444. //if FDebug then
  445. begin
  446. RowNext;
  447. CellStart;
  448. DumpLn('Submitter');
  449. CellNext;
  450. If (FVars.Submitter='') then
  451. EmitInput('submitter','')
  452. else
  453. EmitInput('submitter',FVars.Submitter);
  454. CellEnd;
  455. RowNext;
  456. CellStart;
  457. DumpLn('Machine');
  458. CellNext;
  459. If (FVars.Machine='') then
  460. EmitInput('machine','')
  461. else
  462. EmitInput('machine',FVars.Machine);
  463. CellEnd;
  464. RowNext;
  465. CellStart;
  466. DumpLn('Config');
  467. CellNext;
  468. If (FVars.Config='') then
  469. EmitInput('config','')
  470. else
  471. EmitInput('config',FVars.Config);
  472. CellEnd;
  473. RowNext;
  474. CellStart;
  475. DumpLn('Cond');
  476. CellNext;
  477. If (FVars.Cond='') then
  478. EmitInput('cond','')
  479. else
  480. EmitInput('cond',FVars.Cond);
  481. CellEnd;
  482. end;
  483. RowNext;
  484. CellStart;
  485. DumpLn('Category');
  486. CellNext;
  487. ComboBoxFromQuery('Category','SELECT TA_ID,TA_NAME FROM TESTCATEGORY ORDER BY TA_NAME',IntToStr(FVars.CategoryID));
  488. CellEnd;
  489. RowNext;
  490. CellStart;
  491. DumpLn('Only failed tests');
  492. CellNext;
  493. EmitCheckBox('failedonly','1',FVars.onlyFailed);
  494. CellEnd;
  495. RowNext;
  496. CellStart;
  497. DumpLn('Hide skipped tests');
  498. CellNext;
  499. EmitCheckBox('noskipped','1',FVars.NoSkipped);
  500. CellEnd;
  501. RowEnd;
  502. TableEnd;
  503. ParaGraphStart;
  504. EmitSubmitButton('','Search');
  505. EmitSubmitButton('action','View history');
  506. EmitResetButton('','Reset form');
  507. FormEnd;
  508. end;
  509. procedure TTestSuiteHTMLWriter.DumpTestInfo(aInfo: TTestInfo);
  510. Procedure MaybeField(const aName,aValue : string);
  511. begin
  512. if aValue='' then exit;
  513. DumpLn(aName+':');
  514. DumpLn(' ');
  515. DumpLn(aValue);
  516. DumpLn('<BR>');
  517. end;
  518. Procedure MaybeField(const aName : string; aValue : Boolean);
  519. begin
  520. if not aValue then exit;
  521. DumpLn('Flag ');
  522. DumpLn('"'+aName+'" :');
  523. DumpLn(' set');
  524. DumpLn('<BR>');
  525. end;
  526. Procedure MaybeField(const aName : string; aValue : Integer);
  527. begin
  528. if aValue<=0 then exit;
  529. MaybeField(aName,IntToStr(aValue));
  530. end;
  531. begin
  532. With aInfo do
  533. begin
  534. MaybeField('CPU',CPU);
  535. MaybeField('OS',OS);
  536. MaybeField('Version',Version);
  537. if addDate<>0 then
  538. MaybeField('Add date',FormatDateTime('yyy-mm-dd',addDate));
  539. MaybeField('Version',Version);
  540. MaybeField('Graph',Graph);
  541. MaybeField('Interactive',Interactive);
  542. MaybeField('Result',Result);
  543. MaybeField('Fail',Fail);
  544. MaybeField('Recompile',Recompile);
  545. MaybeField('NoRun',NoRun);
  546. MaybeField('NeedLibrary',NoRun);
  547. MaybeField('KnownRunError',KnownRunError);
  548. MaybeField('Note',Note);
  549. MaybeField('Description',Description);
  550. MaybeField('Opts',opts);
  551. end;
  552. end;
  553. procedure TTestSuiteHTMLWriter.EmitEnd;
  554. begin
  555. if not FNeedEnd then
  556. exit;
  557. DumpLn('</BODY>');
  558. DumpLn('</HTML>');
  559. end;
  560. procedure TTestSuiteHTMLWriter.HandleVerbose(lvl: TVerboseLevel; const aMsg: String);
  561. Const
  562. StyleNames : Array[TVerboseLevel] of string
  563. = ('Abort','Error','Warning','Normal','Debug','SQL');
  564. begin
  565. LDumpln(Format('<span class="log%s" >%s</span><br>',[StyleNames[lvl],aMsg]));
  566. end;
  567. procedure TTestsuiteHTMLWriter.LDump(Const St : String);
  568. var
  569. ShortS : ShortString;
  570. i,p : longint;
  571. begin
  572. i:=length(St);
  573. p:=1;
  574. while (i>255) do
  575. begin
  576. ShortS:=copy(St,p,255);
  577. inc(p,255);
  578. dec(i,255);
  579. Dump(ShortS);
  580. end;
  581. ShortS:=Copy(St,p,255);
  582. Dump(ShortS);
  583. end;
  584. procedure TTestsuiteHTMLWriter.LDumpLn(Const St : String);
  585. begin
  586. LDump(St);
  587. LDump(LineFeed);
  588. end;
  589. end.