pas2ut.pp 9.0 KB

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