pas2ut.pp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. {
  2. This file is part of the Free Pascal project
  3. Copyright (c) 2012 by the Free Pascal team
  4. Pascal source to FPC Unit test generator program
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. program pas2ut;
  12. {$mode objfpc}{$H+}
  13. uses
  14. Classes, SysUtils, pastounittest, pastree,CustApp;
  15. Resourcestring
  16. SErrNoInput = 'Error: No input file specified';
  17. SHelp0 = 'Usage : pp2ut [options] inputfile [outputfile]';
  18. SHelp1 = 'Where options is one or more of';
  19. SHelp2 = '--help this help';
  20. SHelp10 = '--test-protected also generate tests for protected class members' ;
  21. SHelp20 = '--skip-default skip tests for default visibility members' ;
  22. SHelp30 = '--skip-published skip tests for published members' ;
  23. SHelp40 = '--skip-public skip tests for public members';
  24. SHelp50 = '--tiopf tiopf tests (default,bounds,required,notify,maxlen)' ;
  25. SHelp60 = '--skip-property-default generate a default test for each property' ;
  26. SHelp70 = '--test-property-bounds generate a GetBounds test for each property' ;
  27. SHelp80 = '--test-property-required generate a Required test for each property' ;
  28. SHelp90 = '--test-property-notify generate a notify test for each property' ;
  29. SHelp100 = '--test-property-maxlen generate a maxlen test for each property' ;
  30. SHelp105 = '--skip-declaration Do not generate declarations for the tests' ;
  31. SHelp110 = '--skip-implementation Do not generate (empty) implementation for the tests' ;
  32. SHelp120 = '--skip-fail Skip fail() statement in test implementations ' ;
  33. SHelp130 = '--skip-unit Do not generate a unit' ;
  34. SHelp140 = '--skip-setup Skip TestCase class Setup() method' ;
  35. SHelp150 = '--skip-teardown Skip testcase class TearDown() method' ;
  36. SHelp160 = '--skip-functions Skip tests for functions/procedures' ;
  37. SHelp170 = '--skip-classes Skip tests for classes' ;
  38. SHelp180 = '--skip-register Do not generate RegisterTests statement' ;
  39. SHelp190 = '--singletestclass Use a single test class' ;
  40. SHelp200 = '--skip-methods Skip tests for methods of classes' ;
  41. SHelp210 = '--skip-fields Skip tests for fields of classes';
  42. SHelp220 = '--skip-properties Skip tests for properties of classes ' ;
  43. SHelp230 = '--testparentname=name Set the name of the parent class of test classes' ;
  44. SHelp240 = '--testunitname=name Set the name of the generated unit (default is taken from output file name)' ;
  45. SHelp250 = '--failmessage=Msg Set the message for the Fail() statement ' ;
  46. SHelp260 = '--unittestclassname=name Set the global unit test class name' ;
  47. SHelp270 = '--prefix=name Set the prefix for the test names (default is "Test") ' ;
  48. SHelp280 = '--limit=list Specify a comma-separated list of global identifiers for which to generate tests.' ;
  49. SHelp290 = '--defaultclasstest=list Specify a comma-separated list of default tests for each class' ;
  50. SHelp400 = '--limit and --defaultclasstest may be specified multiple times.';
  51. type
  52. { TPasToUnitTestApplication }
  53. TPasToUnitTestApplication = class(TCustomApplication)
  54. Private
  55. FCodeGen : TFPTestCodeCreator;
  56. FInputFile,FoutputFile : string;
  57. function CheckOptions : Boolean;
  58. protected
  59. procedure DoRun; override;
  60. public
  61. constructor Create(TheOwner: TComponent); override;
  62. destructor Destroy; override;
  63. procedure WriteHelp; virtual;
  64. end;
  65. { TPasToUnitTestApplication }
  66. function TPasToUnitTestApplication.CheckOptions : Boolean;
  67. Procedure ov(value : TPasMemberVisibility;incl: Boolean);
  68. begin
  69. if incl then
  70. FCodeGen.Visibilities:=FCodeGen.Visibilities+[value]
  71. else
  72. FCodeGen.Visibilities:=FCodeGen.Visibilities-[value]
  73. end;
  74. Procedure op(value : TTestPropertyOption;incl: Boolean);
  75. begin
  76. if incl then
  77. FCodeGen.PropertyOptions:=FCodeGen.PropertyOptions+[value]
  78. else
  79. FCodeGen.PropertyOptions:=FCodeGen.PropertyOptions-[value]
  80. end;
  81. Procedure oc(value : TTestCodeOption;incl: Boolean);
  82. begin
  83. if incl then
  84. FCodeGen.CodeOptions:=FCodeGen.CodeOptions+[value]
  85. else
  86. FCodeGen.CodeOptions:=FCodeGen.CodeOptions-[value]
  87. end;
  88. Procedure om(value : TTestMemberType;incl: Boolean);
  89. begin
  90. if incl then
  91. FCodeGen.MemberTypes:=FCodeGen.MemberTypes+[value]
  92. else
  93. FCodeGen.MemberTypes:=FCodeGen.MemberTypes-[value]
  94. end;
  95. Procedure AddValues(S : String; List : Tstrings);
  96. Var
  97. P : Integer;
  98. V : String;
  99. begin
  100. Repeat
  101. P:=Pos(',',S);
  102. If P=0 then
  103. P:=Length(S)+1;
  104. V:=Trim(Copy(S,1,P-1));
  105. If (V<>'') then
  106. List.Add(V);
  107. Delete(S,1,P);
  108. until (S='');
  109. end;
  110. Var
  111. S,O : string;
  112. I,p : Integer;
  113. begin
  114. Result:=False;
  115. I:=1;
  116. While (I<=ParamCount) do
  117. begin
  118. S:=ParamStr(I);
  119. P:=pos('=',S);
  120. if (P>0) then
  121. begin
  122. O:=S;
  123. Delete(O,1,P);
  124. S:=lowercase(Copy(S,1,P-1));
  125. end
  126. else
  127. O:='';
  128. if s='--test-protected' then
  129. ov(visProtected,true)
  130. else if s='--skip-default' then
  131. ov(visDefault,false)
  132. else if s='--skip-published' then
  133. ov(visPublished,false)
  134. else if s='--skip-public' then
  135. ov(visPublic,false)
  136. else if s='--tiopf' then
  137. begin
  138. FCodeGen.PropertyOptions:=[tDefault,tGetBounds,tRequired,tNotify,tMaxLen];
  139. end
  140. else if s='--skip-property-default' then
  141. op(tdefault,false)
  142. else if s='--test-property-bounds' then
  143. op(tgetBounds,true)
  144. else if s='--test-property-required' then
  145. op(trequired,true)
  146. else if s='--test-property-notify' then
  147. op(tNotify,true)
  148. else if s='--test-property-maxlen' then
  149. op(tMaxLen,true)
  150. else if s='--skip-declaration' then
  151. oc(coCreateDeclaration,false)
  152. else if s='--skip-implementation' then
  153. oc(coImplementation,false)
  154. else if s='--skip-fail' then
  155. oc(coDefaultFail,false)
  156. else if s='--skip-unit' then
  157. oc(coCreateUnit,false)
  158. else if s='--skip-setup' then
  159. oc(coSetup,false)
  160. else if s='--skip-teardown' then
  161. oc(coTeardown,false)
  162. else if s='--skip-functions' then
  163. oc(coFunctions,false)
  164. else if s='--skip-classes' then
  165. oc(coClasses,false)
  166. else if s='--skip-register' then
  167. oc(coRegisterTests,false)
  168. else if s='--singletestclass' then
  169. oc(coSingleClass,true)
  170. else if s='--skip-methods' then
  171. om(tmtMethods,false)
  172. else if s='--skip-fields' then
  173. om(tmtMethods,false)
  174. else if s='--skip-properties' then
  175. om(tmtMethods,false)
  176. else if (s='--testparentname') then
  177. FCodeGen.TestClassParent:=o
  178. else if (s='--testunitname') then
  179. FCodeGen.DestUnitname:=o
  180. else if (s='--failmessage') then
  181. FCodeGen.Failmessage:=o
  182. else if (s='--unittestclassname') then
  183. FCodeGen.UnitTestClassName:=O
  184. else if (s='--prefix') then
  185. FCodeGen.TestNamePrefix:=O
  186. else if (s='--limit') then
  187. AddValues(O,FCodeGen.LimitIdentifiers)
  188. else if (s='--defaultclasstest') then
  189. AddValues(O,FCodeGen.DefaultClassTests)
  190. else
  191. begin
  192. if (FInputFile='') then
  193. FInputFile:=s
  194. else if (FoutputFile<>'') then
  195. begin
  196. WriteHelp;
  197. Exit;
  198. end
  199. else
  200. FoutputFile:=s;
  201. end;
  202. Inc(I);
  203. end;
  204. Result:=FInputFile<>'';
  205. If Not Result then
  206. begin
  207. Writeln(SErrNoInput);
  208. WriteHelp;
  209. end;
  210. If (FOutputFile='') then
  211. FOutputFile:='tc'+FInputFile;
  212. end;
  213. procedure TPasToUnitTestApplication.DoRun;
  214. var
  215. ErrorMsg: String;
  216. begin
  217. Terminate;
  218. // parse parameters
  219. if HasOption('h','help') then
  220. begin
  221. WriteHelp;
  222. Exit;
  223. end;
  224. if CheckOptions then
  225. FCodeGen.Execute(FInputfile,FOutputFile);
  226. end;
  227. constructor TPasToUnitTestApplication.Create(TheOwner: TComponent);
  228. begin
  229. inherited Create(TheOwner);
  230. StopOnException:=True;
  231. FCodeGen :=TFPTestCodeCreator.Create(Self)
  232. end;
  233. destructor TPasToUnitTestApplication.Destroy;
  234. begin
  235. FreeAndNil(FCodeGen);
  236. inherited Destroy;
  237. end;
  238. procedure TPasToUnitTestApplication.WriteHelp;
  239. begin
  240. Writeln(SHelp0);
  241. Writeln(SHelp1);
  242. Writeln(SHelp10 );
  243. Writeln(SHelp20 );
  244. Writeln(SHelp30 );
  245. Writeln(SHelp40 );
  246. Writeln(SHelp50 );
  247. Writeln(SHelp60 );
  248. Writeln(SHelp70 );
  249. Writeln(SHelp80 );
  250. Writeln(SHelp90 );
  251. Writeln(SHelp100);
  252. Writeln(SHelp105);
  253. Writeln(SHelp110);
  254. Writeln(SHelp120);
  255. Writeln(SHelp130);
  256. Writeln(SHelp140);
  257. Writeln(SHelp150);
  258. Writeln(SHelp160);
  259. Writeln(SHelp170);
  260. Writeln(SHelp180);
  261. Writeln(SHelp190);
  262. Writeln(SHelp200);
  263. Writeln(SHelp210);
  264. Writeln(SHelp220);
  265. Writeln(SHelp230);
  266. Writeln(SHelp240);
  267. Writeln(SHelp250);
  268. Writeln(SHelp260);
  269. Writeln(SHelp270);
  270. Writeln(SHelp280);
  271. Writeln(SHelp290);
  272. Writeln(SHelp400);
  273. end;
  274. var
  275. Application: TPasToUnitTestApplication;
  276. begin
  277. Application:=TPasToUnitTestApplication.Create(nil);
  278. Application.Title:='Pascal code to Unit Tests';
  279. Application.Run;
  280. Application.Free;
  281. end.