tcmoduleparser.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  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('No interface units',0,IntfSection.UsesList.Count);
  106. AssertEquals('No implementation units',0,ImplSection.UsesList.Count);
  107. end;
  108. procedure TTestModuleParser.TestUnitOneUses;
  109. begin
  110. StartUnit('unit1');
  111. UsesClause(['a']);
  112. StartImplementation;
  113. ParseUnit;
  114. AssertEquals('Two interface units',2,IntfSection.UsesList.Count);
  115. CheckUnit(0,'System',IntfSection.UsesList);
  116. CheckUnit(1,'a',IntfSection.UsesList);
  117. AssertEquals('No implementation units',0,ImplSection.UsesList.Count);
  118. end;
  119. procedure TTestModuleParser.TestUnitTwoUses;
  120. begin
  121. StartUnit('unit1');
  122. UsesClause(['a','b']);
  123. StartImplementation;
  124. ParseUnit;
  125. AssertEquals('Two interface units',3,IntfSection.UsesList.Count);
  126. CheckUnit(0,'System',IntfSection.UsesList);
  127. CheckUnit(1,'a',IntfSection.UsesList);
  128. CheckUnit(2,'b',IntfSection.UsesList);
  129. AssertEquals('No implementation units',0,ImplSection.UsesList.Count);
  130. end;
  131. procedure TTestModuleParser.TestUnitOneImplUses;
  132. begin
  133. StartUnit('unit1');
  134. StartImplementation;
  135. UsesClause(['a']);
  136. ParseUnit;
  137. AssertEquals('One implementation units',1,ImplSection.UsesList.Count);
  138. CheckUnit(0,'a',ImplSection.UsesList);
  139. AssertEquals('No interface units',0,IntfSection.UsesList.Count);
  140. end;
  141. procedure TTestModuleParser.TestUnitTwoImplUses;
  142. begin
  143. StartUnit('unit1');
  144. StartImplementation;
  145. UsesClause(['a','b']);
  146. ParseUnit;
  147. AssertEquals('Two implementation units',2,ImplSection.UsesList.Count);
  148. CheckUnit(0,'a',ImplSection.UsesList);
  149. CheckUnit(1,'b',ImplSection.UsesList);
  150. AssertEquals('No interface units',0,IntfSection.UsesList.Count);
  151. end;
  152. procedure TTestModuleParser.TestEmptyUnitInitialization;
  153. begin
  154. StartUnit('unit1');
  155. StartImplementation;
  156. Add('initialization');
  157. ParseUnit;
  158. AssertNotNull('Have initialization section',Module.InitializationSection);
  159. AssertNull('Have no finalization section',Module.FinalizationSection)
  160. end;
  161. procedure TTestModuleParser.TestEmptyUnitFinalization;
  162. begin
  163. StartUnit('unit1');
  164. StartImplementation;
  165. Add('finalization');
  166. ParseUnit;
  167. AssertNull('Have no initalization section',Module.InitializationSection);
  168. AssertNotNull('Have finalization section',Module.FinalizationSection)
  169. end;
  170. procedure TTestModuleParser.TestEmptyUnitInitializationFinalization;
  171. begin
  172. StartUnit('unit1');
  173. StartImplementation;
  174. Add('initialization');
  175. Add('finalization');
  176. ParseUnit;
  177. AssertNotNull('Have finalization section',Module.InitializationSection);
  178. AssertNotNull('Have finalization section',Module.FinalizationSection);
  179. end;
  180. procedure TTestModuleParser.TestEmptyUnitBegin;
  181. begin
  182. StartUnit('unit1');
  183. StartImplementation;
  184. Add('begin');
  185. ParseUnit;
  186. AssertNotNull('Have initialization section',Module.InitializationSection);
  187. AssertNull('Have no finalization section',Module.FinalizationSection)
  188. end;
  189. procedure TTestModuleParser.TestEmptyProgram;
  190. begin
  191. StartProgram('something');
  192. Add('begin');
  193. ParseProgram;
  194. end;
  195. procedure TTestModuleParser.TestEmptyProgramInputOUtput;
  196. begin
  197. StartProgram('something','input','output');
  198. Add('begin');
  199. ParseProgram;
  200. end;
  201. procedure TTestModuleParser.TestEmptyProgramNoInitialization;
  202. begin
  203. StartProgram('something','input','output');
  204. Add('initialization');
  205. AssertProgramError;
  206. end;
  207. procedure TTestModuleParser.TestEmptyProgramNoFinalization;
  208. begin
  209. StartProgram('something','input','output');
  210. Add('finalization');
  211. AssertProgramError;
  212. end;
  213. procedure TTestModuleParser.TestEmptyProgramMissingBegin;
  214. begin
  215. StartProgram('something','input','output');
  216. AssertProgramError;
  217. end;
  218. procedure TTestModuleParser.TestEmptyProgramNoheader;
  219. begin
  220. Add('begin');
  221. ParseProgram;
  222. end;
  223. procedure TTestModuleParser.TestEmptyProgramUses;
  224. begin
  225. UsesClause(['a']);
  226. Add('begin');
  227. ParseProgram;
  228. AssertEquals('Two interface units',2, PasProgram.ProgramSection.UsesList.Count);
  229. CheckUnit(0,'System',PasProgram.ProgramSection.UsesList);
  230. CheckUnit(1,'a',PasProgram.ProgramSection.UsesList);
  231. end;
  232. procedure TTestModuleParser.TestEmptyProgramUsesTwoUnits;
  233. begin
  234. UsesClause(['a','b']);
  235. Add('begin');
  236. ParseProgram;
  237. AssertEquals('Three interface units',3, PasProgram.ProgramSection.UsesList.Count);
  238. CheckUnit(0,'System',PasProgram.ProgramSection.UsesList);
  239. CheckUnit(1,'a',PasProgram.ProgramSection.UsesList);
  240. CheckUnit(2,'b',PasProgram.ProgramSection.UsesList);
  241. end;
  242. procedure TTestModuleParser.TestEmptyProgramUsesUnitIn;
  243. Var
  244. U : TPasUnresolvedUnitRef;
  245. begin
  246. UsesClause(['a in ''../a.pas''','b']);
  247. Add('begin');
  248. ParseProgram;
  249. AssertEquals('One interface unit',3, PasProgram.ProgramSection.UsesList.Count);
  250. CheckUnit(0,'System',PasProgram.ProgramSection.UsesList);
  251. U:=CheckUnit(1,'a',PasProgram.ProgramSection.UsesList);
  252. AssertEquals('Filename','''../a.pas''',U.FileName);
  253. CheckUnit(2,'b',PasProgram.ProgramSection.UsesList);
  254. end;
  255. procedure TTestModuleParser.TestEmptyLibrary;
  256. begin
  257. StartLibrary('');
  258. ParseLibrary;
  259. AssertEquals('Correct class',TPasLibrary,Module.ClassType);
  260. end;
  261. procedure TTestModuleParser.TestEmptyLibraryUses;
  262. begin
  263. StartLibrary('');
  264. UsesClause(['a']);
  265. ParseLibrary;
  266. AssertEquals('Correct class',TPasLibrary,Module.ClassType);
  267. AssertEquals('Two interface units',2, PasLibrary.LibrarySection.UsesList.Count);
  268. CheckUnit(0,'System',PasLibrary.LibrarySection.UsesList);
  269. CheckUnit(1,'a',PasLibrary.LibrarySection.UsesList);
  270. end;
  271. procedure TTestModuleParser.TestEmptyLibraryExports;
  272. begin
  273. StartLibrary('');
  274. UsesClause(['b']);
  275. Add('exports A;');
  276. ParseLibrary;
  277. AssertEquals('1 export symbol',1,PasLibrary.LibrarySection.ExportSymbols.Count);
  278. AssertExportSymbol('Export symbol a',0,'A','',-1);
  279. end;
  280. procedure TTestModuleParser.TestEmptyLibraryExportsAlias;
  281. begin
  282. StartLibrary('');
  283. UsesClause(['b']);
  284. Add('exports A name ''c'';');
  285. ParseLibrary;
  286. AssertEquals('1 export symbol',1,PasLibrary.LibrarySection.ExportSymbols.Count);
  287. AssertExportSymbol('Export symbol a',0,'A','c',-1);
  288. end;
  289. procedure TTestModuleParser.TestEmptyLibraryExportsIndex;
  290. begin
  291. StartLibrary('');
  292. UsesClause(['b']);
  293. Add('exports A index 23;');
  294. ParseLibrary;
  295. AssertEquals('1 export symbol',1,PasLibrary.LibrarySection.ExportSymbols.Count);
  296. AssertExportSymbol('Export symbol a',0,'A','',23);
  297. end;
  298. procedure TTestModuleParser.TestEmptyLibraryExportsTwo;
  299. begin
  300. StartLibrary('');
  301. UsesClause(['b']);
  302. Add('exports A , C;');
  303. ParseLibrary;
  304. AssertEquals('2 export symbol',2,PasLibrary.LibrarySection.ExportSymbols.Count);
  305. AssertExportSymbol('Export symbol a',0,'A','',-1);
  306. AssertExportSymbol('Export symbol C',1,'C','',-1);
  307. end;
  308. procedure TTestModuleParser.TestEmptyLibraryExportsTwoAlias;
  309. begin
  310. StartLibrary('');
  311. UsesClause(['b']);
  312. Add('exports A name ''de'', C;');
  313. ParseLibrary;
  314. AssertEquals('2 export symbol',2,PasLibrary.LibrarySection.ExportSymbols.Count);
  315. AssertExportSymbol('Export symbol a',0,'A','de',-1);
  316. AssertExportSymbol('Export symbol C',1,'C','',-1);
  317. end;
  318. procedure TTestModuleParser.TestEmptyLibraryExportsTwoIndex;
  319. begin
  320. StartLibrary('');
  321. UsesClause(['b']);
  322. Add('exports A index 23, C;');
  323. ParseLibrary;
  324. AssertEquals('2 export symbol',2,PasLibrary.LibrarySection.ExportSymbols.Count);
  325. AssertExportSymbol('Export symbol a',0,'A','',23);
  326. AssertExportSymbol('Export symbol C',1,'C','',-1);
  327. end;
  328. initialization
  329. RegisterTests([TTestModuleParser]);
  330. end.