utests.pp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. {$mode objfpc}
  2. {$h+}
  3. unit utests;
  4. interface
  5. uses cgiapp,sysutils,mysqlDB4,whtml,dbwhtml,db,
  6. Classes,ftFont,fpimage,fpimgcanv,fpWritePng,fpcanvas;
  7. Type
  8. TTestSuite = Class(TCgiApplication)
  9. Private
  10. FHTMLWriter : THtmlWriter;
  11. FComboBoxProducer : TComboBoxProducer;
  12. FDB : TMySQLDatabase;
  13. FRunID,
  14. FVersion,
  15. FCPU,
  16. FOS : String;
  17. FDate : TDateTime;
  18. FDebug,
  19. FNoSkipped,
  20. FOnlyFailed : Boolean;
  21. FRunSkipCount,
  22. FRunFailedCount,
  23. FRunCount : Integer;
  24. FAction : Integer;
  25. FTestLastDays : Integer;
  26. Procedure GetOverviewRowAttr(Sender : TObject; Var BGColor : String;
  27. Var Align : THTMLAlign; Var VAlign : THTMLValign;
  28. Var CustomAttr : String) ;
  29. Procedure GetRunRowAttr(Sender : TObject; Var BGColor : String;
  30. Var Align : THTMLAlign; Var VAlign : THTMLValign;
  31. Var CustomAttr : String) ;
  32. Procedure FormatFailedOverview(Sender : TObject; Var CellData : String);
  33. Procedure DoDrawPie(Img : TFPCustomImage; Skipped,Failed,Total : Integer);
  34. Public
  35. Function CreateDataset(Qry : String) : TMySQLDataset;
  36. Function CreateTableProducer(DS : TDataset) :TTableProducer;
  37. Procedure DefaultTableFromQuery(Qry,ALink : String; IncludeRecordCount : Boolean);
  38. Procedure ComboBoxFromQuery(Const ComboName,Qry : String);
  39. Procedure ComboBoxFromQuery(Const ComboName,Qry,Value : String);
  40. Function GetSingleTon(Const Qry : String) : String;
  41. Function GetOSName(ID : String) : String;
  42. Function GetCPUName(ID : String) : String;
  43. Function GetVersionName(ID : String) : String;
  44. Function InitCGIVars : Integer;
  45. Procedure DoRun; override;
  46. Procedure EmitForm;
  47. Procedure ShowRunResults;
  48. Function ConnectToDB : Boolean;
  49. procedure DisconnectFromDB;
  50. Procedure EmitTitle(ATitle : String);
  51. Procedure ShowRunOverview;
  52. Procedure CreateRunPie;
  53. Function ShowRunData : Boolean;
  54. end;
  55. implementation
  56. Const
  57. {$i utests.cfg}
  58. { if utests.cfg is missed, create one with the following contents:
  59. DefDatabase = 'TESTSUITE';
  60. DefHost = '';
  61. DefDBUser = ''; // fill this in when compiling.
  62. DefPassword = ''; // fill this in, too.
  63. }
  64. Const
  65. SDetailsURL = 'testsuite.cgi?TESTACTION=1&TESTRUN=%s';
  66. Procedure TTestSuite.DoRun;
  67. begin
  68. Try
  69. Try
  70. Case InitCGIVars of
  71. 0 : EmitForm;
  72. 1 : ShowRunResults;
  73. 2 : CreateRunPie;
  74. end;
  75. finally
  76. DisConnectFromDB;
  77. end;
  78. Finally
  79. Terminate;
  80. end;
  81. end;
  82. Function TTestSuite.InitCGIVars : Integer;
  83. Var
  84. S : String;
  85. begin
  86. FHtmlWriter:=THTMLWriter.Create(Response);
  87. FComboBoxProducer:=TComboBoxProducer.Create(Self);
  88. DateSeparator:='/';
  89. Result:=0;
  90. FAction:=StrToIntDef(RequestVariables['TESTACTION'],0);
  91. FVersion:=RequestVariables['TESTVERSION'];
  92. FOS:=RequestVariables['TESTOS'];
  93. FCPU:=RequestVariables['TESTCPU'];
  94. S:=RequestVariables['TESTDATE'];
  95. FRunID:=RequestVariables['TESTRUN'];
  96. FTestLastDays:=StrToIntDef(RequestVariables['TESTLASTDAYS'],31);
  97. If (S<>'') then
  98. Try
  99. FDate:=StrToDate(S);
  100. except
  101. FDate:=0;
  102. end;
  103. S:=RequestVariables['TESTFAILEDONLY'];
  104. FOnlyFailed:=(S='1');
  105. S:=RequestVariables['TESTNOSKIPPED'];
  106. FNoSkipped:=(S='1');
  107. S:=RequestVariables['DEBUGCGI'];
  108. FRunCount:=StrToIntDef(RequestVariables['PIETOTAL'],0);
  109. FRunSkipCount:=StrToIntDef(RequestVariables['PIESKIPPED'],0);
  110. FRunFailedCount:=StrToIntDef(RequestVariables['PIEFAILED'],0);
  111. FDebug:=(S='1');
  112. Result:=FAction;
  113. end;
  114. Function TTestSuite.ConnectToDB : Boolean;
  115. begin
  116. Result:=False;
  117. FDB:=TMySQLDatabase.Create(Self);
  118. FDB.HostName:=DefHost;
  119. FDB.DatabaseName:=DefDatabase;
  120. FDB.UserName:=DefDBUser;
  121. FDB.Password:=DefPassword;
  122. FDB.Connected:=True;
  123. Result:=True;
  124. end;
  125. procedure TTestSuite.DisconnectFromDB;
  126. begin
  127. If Assigned(FDB) then
  128. begin
  129. if (FDB.Connected) then
  130. FDB.Connected:=False;
  131. FreeAndNil(FDB);
  132. end;
  133. end;
  134. Procedure TTestSuite.ComboBoxFromQuery(Const ComboName,Qry: String);
  135. begin
  136. ComboBoxFromQuery(ComboName,Qry,'')
  137. end;
  138. Procedure TTestSuite.ComboBoxFromQuery(Const ComboName,Qry,Value : String);
  139. Var
  140. Q : TMySQLDataset;
  141. begin
  142. Q:=TMySQLDataset.Create(Self);
  143. try
  144. Q.Database:=FDB;
  145. Q.SQL.Text:=Qry;
  146. Q.Open;
  147. FComboboxProducer.Dataset:=Q;
  148. FComboBoxProducer.ValueField:=Q.Fields[0].FieldName;
  149. FComboBoxProducer.DataField:=Q.Fields[1].FieldName;
  150. FComboBoxProducer.Value:=Value;
  151. FComboBoxProducer.InputName:=ComboName;
  152. FComboBoxProducer.CreateComboBox(Response);
  153. Finally
  154. Q.Free;
  155. end;
  156. end;
  157. Function TTestSuite.GetSingleton(Const Qry : String) : String;
  158. Var
  159. Q : TMySQLDataset;
  160. begin
  161. Result:='';
  162. Q:=TMySQLDataset.Create(Self);
  163. try
  164. Q.Database:=FDB;
  165. Q.SQL.Text:=Qry;
  166. Q.Open;
  167. Try
  168. If Not (Q.EOF and Q.BOF) then
  169. Result:=Q.Fields[0].AsString;
  170. Finally
  171. Q.Close;
  172. end;
  173. finally
  174. Q.Free;
  175. end;
  176. end;
  177. Procedure TTestSuite.EmitTitle(ATitle : String);
  178. begin
  179. AddResponseLn('<HTML>');
  180. AddResponseLn('<TITLE>'+ATitle+'</TITLE>');
  181. AddResponseLn('<BODY>');
  182. end;
  183. Procedure TTestSuite.EmitForm;
  184. begin
  185. ConnectToDB;
  186. ContentType:='text/html';
  187. EmitContentType;
  188. EmitTitle(Title);
  189. With FHTMLWriter do
  190. begin
  191. HeaderStart(1);
  192. Write('View Test suite results');
  193. HeaderEnd(1);
  194. Write('Please specify search criteria:');
  195. ParagraphStart;
  196. FormStart('testsuite.cgi','');
  197. TableStart(2,true);
  198. RowStart;
  199. CellStart;
  200. Write('Operating system:');
  201. CellNext;
  202. ComboBoxFromQuery('TESTOS','SELECT TO_ID,TO_NAME FROM TESTOS ORDER BY TO_NAME',FOS);
  203. CellEnd;
  204. RowNext;
  205. CellStart;
  206. Write('Processor:');
  207. CellNext;
  208. ComboBoxFromQuery('TESTCPU','SELECT TC_ID,TC_NAME FROM TESTCPU ORDER BY TC_NAME',FCPU);
  209. CellEnd;
  210. RowNext;
  211. CellStart;
  212. Write('Version');
  213. CellNext;
  214. ComboBoxFromQuery('TESTVERSION','SELECT TV_ID,TV_VERSION FROM TESTVERSION ORDER BY TV_VERSION DESC',FVERSION);
  215. CellEnd;
  216. RowNext;
  217. CellStart;
  218. Write('Date');
  219. CellNext;
  220. If (FDate=0) then
  221. EmitInput('TESTDATE','')
  222. else
  223. EmitInput('TESTDATE',DateToStr(FDate));
  224. CellEnd;
  225. RowNext;
  226. CellStart;
  227. Write('Only failed tests');
  228. CellNext;
  229. EmitCheckBox('TESTFAILEDONLY','1',FonlyFailed);
  230. CellEnd;
  231. RowNext;
  232. CellStart;
  233. Write('No skipped tests');
  234. CellNext;
  235. EmitCheckBox('TESTNOSKIPPED','1',FNoSkipped);
  236. CellEnd;
  237. RowEnd;
  238. TableEnd;
  239. ParaGraphStart;
  240. EmitSubmitButton('','Search');
  241. EmitResetButton('','Reset form');
  242. FormEnd;
  243. end;
  244. ShowRunOverview;
  245. AddResponseLn('</BODY>');
  246. AddResponseLn('</HTML>');
  247. end;
  248. procedure TTestSuite.GetOverviewRowAttr(Sender: TObject; var BGColor: String;
  249. var Align: THTMLAlign; var VAlign: THTMLValign; var CustomAttr: String);
  250. begin
  251. If ((Sender as TTAbleProducer).CurrentRow mod 2=0) then
  252. BGColor:='#EEEEEE'
  253. end;
  254. Function TTestSuite.CreateDataset(Qry : String) : TMySQLDataset;
  255. begin
  256. Result:=TMySQLdataset.Create(Self);
  257. With Result do
  258. begin
  259. Database:=FDB;
  260. SQL.Text:=Qry;
  261. end;
  262. end;
  263. Function TTestSuite.CreateTableProducer(DS : TDataset) :TTableProducer;
  264. begin
  265. Result:=TTableProducer.Create(Self);
  266. Result.Dataset:=DS;
  267. end;
  268. Procedure TTestSuite.DefaultTableFromQuery(Qry,Alink : String; IncludeRecordCount : Boolean);
  269. Var
  270. Q : TMySQLDataset;
  271. begin
  272. If FDebug then
  273. Write('Query : '+Qry);
  274. Q:=CreateDataset(Qry);
  275. With Q do
  276. try
  277. Open;
  278. Try
  279. With CreateTableProducer(Q) do
  280. Try
  281. Border:=True;
  282. If (Alink<>'') then
  283. begin
  284. CreateColumns(Nil);
  285. If TableColumns.Count>0 then
  286. (TableColumns.Items[0] as TTableColumn).ActionURL:=ALink;
  287. end;
  288. CreateTable(Response);
  289. Finally
  290. Free;
  291. end;
  292. If IncludeRecordCount then
  293. Write('Record count: '+IntTostr(Q.RecordCount));
  294. Finally
  295. Close;
  296. end;
  297. finally
  298. Free;
  299. end;
  300. end;
  301. Procedure TTestSuite.ShowRunOverview;
  302. Const
  303. SOverview = 'SELECT TU_ID,TU_DATE,TC_NAME,TO_NAME,TV_VERSION,COUNT(TR_ID) as RESULTCOUNT,'+
  304. '(TU_SUCCESSFULLYFAILED+TU_SUCCESFULLYCOMPILED+TU_SUCCESSFULLYRUN) AS OK,'+
  305. '(TU_FAILEDTOCOMPILE+TU_FAILEDTORUN+TU_FAILEDTOFAIL) as FAILED,'+
  306. '(TU_SUCCESSFULLYFAILED+TU_SUCCESFULLYCOMPILED+TU_SUCCESSFULLYRUN+'+
  307. 'TU_FAILEDTOCOMPILE+TU_FAILEDTORUN+TU_FAILEDTOFAIL) as TOTAL,'+
  308. 'TU_SUBMITTER as SUBMITTER, TU_MACHINE as MACHINE, TU_COMMENT as COMMENT'+
  309. ' FROM TESTRESULTS,TESTRUN,TESTCPU,TESTOS,TESTVERSION '+
  310. 'WHERE '+
  311. ' (TC_ID=TU_CPU_FK) AND '+
  312. ' (TO_ID=TU_OS_FK) AND '+
  313. ' (TV_ID=TU_VERSION_FK) AND '+
  314. ' (TR_TESTRUN_FK=TU_ID) '+
  315. ' %s '+
  316. ' GROUP BY TU_ID ';
  317. Var
  318. S,A,Qry : String;
  319. Q : TMySQLDataset;
  320. begin
  321. S:='';
  322. If (FCPU<>'') and (FCPU<>'0') then
  323. S:=S+' AND (TU_CPU_FK='+FCPU+')';
  324. If (FVersion<>'') and (FVersion<>'0') then
  325. S:=S+' AND (TU_VERSION_FK='+FVERSION+')';
  326. if (FOS<>'') and (FOS<>'0') then
  327. S:=S+' AND (TU_OS_FK='+FOS+')';
  328. If (Round(FDate)<>0) then
  329. S:=S+' AND (TU_DATE>="'+FormatDateTime('YYYY/MM/DD',FDate)+'")'
  330. else
  331. S:=S+' AND (TU_DATE>="'+FormatDateTime('YYYY/MM/DD',Date-FTESTLASTDAYS)+'")';
  332. If FOnlyFailed then
  333. S:=S+' AND (TR_OK="-")';
  334. A:=SDetailsURL;
  335. If FOnlyFailed then
  336. A:=A+'&TESTFAILEDONLY=1';
  337. If FNoSkipped then
  338. A:=A+'&TESTNOSKIPPED=1';
  339. Qry:=Format(SOverview,[S]);
  340. If FDebug then
  341. Write('Query : '+Qry);
  342. Q:=CreateDataset(Qry);
  343. With Q do
  344. try
  345. Open;
  346. Try
  347. With CreateTableProducer(Q) do
  348. Try
  349. Border:=True;
  350. OnGetRowAttributes:=@GetOverViewRowAttr;
  351. CreateColumns(Nil);
  352. TableColumns.ColumnByName('TU_ID').ActionURL:=A;
  353. TableColumns.ColumnByNAme('FAILED').OnGetCellContents:=@FormatFailedOverview;
  354. CreateTable(Response);
  355. Finally
  356. Free;
  357. end;
  358. Write('Record count: '+IntTostr(Q.RecordCount));
  359. Finally
  360. Close;
  361. end;
  362. finally
  363. Free;
  364. end;
  365. end;
  366. Function TTestSuite.GetOSName(ID : String) : String;
  367. begin
  368. if (ID<>'') then
  369. Result:=GetSingleTon('SELECT TO_NAME FROM TESTOS WHERE TO_ID='+ID);
  370. end;
  371. Function TTestSuite.GetCPUName(ID : String) : String;
  372. begin
  373. if (ID<>'') then
  374. Result:=GetSingleTon('SELECT TC_NAME FROM TESTCPU WHERE TC_ID='+ID);
  375. end;
  376. Function TTestSuite.GetVersionName(ID : String) : String;
  377. begin
  378. if (ID<>'') then
  379. Result:=GetSingleton('SELECT TV_VERSION FROM TESTVERSION WHERE TV_ID='+ID);
  380. end;
  381. Function TTestSuite.ShowRunData : Boolean;
  382. COnst
  383. SGetRunData = 'SELECT TU_ID,TU_DATE,TC_NAME,TO_NAME,TV_VERSION '+
  384. ' FROM TESTRUN,TESTCPU,TESTOS,TESTVERSION '+
  385. 'WHERE '+
  386. ' (TC_ID=TU_CPU_FK) AND '+
  387. ' (TO_ID=TU_OS_FK) AND '+
  388. ' (TV_ID=TU_VERSION_FK) AND '+
  389. ' (TU_ID=%s)';
  390. Var
  391. Q : TmYSQLDataset;
  392. begin
  393. Result:=(FRunID<>'');
  394. If Result then
  395. begin
  396. Q:=CreateDataset(Format(SGetRunData,[FRunID]));
  397. Try
  398. Q.Open;
  399. Result:=Not (Q.EOF and Q.BOF);
  400. If Result then
  401. With FHTMLWriter do
  402. begin
  403. TableStart(2,true);
  404. RowStart;
  405. CellStart;
  406. Write('Operating system:');
  407. CellNext;
  408. Write(Q.FieldByName('TO_NAME').AsString);
  409. CellEnd;
  410. RowNext;
  411. CellStart;
  412. Write('Processor:');
  413. CellNext;
  414. Write(Q.FieldByName('TC_NAME').AsString);
  415. CellEnd;
  416. RowNext;
  417. CellStart;
  418. Write('Version');
  419. CellNext;
  420. Write(Q.FieldByNAme('TV_VERSION').AsString);
  421. CellEnd;
  422. RowNext;
  423. CellStart;
  424. Write('Date');
  425. CellNext;
  426. Write(Q.FieldByNAme('TU_DATE').AsString);
  427. CellEnd;
  428. RowEnd;
  429. TableEnd;
  430. ParaGraphStart;
  431. end;
  432. Finally
  433. Q.Close;
  434. Q.Free;
  435. end;
  436. end;
  437. end;
  438. Procedure TTestSuite.ShowRunResults;
  439. Var
  440. S : String;
  441. Qry : String;
  442. Q : TMySQLDataset;
  443. FL : String;
  444. begin
  445. ConnectToDB;
  446. ContentType:='text/html';
  447. EmitContentType;
  448. EmitTitle(Title+' : Search Results');
  449. With FHTMLWriter do
  450. begin
  451. HeaderStart(1);
  452. Write('Test suite results for run '+FRunID);
  453. HeaderEnd(1);
  454. HeaderStart(2);
  455. Write('Test run data : ');
  456. HeaderEnd(2);
  457. If ShowRunData then
  458. begin
  459. HeaderStart(2);
  460. Write('Detailed test run results:');
  461. FL:='';
  462. If FOnlyFailed or FNoSkipped then
  463. begin
  464. FL:='';
  465. If FOnlyFailed then
  466. FL:='failed';
  467. if FNoSkipped then
  468. begin
  469. If (FL<>'') then
  470. FL:=FL+',';
  471. FL:=FL+'not skipped';
  472. end;
  473. Write(' (only '+FL+' tests are shown)');
  474. end;
  475. HeaderEnd(2);
  476. ParaGraphStart;
  477. S:='SELECT T_NAME as Test,T_FULLNAME as FileName ,TR_SKIP as Skipped,TR_OK as OK FROM ';
  478. S:=S+' TESTRESULTS,TESTS WHERE ';
  479. S:=S+' (TR_TEST_FK=T_ID) ';
  480. S:=S+' AND (TR_TESTRUN_FK='+FRunID+') ';
  481. If FOnlyFailed then
  482. S:=S+' AND (TR_OK="-")';
  483. If FNoSkipped then
  484. S:=S+' AND (TR_SKIP="-")';
  485. Qry:=S;
  486. If FDebug then
  487. Write('Query : '+Qry);
  488. FRunCount:=0;
  489. FRunSkipCount:=0;
  490. FRunFailedCount:=0;
  491. Q:=CreateDataset(Qry);
  492. With Q do
  493. try
  494. Open;
  495. Try
  496. With CreateTableProducer(Q) do
  497. Try
  498. Border:=True;
  499. FL:='Test,FileName';
  500. If Not FNoSkipped then
  501. FL:=FL+',Skipped';
  502. If Not FOnlyFailed then
  503. FL:=FL+',OK';
  504. CreateColumns(FL);
  505. OnGetRowAttributes:=@GetRunRowAttr;
  506. //(TableColumns.Items[0] as TTableColumn).ActionURL:=ALink;
  507. CreateTable(Response);
  508. Finally
  509. Free;
  510. end;
  511. Write('Record count: '+IntTostr(Q.RecordCount));
  512. Finally
  513. Close;
  514. end;
  515. finally
  516. Free;
  517. end;
  518. If Not (FRunCount=0) and not (FNoSkipped or FOnlyFailed) then
  519. begin
  520. ParaGraphStart;
  521. TagStart('IMG',Format('Src="testsuite.cgi?TESTACTION=2&PIETOTAL=%d&PIEFAILED=%d&PIESKIPPED=%d"',[FRunCount,FRunFailedCount,FRunSkipCount]));
  522. end;
  523. end
  524. else
  525. Write('No data for test run with ID: '+FRunID);
  526. end;
  527. end;
  528. procedure TTestSuite.GetRunRowAttr(Sender: TObject; var BGColor: String;
  529. var Align: THTMLAlign; var VAlign: THTMLValign; var CustomAttr: String);
  530. Var
  531. P : TTableProducer;
  532. begin
  533. P:=(Sender as TTAbleProducer);
  534. Inc(FRunCount);
  535. If (FOnlyFailed and FNoSkipped) then
  536. begin
  537. If (P.CurrentRow Mod 2)=0 then
  538. BGColor:='#EEEEEE'
  539. end
  540. else
  541. If P.Dataset.FieldByName('Skipped').AsString='+' then
  542. begin
  543. Inc(FRunSkipCount);
  544. BGColor:='yellow'; // Yellow
  545. end
  546. else If P.Dataset.FieldByName('OK').AsString='+' then
  547. BGColor:='#98FB98' // pale Green
  548. else
  549. begin
  550. Inc(FRunFailedCount);
  551. BGColor:='#FF82AB'; // Light red
  552. end;
  553. end;
  554. procedure TTestSuite.FormatFailedOverview(Sender: TObject; var CellData: String);
  555. Var
  556. S: String;
  557. P : TTableProducer;
  558. begin
  559. P:=(Sender as TTableProducer);
  560. S:=Format(SDetailsURL,[P.DataSet.FieldByName('TU_ID').AsString]);
  561. S:=S+'&TESTFAILEDONLY=1&TESTNOSKIPPED=1';
  562. CellData:=Format('<A HREF="%s">%s</A>',[S,CellData]);
  563. end;
  564. Procedure TTestSuite.CreateRunPie;
  565. Var
  566. I : TFPMemoryImage;
  567. M : TMemoryStream;
  568. begin
  569. ftFont.InitEngine;
  570. FontMgr.SearchPath:='/usr/lib/X11/fonts/truetype';
  571. I:=TFPMemoryImage.Create(320,320);
  572. try
  573. If FRunCount=0 Then
  574. Raise Exception.Create('Invalid parameters passed to script: No total count');
  575. DoDrawPie(I,FRunSkipCount,FRunFailedCount,FRunCount);
  576. M:=TMemoryStream.Create;
  577. Try
  578. With TFPWriterPNG.Create do
  579. try
  580. UseAlpha:=True;
  581. ImageWrite(M,I);
  582. Finally
  583. Free;
  584. end;
  585. ContentType:='image/png';
  586. EmitContentType;
  587. M.Position:=0;
  588. Response.CopyFrom(M,M.Size);
  589. Finally
  590. M.Free;
  591. end;
  592. Finally
  593. I.Free;
  594. end;
  595. end;
  596. Procedure TTestSuite.DoDrawPie(Img : TFPCustomImage; Skipped,Failed,Total : Integer);
  597. Var
  598. Cnv : TFPImageCanvas;
  599. W,H,FH,CR,ra : Integer;
  600. A1,A2,FR,SR,PR : Double;
  601. R : TRect;
  602. F : TFreeTypeFont;
  603. Procedure AddPie(X,Y,R : Integer; AStart,AStop : Double; Col : TFPColor);
  604. Var
  605. DX,Dy : Integer;
  606. begin
  607. DX:=Round(R*Cos(A1));
  608. DY:=Round(R*Sin(A1));
  609. Cnv.Line(X,Y,X+DX,Y-DY);
  610. DX:=Round(Ra*Cos(A2));
  611. DY:=Round(Ra*Sin(A2));
  612. Cnv.Line(X,Y,X+DX,Y-Dy);
  613. DX:=Round(R/2*Cos((A1+A2)/2));
  614. DY:=Round(R/2*Sin((A1+A2)/2));
  615. Cnv.Brush.FpColor:=Col;
  616. Cnv.FloodFill(X+DX,Y-DY);
  617. end;
  618. Function FractionAngle(F,T : Integer): Double;
  619. begin
  620. Result:=(2*Pi*(F/T))
  621. end;
  622. begin
  623. F:=TFreeTypeFont.Create;
  624. With F do
  625. begin
  626. Name:='arial';
  627. FontIndex:=0;
  628. Size:=12;
  629. FPColor:=colred;
  630. AntiAliased:=False;
  631. Resolution:=96;
  632. end;
  633. // Writeln('Creating image');
  634. Cnv:=TFPImageCanvas.Create(Img);
  635. // Writeln('Getting width and height');
  636. W:=Img.Width;
  637. H:=Img.Height;
  638. // Writeln('Transparant');
  639. cnv.Brush.Style:=bsSolid;
  640. cnv.Brush.FPColor:=colTransparent;
  641. cnv.Pen.FPColor:=colWhite;
  642. Cnv.Rectangle(0,0,W,H);
  643. // Writeln('Setting font');
  644. Cnv.Font:=F;
  645. // Writeln('Getting textwidth ');
  646. FH:=CNV.GetTextHeight('A');
  647. If FH=0 then
  648. FH:=14; // 3 * 14;
  649. Inc(FH,3);
  650. R.Top:=FH*4;
  651. R.Left:=0;
  652. R.Bottom:=H;
  653. CR:=H-(FH*4);
  654. If W>CR then
  655. R.Right:=CR
  656. else
  657. R.Right:=W;
  658. Ra:=CR div 2;
  659. // Writeln('Setting pen color');
  660. Cnv.Pen.FPColor:=colBlack;
  661. // Writeln('Palette size : ',Img.Palette.Count);
  662. // Writeln('Setting brush style');
  663. cnv.brush.FPColor:=colRed;
  664. // cnv.pen.width:=1;
  665. // Writeln('Drawing ellipse');
  666. Cnv.Ellipse(R);
  667. // Writeln('Setting text');
  668. // Writeln('Palette size : ',Img.Palette.Count);
  669. cnv.font.FPColor:=colred;
  670. Inc(FH,4);
  671. FR:=Failed/Total;
  672. SR:=Skipped/Total;
  673. PR:=1-(FR+SR);
  674. Cnv.Textout(1,FH,Format('%d Failed (%3.1f%%)',[Failed,Fr*100]));
  675. // Writeln('Palette size : ',Img.Palette.Count);
  676. cnv.font.FPColor:=colYellow;
  677. Cnv.Textout(1,FH*2,Format('%d Skipped (%3.1f%%)',[Skipped,SR*100]));
  678. A1:=(Pi*2*(failed/total));
  679. A2:=A1+(Pi*2*(Skipped/Total));
  680. AddPie(Ra,R.Top+Ra,Ra,A1,A2,ColYellow);
  681. cnv.font.FPColor:=colGreen;
  682. // Writeln('Palette size : ',Img.Palette.Count);
  683. A1:=A2;
  684. A2:=A1+(Pi*2*((Total-(Skipped+Failed))/Total));
  685. Cnv.Textout(1,FH*3,Format('%d Passed (%3.1f%%',[Total-Skipped-Failed,PR*100]));
  686. AddPie(Ra,R.Top+Ra,Ra,A1,A2,ColGreen);
  687. // Writeln('Palette size : ',Img.Palette.Count);
  688. // Writeln('All done');
  689. end;
  690. end.