tcmoduleparser.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. unit tcmoduleparser;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, fpcunit, pastree, pscanner, pparser,
  6. tcbaseparser, testregistry;
  7. Type
  8. { TTestModuleParser }
  9. TTestModuleParser = class(TTestParser)
  10. private
  11. function GetIf: TInterfaceSection;
  12. function GetIm: TImplementationSection;
  13. function CheckUnit(AIndex: Integer; const AName: String; AList: TFPList): TPasUnresolvedUnitRef;
  14. Protected
  15. Procedure ParseUnit;
  16. Procedure ParseProgram;
  17. Procedure ParseLibrary;
  18. Procedure AssertProgramError;
  19. Property ImplSection : TImplementationSection Read GetIm;
  20. Property IntfSection : TInterfaceSection Read GetIf;
  21. Published
  22. Procedure TestEmptyUnit;
  23. Procedure TestUnitOneUses;
  24. Procedure TestUnitTwoUses;
  25. Procedure TestUnitOneImplUses;
  26. Procedure TestUnitTwoImplUses;
  27. Procedure TestEmptyUnitInitialization;
  28. Procedure TestEmptyUnitFinalization;
  29. Procedure TestEmptyUnitInitializationFinalization;
  30. Procedure TestEmptyUnitBegin;
  31. Procedure TestEmptyProgram;
  32. Procedure TestEmptyProgramInputOUtput;
  33. Procedure TestEmptyProgramNoInitialization;
  34. Procedure TestEmptyProgramNoFinalization;
  35. Procedure TestEmptyProgramMissingBegin;
  36. Procedure TestEmptyProgramNoheader;
  37. Procedure TestEmptyProgramUses;
  38. Procedure TestEmptyProgramUsesTwoUnits;
  39. Procedure TestEmptyProgramUsesUnitIn;
  40. Procedure TestEmptyLibrary;
  41. Procedure TestEmptyLibraryUses;
  42. Procedure TestEmptyLibraryExports;
  43. Procedure TestEmptyLibraryExportsAlias;
  44. Procedure TestEmptyLibraryExportsIndex;
  45. Procedure TestEmptyLibraryExportsTwo;
  46. Procedure TestEmptyLibraryExportsTwoAlias;
  47. Procedure TestEmptyLibraryExportsTwoIndex;
  48. end;
  49. implementation
  50. { TTestModuleParser }
  51. function TTestModuleParser.GetIf: TInterfaceSection;
  52. begin
  53. Result:=Module.InterfaceSection;
  54. end;
  55. function TTestModuleParser.GetIm: TImplementationSection;
  56. begin
  57. Result:=Module.ImplementationSection;
  58. end;
  59. procedure TTestModuleParser.ParseUnit;
  60. begin
  61. EndSource;
  62. ParseModule;
  63. AssertNotNull('Have interface',Module.InterfaceSection);
  64. Declarations:=Module.InterfaceSection;
  65. AssertEquals('Interface section',TInterfaceSection,Declarations.ClassType);
  66. AssertNotNull('Have implmeentation',Module.ImplementationSection);
  67. AssertEquals('implementation section',TImplementationSection,Module.ImplementationSection.ClassType);
  68. AssertNotNull('Have interface units',IntfSection.UsesList);
  69. AssertNotNull('Have implementation units',ImplSection.UsesList);
  70. end;
  71. procedure TTestModuleParser.ParseProgram;
  72. begin
  73. EndSource;
  74. ParseModule;
  75. AssertEquals('Is program',TPasProgram,Module.ClassType);
  76. end;
  77. procedure TTestModuleParser.ParseLibrary;
  78. begin
  79. EndSource;
  80. ParseModule;
  81. AssertEquals('Is library',TPasLibrary,Module.ClassType);
  82. end;
  83. procedure TTestModuleParser.AssertProgramError;
  84. begin
  85. AssertException(EParserError,@ParseProgram)
  86. end;
  87. function TTestModuleParser.CheckUnit(AIndex: Integer; const AName: String;
  88. AList: TFPList) : TPasUnresolvedUnitRef;
  89. Var
  90. C : string;
  91. begin
  92. C:='Unit '+IntTostr(AIndex)+' ';
  93. if (AIndex>=AList.Count) then
  94. Fail(Format('Index %d larger than unit list count %d',[AIndex,AList.Count ]));
  95. AssertNotNull('Have pascal element',AList[AIndex]);
  96. AssertEquals(C+'Correct class',TPasUnresolvedUnitRef,TObject(AList[AIndex]).CLassType);
  97. Result:=TPasUnresolvedUnitRef(AList[AIndex]);
  98. AssertEquals(C+'Unit name correct',AName,Result.Name);
  99. end;
  100. procedure TTestModuleParser.TestEmptyUnit;
  101. begin
  102. StartUnit('unit1');
  103. StartImplementation;
  104. ParseUnit;
  105. AssertEquals('Only system in interface units',1,IntfSection.UsesList.Count);
  106. CheckUnit(0,'System',IntfSection.UsesList);
  107. AssertEquals('No implementation units',0,ImplSection.UsesList.Count);
  108. end;
  109. procedure TTestModuleParser.TestUnitOneUses;
  110. begin
  111. StartUnit('unit1');
  112. UsesClause(['a']);
  113. StartImplementation;
  114. ParseUnit;
  115. AssertEquals('Two interface units',2,IntfSection.UsesList.Count);
  116. CheckUnit(0,'System',IntfSection.UsesList);
  117. CheckUnit(1,'a',IntfSection.UsesList);
  118. AssertEquals('No implementation units',0,ImplSection.UsesList.Count);
  119. end;
  120. procedure TTestModuleParser.TestUnitTwoUses;
  121. begin
  122. StartUnit('unit1');
  123. UsesClause(['a','b']);
  124. StartImplementation;
  125. ParseUnit;
  126. AssertEquals('Two interface units',3,IntfSection.UsesList.Count);
  127. CheckUnit(0,'System',IntfSection.UsesList);
  128. CheckUnit(1,'a',IntfSection.UsesList);
  129. CheckUnit(2,'b',IntfSection.UsesList);
  130. AssertEquals('No implementation units',0,ImplSection.UsesList.Count);
  131. end;
  132. procedure TTestModuleParser.TestUnitOneImplUses;
  133. begin
  134. StartUnit('unit1');
  135. StartImplementation;
  136. UsesClause(['a']);
  137. ParseUnit;
  138. AssertEquals('One implementation units',1,ImplSection.UsesList.Count);
  139. CheckUnit(0,'a',ImplSection.UsesList);
  140. AssertEquals('Only system in interface units',1,IntfSection.UsesList.Count);
  141. CheckUnit(0,'System',IntfSection.UsesList);
  142. end;
  143. procedure TTestModuleParser.TestUnitTwoImplUses;
  144. begin
  145. StartUnit('unit1');
  146. StartImplementation;
  147. UsesClause(['a','b']);
  148. ParseUnit;
  149. AssertEquals('One interface unit',1,IntfSection.UsesList.Count);
  150. CheckUnit(0,'System',IntfSection.UsesList);
  151. AssertEquals('Two implementation units',2,ImplSection.UsesList.Count);
  152. CheckUnit(0,'a',ImplSection.UsesList);
  153. CheckUnit(1,'b',ImplSection.UsesList);
  154. end;
  155. procedure TTestModuleParser.TestEmptyUnitInitialization;
  156. begin
  157. StartUnit('unit1');
  158. StartImplementation;
  159. Add('initialization');
  160. ParseUnit;
  161. AssertNotNull('Have initialization section',Module.InitializationSection);
  162. AssertNull('Have no finalization section',Module.FinalizationSection)
  163. end;
  164. procedure TTestModuleParser.TestEmptyUnitFinalization;
  165. begin
  166. StartUnit('unit1');
  167. StartImplementation;
  168. Add('finalization');
  169. ParseUnit;
  170. AssertNull('Have no initalization section',Module.InitializationSection);
  171. AssertNotNull('Have finalization section',Module.FinalizationSection)
  172. end;
  173. procedure TTestModuleParser.TestEmptyUnitInitializationFinalization;
  174. begin
  175. StartUnit('unit1');
  176. StartImplementation;
  177. Add('initialization');
  178. Add('finalization');
  179. ParseUnit;
  180. AssertNotNull('Have finalization section',Module.InitializationSection);
  181. AssertNotNull('Have finalization section',Module.FinalizationSection);
  182. end;
  183. procedure TTestModuleParser.TestEmptyUnitBegin;
  184. begin
  185. StartUnit('unit1');
  186. StartImplementation;
  187. Add('begin');
  188. ParseUnit;
  189. AssertNotNull('Have initialization section',Module.InitializationSection);
  190. AssertNull('Have no finalization section',Module.FinalizationSection)
  191. end;
  192. procedure TTestModuleParser.TestEmptyProgram;
  193. begin
  194. StartProgram('something');
  195. Add('begin');
  196. ParseProgram;
  197. end;
  198. procedure TTestModuleParser.TestEmptyProgramInputOUtput;
  199. begin
  200. StartProgram('something','input','output');
  201. Add('begin');
  202. ParseProgram;
  203. end;
  204. procedure TTestModuleParser.TestEmptyProgramNoInitialization;
  205. begin
  206. StartProgram('something','input','output');
  207. Add('initialization');
  208. AssertProgramError;
  209. end;
  210. procedure TTestModuleParser.TestEmptyProgramNoFinalization;
  211. begin
  212. StartProgram('something','input','output');
  213. Add('finalization');
  214. AssertProgramError;
  215. end;
  216. procedure TTestModuleParser.TestEmptyProgramMissingBegin;
  217. begin
  218. StartProgram('something','input','output');
  219. AssertProgramError;
  220. end;
  221. procedure TTestModuleParser.TestEmptyProgramNoheader;
  222. begin
  223. Add('begin');
  224. ParseProgram;
  225. end;
  226. procedure TTestModuleParser.TestEmptyProgramUses;
  227. begin
  228. UsesClause(['a']);
  229. Add('begin');
  230. ParseProgram;
  231. AssertEquals('Two interface units',2, PasProgram.ProgramSection.UsesList.Count);
  232. CheckUnit(0,'System',PasProgram.ProgramSection.UsesList);
  233. CheckUnit(1,'a',PasProgram.ProgramSection.UsesList);
  234. end;
  235. procedure TTestModuleParser.TestEmptyProgramUsesTwoUnits;
  236. begin
  237. UsesClause(['a','b']);
  238. Add('begin');
  239. ParseProgram;
  240. AssertEquals('Three interface units',3, PasProgram.ProgramSection.UsesList.Count);
  241. CheckUnit(0,'System',PasProgram.ProgramSection.UsesList);
  242. CheckUnit(1,'a',PasProgram.ProgramSection.UsesList);
  243. CheckUnit(2,'b',PasProgram.ProgramSection.UsesList);
  244. end;
  245. procedure TTestModuleParser.TestEmptyProgramUsesUnitIn;
  246. Var
  247. U : TPasUnresolvedUnitRef;
  248. begin
  249. UsesClause(['a in ''../a.pas''','b']);
  250. Add('begin');
  251. ParseProgram;
  252. AssertEquals('One interface unit',3, PasProgram.ProgramSection.UsesList.Count);
  253. CheckUnit(0,'System',PasProgram.ProgramSection.UsesList);
  254. U:=CheckUnit(1,'a',PasProgram.ProgramSection.UsesList);
  255. AssertEquals('Filename','''../a.pas''',U.FileName);
  256. CheckUnit(2,'b',PasProgram.ProgramSection.UsesList);
  257. end;
  258. procedure TTestModuleParser.TestEmptyLibrary;
  259. begin
  260. StartLibrary('');
  261. ParseLibrary;
  262. AssertEquals('Correct class',TPasLibrary,Module.ClassType);
  263. end;
  264. procedure TTestModuleParser.TestEmptyLibraryUses;
  265. begin
  266. StartLibrary('');
  267. UsesClause(['a']);
  268. ParseLibrary;
  269. AssertEquals('Correct class',TPasLibrary,Module.ClassType);
  270. AssertEquals('Two interface units',2, PasLibrary.LibrarySection.UsesList.Count);
  271. CheckUnit(0,'System',PasLibrary.LibrarySection.UsesList);
  272. CheckUnit(1,'a',PasLibrary.LibrarySection.UsesList);
  273. end;
  274. procedure TTestModuleParser.TestEmptyLibraryExports;
  275. begin
  276. StartLibrary('');
  277. UsesClause(['b']);
  278. Add('exports A;');
  279. ParseLibrary;
  280. AssertEquals('1 export symbol',1,PasLibrary.LibrarySection.ExportSymbols.Count);
  281. AssertExportSymbol('Export symbol a',0,'A','',-1);
  282. end;
  283. procedure TTestModuleParser.TestEmptyLibraryExportsAlias;
  284. begin
  285. StartLibrary('');
  286. UsesClause(['b']);
  287. Add('exports A name ''c'';');
  288. ParseLibrary;
  289. AssertEquals('1 export symbol',1,PasLibrary.LibrarySection.ExportSymbols.Count);
  290. AssertExportSymbol('Export symbol a',0,'A','c',-1);
  291. end;
  292. procedure TTestModuleParser.TestEmptyLibraryExportsIndex;
  293. begin
  294. StartLibrary('');
  295. UsesClause(['b']);
  296. Add('exports A index 23;');
  297. ParseLibrary;
  298. AssertEquals('1 export symbol',1,PasLibrary.LibrarySection.ExportSymbols.Count);
  299. AssertExportSymbol('Export symbol a',0,'A','',23);
  300. end;
  301. procedure TTestModuleParser.TestEmptyLibraryExportsTwo;
  302. begin
  303. StartLibrary('');
  304. UsesClause(['b']);
  305. Add('exports A , C;');
  306. ParseLibrary;
  307. AssertEquals('2 export symbol',2,PasLibrary.LibrarySection.ExportSymbols.Count);
  308. AssertExportSymbol('Export symbol a',0,'A','',-1);
  309. AssertExportSymbol('Export symbol C',1,'C','',-1);
  310. end;
  311. procedure TTestModuleParser.TestEmptyLibraryExportsTwoAlias;
  312. begin
  313. StartLibrary('');
  314. UsesClause(['b']);
  315. Add('exports A name ''de'', C;');
  316. ParseLibrary;
  317. AssertEquals('2 export symbol',2,PasLibrary.LibrarySection.ExportSymbols.Count);
  318. AssertExportSymbol('Export symbol a',0,'A','de',-1);
  319. AssertExportSymbol('Export symbol C',1,'C','',-1);
  320. end;
  321. procedure TTestModuleParser.TestEmptyLibraryExportsTwoIndex;
  322. begin
  323. StartLibrary('');
  324. UsesClause(['b']);
  325. Add('exports A index 23, C;');
  326. ParseLibrary;
  327. AssertEquals('2 export symbol',2,PasLibrary.LibrarySection.ExportSymbols.Count);
  328. AssertExportSymbol('Export symbol a',0,'A','',23);
  329. AssertExportSymbol('Export symbol C',1,'C','',-1);
  330. end;
  331. initialization
  332. RegisterTests([TTestModuleParser]);
  333. end.