tcprecompile.pas 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 2018 by Michael Van Canneyt
  4. Unit tests for Pascal-to-Javascript converter class.
  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. Examples:
  12. ./testpas2js --suite=TTestCLI_Precompile
  13. ./testpas2js --suite=TTestModule.TestEmptyUnit
  14. }
  15. unit tcprecompile;
  16. {$mode objfpc}{$H+}
  17. interface
  18. uses
  19. Classes, SysUtils,
  20. fpcunit, testregistry, Pas2jsFileUtils, Pas2JsFiler,
  21. tcunitsearch, tcmodules;
  22. type
  23. { TCustomTestCLI_Precompile }
  24. TCustomTestCLI_Precompile = class(TCustomTestCLI)
  25. private
  26. FFormat: TPas2JSPrecompileFormat;
  27. protected
  28. procedure CheckPrecompile(MainFile, UnitPaths: string;
  29. SharedParams: TStringList = nil;
  30. FirstRunParams: TStringList = nil;
  31. SecondRunParams: TStringList = nil; ExpExitCode: integer = 0);
  32. public
  33. constructor Create; override;
  34. property Format: TPas2JSPrecompileFormat read FFormat write FFormat;
  35. end;
  36. { TTestCLI_Precompile }
  37. TTestCLI_Precompile = class(TCustomTestCLI_Precompile)
  38. published
  39. procedure TestPCU_EmptyUnit;
  40. procedure TestPCU_UTF8BOM;
  41. procedure TestPCU_ParamNS;
  42. procedure TestPCU_Overloads;
  43. procedure TestPCU_UnitCycle;
  44. procedure TestPCU_ClassForward;
  45. end;
  46. function LinesToList(const Lines: array of string): TStringList;
  47. implementation
  48. function LinesToList(const Lines: array of string): TStringList;
  49. var
  50. i: Integer;
  51. begin
  52. Result:=TStringList.Create;
  53. for i:=Low(Lines) to High(Lines) do Result.Add(Lines[i]);
  54. end;
  55. { TCustomTestCLI_Precompile }
  56. procedure TCustomTestCLI_Precompile.CheckPrecompile(MainFile,
  57. UnitPaths: string; SharedParams: TStringList; FirstRunParams: TStringList;
  58. SecondRunParams: TStringList; ExpExitCode: integer);
  59. var
  60. UnitOutputDir, JSFilename, OrigSrc, NewSrc, s: String;
  61. JSFile: TCLIFile;
  62. begin
  63. try
  64. UnitOutputDir:='units';
  65. AddDir(UnitOutputDir);
  66. // compile, create .pcu files
  67. {$IFDEF VerbosePCUFiler}
  68. writeln('TTestCLI_Precompile.CheckPrecompile create pcu files=========================');
  69. {$ENDIF}
  70. Params.Clear;
  71. if SharedParams<>nil then
  72. Params.Assign(SharedParams);
  73. if FirstRunParams<>nil then
  74. Params.AddStrings(FirstRunParams);
  75. Compile([MainFile,'-Jc','-Fu'+UnitPaths,'-JU'+Format.Ext,'-FU'+UnitOutputDir]);
  76. AssertFileExists('units/system.'+Format.Ext);
  77. JSFilename:=UnitOutputDir+PathDelim+ExtractFilenameOnly(MainFile)+'.js';
  78. AssertFileExists(JSFilename);
  79. JSFile:=FindFile(JSFilename);
  80. OrigSrc:=JSFile.Source;
  81. // compile, using .pcu files
  82. {$IFDEF VerbosePCUFiler}
  83. writeln('TTestCLI_Precompile.CheckPrecompile compile using pcu files==================');
  84. {$ENDIF}
  85. JSFile.Source:='';
  86. Compiler.Reset;
  87. Params.Clear;
  88. if SharedParams<>nil then
  89. Params.Assign(SharedParams);
  90. if SecondRunParams<>nil then
  91. Params.AddStrings(SecondRunParams);
  92. Compile([MainFile,'-Jc','-FU'+UnitOutputDir],ExpExitCode);
  93. if ExpExitCode=0 then
  94. begin
  95. NewSrc:=JSFile.Source;
  96. if not CheckSrcDiff(OrigSrc,NewSrc,s) then
  97. begin
  98. WriteSources;
  99. Fail('test1.js: '+s);
  100. end;
  101. end;
  102. finally
  103. SharedParams.Free;
  104. FirstRunParams.Free;
  105. SecondRunParams.Free;
  106. end;
  107. end;
  108. constructor TCustomTestCLI_Precompile.Create;
  109. begin
  110. inherited Create;
  111. FFormat:=PrecompileFormats.FindExt('pcu');
  112. end;
  113. { TTestCLI_Precompile }
  114. procedure TTestCLI_Precompile.TestPCU_EmptyUnit;
  115. begin
  116. AddUnit('src/system.pp',[''],['']);
  117. AddFile('test1.pas',[
  118. 'begin',
  119. 'end.']);
  120. CheckPrecompile('test1.pas','src');
  121. end;
  122. procedure TTestCLI_Precompile.TestPCU_UTF8BOM;
  123. var
  124. aFile: TCLIFile;
  125. begin
  126. aFile:=AddUnit('src/system.pp',
  127. ['var',
  128. ' s: string = ''aaaäö'';',
  129. ' s2: string = ''😊'';', // 1F60A
  130. ''],
  131. ['']);
  132. aFile.Source:=UTF8BOM+aFile.Source;
  133. aFile:=AddFile('test1.pas',[
  134. 'begin',
  135. ' s:=''ö😊'';',
  136. 'end.']);
  137. aFile.Source:=UTF8BOM+aFile.Source;
  138. CheckPrecompile('test1.pas','src');
  139. end;
  140. procedure TTestCLI_Precompile.TestPCU_ParamNS;
  141. begin
  142. AddUnit('src/system.pp',[''],['']);
  143. AddUnit('src/foo.unit1.pp',['var i: longint;'],['']);
  144. AddFile('test1.pas',[
  145. 'uses unit1;',
  146. 'begin',
  147. ' i:=3;',
  148. 'end.']);
  149. CheckPrecompile('test1.pas','src',LinesToList(['-NSfoo']));
  150. end;
  151. procedure TTestCLI_Precompile.TestPCU_Overloads;
  152. begin
  153. AddUnit('src/system.pp',['type integer = longint;'],['']);
  154. AddUnit('src/unit1.pp',
  155. ['var i: integer;',
  156. 'procedure DoIt(j: integer); overload;',
  157. 'procedure DoIt(b: boolean);'],
  158. ['procedure DoIt(j: integer);',
  159. 'begin',
  160. ' i:=j;',
  161. 'end;',
  162. 'procedure DoIt(b: boolean);',
  163. 'begin',
  164. ' i:=3;',
  165. 'end;']);
  166. AddUnit('src/unit2.pp',
  167. ['uses unit1;',
  168. 'procedure DoIt(s: string); overload;'],
  169. ['procedure DoIt(s: string);',
  170. 'begin',
  171. ' unit1.i:=length(s);',
  172. 'end;']);
  173. AddFile('test1.pas',[
  174. 'uses unit1, unit2;',
  175. 'procedure DoIt(d: double); overload;',
  176. 'begin',
  177. ' unit1.i:=4;',
  178. 'end;',
  179. 'begin',
  180. ' DoIt(3);',
  181. ' DoIt(''abc'');',
  182. ' DoIt(true);',
  183. ' DoIt(3.3);',
  184. 'end.']);
  185. CheckPrecompile('test1.pas','src');
  186. end;
  187. procedure TTestCLI_Precompile.TestPCU_UnitCycle;
  188. begin
  189. AddUnit('src/system.pp',['type integer = longint;'],['']);
  190. AddUnit('src/unit1.pp',
  191. ['var i: integer;',
  192. 'procedure Do1(j: integer);'],
  193. ['uses unit2;',
  194. 'procedure Do1(j: integer);',
  195. 'begin',
  196. ' Do2(j);',
  197. 'end;']);
  198. AddUnit('src/unit2.pp',
  199. ['uses unit1;',
  200. 'procedure Do2(j: integer);'],
  201. ['procedure Do2(j: integer);',
  202. 'begin',
  203. ' unit1.i:=j;',
  204. 'end;']);
  205. AddFile('test1.pas',[
  206. 'uses unit1;',
  207. 'begin',
  208. ' Do1(3);',
  209. 'end.']);
  210. CheckPrecompile('test1.pas','src');
  211. end;
  212. procedure TTestCLI_Precompile.TestPCU_ClassForward;
  213. begin
  214. AddUnit('src/system.pp',[
  215. 'type integer = longint;',
  216. 'procedure Writeln; varargs;'],
  217. ['procedure Writeln; begin end;']);
  218. AddUnit('src/unit1.pp',
  219. ['type',
  220. ' TClass = class of TObject;',
  221. ' TBirdClass = class of TBird;',
  222. ' TObject = class',
  223. ' FBirdClass: TBirdClass;',
  224. ' constructor Create;',
  225. ' constructor Create(Id: integer);',
  226. ' property BirdClass: TBirdClass read FBirdClass;',
  227. ' end;',
  228. ' TBird = class',
  229. ' constructor Create(d: double); overload;',
  230. ' end;',
  231. ''],
  232. ['constructor TObject.Create; begin end;',
  233. 'constructor TObject.Create(Id: integer); begin end;',
  234. 'constructor TBird.Create(d: double); begin end;']);
  235. AddFile('test1.pas',[
  236. 'uses unit1;',
  237. 'var',
  238. ' b: TBird;',
  239. ' c: TClass;',
  240. 'begin',
  241. ' c:=TObject;',
  242. ' c:=TBird;',
  243. ' c:=b.BirdClass;',
  244. ' b:=TBird.Create;',
  245. ' b:=TBird.Create(1);',
  246. ' b:=TBird.Create(3.3);',
  247. 'end.']);
  248. CheckPrecompile('test1.pas','src');
  249. end;
  250. Initialization
  251. RegisterTests([TTestCLI_Precompile]);
  252. end.