tcprecompile.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  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, fpcunit, testregistry, Pas2jsFileUtils, Pas2JsFiler,
  20. Pas2jsCompiler, Pas2JSUtils, TCUnitSearch, TCModules;
  21. type
  22. { TCustomTestCLI_Precompile }
  23. TCustomTestCLI_Precompile = class(TCustomTestCLI)
  24. private
  25. FPCUFormat: TPas2JSPrecompileFormat;
  26. FUnitOutputDir: string;
  27. protected
  28. procedure SetUp; override;
  29. procedure CheckPrecompile(MainFile, UnitPaths: string;
  30. SharedParams: TStringList = nil;
  31. FirstRunParams: TStringList = nil;
  32. SecondRunParams: TStringList = nil; ExpExitCode: integer = 0);
  33. function GetJSFilename(ModuleName: string): string; virtual;
  34. public
  35. constructor Create; override;
  36. property PCUFormat: TPas2JSPrecompileFormat read FPCUFormat write FPCUFormat;
  37. property UnitOutputDir: string read FUnitOutputDir write FUnitOutputDir;
  38. end;
  39. { TTestCLI_Precompile }
  40. TTestCLI_Precompile = class(TCustomTestCLI_Precompile)
  41. published
  42. procedure TestPCU_EmptyUnit;
  43. procedure TestPCU_UnitWithoutImplementation;
  44. procedure TestPCU_UTF8BOM;
  45. procedure TestPCU_ParamNS;
  46. procedure TestPCU_Overloads;
  47. procedure TestPCU_Overloads_MDelphi_ModeObjFPC;
  48. procedure TestPCU_UnitCycle;
  49. procedure TestPCU_Class_Forward;
  50. procedure TestPCU_Class_Constructor;
  51. procedure TestPCU_Class_ClassConstructor;
  52. procedure TestPCU_ClassInterface;
  53. procedure TestPCU_EnumNames;
  54. procedure TestPCU_Namespace;
  55. procedure TestPCU_CheckVersionMain;
  56. procedure TestPCU_CheckVersionMain2;
  57. procedure TestPCU_CheckVersionSystem;
  58. procedure TestPCU_RecordGeneric_TValueInference; // ToDo
  59. end;
  60. function LinesToList(const Lines: array of string): TStringList;
  61. implementation
  62. function LinesToList(const Lines: array of string): TStringList;
  63. var
  64. i: Integer;
  65. begin
  66. Result:=TStringList.Create;
  67. for i:=Low(Lines) to High(Lines) do Result.Add(Lines[i]);
  68. end;
  69. { TCustomTestCLI_Precompile }
  70. procedure TCustomTestCLI_Precompile.SetUp;
  71. begin
  72. inherited SetUp;
  73. UnitOutputDir:='units';
  74. end;
  75. procedure TCustomTestCLI_Precompile.CheckPrecompile(MainFile,
  76. UnitPaths: string; SharedParams: TStringList; FirstRunParams: TStringList;
  77. SecondRunParams: TStringList; ExpExitCode: integer);
  78. var
  79. JSFilename, OrigSrc, NewSrc, s: String;
  80. JSFile: TCLIFile;
  81. begin
  82. try
  83. AddDir(UnitOutputDir);
  84. // compile, create .pcu files
  85. {$IFDEF VerbosePCUFiler}
  86. writeln('TTestCLI_Precompile.CheckPrecompile create pcu files=========================');
  87. {$ENDIF}
  88. Params.Clear;
  89. Params.Add('-Jminclude');
  90. Params.Add('-Jc');
  91. if SharedParams<>nil then
  92. Params.AddStrings(SharedParams);
  93. if FirstRunParams<>nil then
  94. Params.AddStrings(FirstRunParams);
  95. Compile([MainFile,'-Fu'+UnitPaths,'-JU'+PCUFormat.Ext,'-FU'+UnitOutputDir]);
  96. AssertFileExists(UnitOutputDir+'/system.'+PCUFormat.Ext);
  97. JSFilename:=GetJSFilename(MainFile);
  98. AssertFileExists(JSFilename);
  99. JSFile:=FindFile(JSFilename);
  100. OrigSrc:=JSFile.Source;
  101. // compile, using .pcu files
  102. //for i:=0 to FileCount-1 do
  103. // writeln('TCustomTestCLI_Precompile.CheckPrecompile ',i,' ',Files[i].Filename);
  104. {$IFDEF VerbosePCUFiler}
  105. writeln('TTestCLI_Precompile.CheckPrecompile compile using pcu files==================');
  106. {$ENDIF}
  107. JSFile.Source:='';
  108. Compiler.Reset;
  109. Params.Clear;
  110. Params.Add('-Jminclude');
  111. Params.Add('-Jc');
  112. if SharedParams<>nil then
  113. Params.AddStrings(SharedParams);
  114. if SecondRunParams<>nil then
  115. Params.AddStrings(SecondRunParams);
  116. Compile([MainFile,'-FU'+UnitOutputDir],ExpExitCode);
  117. if ExpExitCode=0 then
  118. begin
  119. NewSrc:=JSFile.Source;
  120. //writeln('TCustomTestCLI_Precompile.CheckPrecompile ',NewSrc);
  121. if not CheckSrcDiff(OrigSrc,NewSrc,s) then
  122. begin
  123. WriteSources;
  124. writeln('TCustomTestCLI_Precompile.CheckPrecompile OrigSrc==================');
  125. writeln(OrigSrc);
  126. writeln('TCustomTestCLI_Precompile.CheckPrecompile NewSrc==================');
  127. writeln(NewSrc);
  128. Fail('test1.js: '+s);
  129. end;
  130. end;
  131. finally
  132. SharedParams.Free;
  133. FirstRunParams.Free;
  134. SecondRunParams.Free;
  135. end;
  136. end;
  137. function TCustomTestCLI_Precompile.GetJSFilename(ModuleName: string): string;
  138. begin
  139. Result:=UnitOutputDir+PathDelim+ExtractFilenameOnly(ModuleName)+'.js';
  140. end;
  141. constructor TCustomTestCLI_Precompile.Create;
  142. begin
  143. inherited Create;
  144. FPCUFormat:=PrecompileFormats[0];
  145. end;
  146. { TTestCLI_Precompile }
  147. procedure TTestCLI_Precompile.TestPCU_EmptyUnit;
  148. begin
  149. AddUnit('src/system.pp',[''],['']);
  150. AddFile('test1.pas',[
  151. 'begin',
  152. 'end.']);
  153. CheckPrecompile('test1.pas','src');
  154. end;
  155. procedure TTestCLI_Precompile.TestPCU_UnitWithoutImplementation;
  156. begin
  157. AddUnit('src/system.pp',[''],['']);
  158. AddFile('src/unit1.pas',
  159. 'unit unit1;'+LineEnding
  160. +'interface'+LineEnding
  161. +'end.'+LineEnding);
  162. AddFile('src/unit2.pas',
  163. 'unit unit2;'+LineEnding
  164. +'interface'+LineEnding
  165. +'uses unit1;'+LineEnding
  166. +'end.'+LineEnding);
  167. AddFile('test1.pas',[
  168. 'uses unit2;',
  169. 'begin',
  170. 'end.']);
  171. CheckPrecompile('test1.pas','src');
  172. end;
  173. procedure TTestCLI_Precompile.TestPCU_UTF8BOM;
  174. var
  175. aFile: TCLIFile;
  176. begin
  177. aFile:=AddUnit('src/system.pp',
  178. ['var',
  179. ' s: string = ''aaaäö'';',
  180. ' s2: string = ''😊'';', // 1F60A
  181. ''],
  182. ['']);
  183. aFile.Source:=UTF8BOM+aFile.Source;
  184. aFile:=AddFile('test1.pas',[
  185. 'begin',
  186. ' s:=''ö😊'';',
  187. 'end.']);
  188. aFile.Source:=UTF8BOM+aFile.Source;
  189. CheckPrecompile('test1.pas','src');
  190. end;
  191. procedure TTestCLI_Precompile.TestPCU_ParamNS;
  192. begin
  193. AddUnit('src/system.pp',[''],['']);
  194. AddUnit('src/foo.unit1.pp',['var i: longint;'],['']);
  195. AddFile('test1.pas',[
  196. 'uses unit1;',
  197. 'begin',
  198. ' i:=3;',
  199. 'end.']);
  200. CheckPrecompile('test1.pas','src',LinesToList(['-FNfoo']));
  201. end;
  202. procedure TTestCLI_Precompile.TestPCU_Overloads;
  203. begin
  204. AddUnit('src/system.pp',['type integer = longint;'],['']);
  205. AddUnit('src/unit1.pp',
  206. ['var i: integer;',
  207. 'procedure DoIt(j: integer); overload;',
  208. 'procedure DoIt(b: boolean);'],
  209. ['procedure DoIt(j: integer);',
  210. 'begin',
  211. ' i:=j;',
  212. 'end;',
  213. 'procedure DoIt(b: boolean);',
  214. 'begin',
  215. ' i:=3;',
  216. 'end;']);
  217. AddUnit('src/unit2.pp',
  218. ['uses unit1;',
  219. 'procedure DoIt(s: string); overload;'],
  220. ['procedure DoIt(s: string);',
  221. 'begin',
  222. ' unit1.i:=length(s);',
  223. 'end;']);
  224. AddFile('test1.pas',[
  225. 'uses unit1, unit2;',
  226. 'procedure DoIt(d: double); overload;',
  227. 'begin',
  228. ' unit1.i:=4;',
  229. 'end;',
  230. 'begin',
  231. ' DoIt(3);',
  232. ' DoIt(''abc'');',
  233. ' DoIt(true);',
  234. ' DoIt(3.3);',
  235. 'end.']);
  236. CheckPrecompile('test1.pas','src');
  237. end;
  238. procedure TTestCLI_Precompile.TestPCU_Overloads_MDelphi_ModeObjFPC;
  239. var
  240. SharedParams: TStringList;
  241. begin
  242. AddUnit('src/system.pp',[
  243. 'type',
  244. ' integer = longint;',
  245. ' TDateTime = type double;'],
  246. ['']);
  247. AddFile('src/unit1.pp',
  248. LinesToStr([
  249. 'unit unit1;',
  250. '{$mode objfpc}',
  251. 'interface',
  252. 'function DoIt(i: integer): TDateTime;', // no overload needed in ObjFPC
  253. 'function DoIt(i, j: integer): TDateTime;',
  254. 'implementation',
  255. 'function DoIt(i: integer): TDateTime;',
  256. 'begin',
  257. ' Result:=i;',
  258. 'end;',
  259. 'function DoIt(i, j: integer): TDateTime;',
  260. 'begin',
  261. ' Result:=i+j;',
  262. 'end;',
  263. 'end.']));
  264. AddFile('test1.pas',[
  265. 'uses unit1;',
  266. 'var d: TDateTime;',
  267. 'begin',
  268. ' d:=DoIt(3);',
  269. ' d:=DoIt(4,5);',
  270. 'end.']);
  271. SharedParams:=TStringList.Create;
  272. SharedParams.Add('-MDelphi');
  273. CheckPrecompile('test1.pas','src',SharedParams);
  274. end;
  275. procedure TTestCLI_Precompile.TestPCU_UnitCycle;
  276. begin
  277. AddUnit('src/system.pp',['type integer = longint;'],['']);
  278. AddUnit('src/unit1.pp',
  279. ['var i: integer;',
  280. 'procedure Do1(j: integer);'],
  281. ['uses unit2;',
  282. 'procedure Do1(j: integer);',
  283. 'begin',
  284. ' Do2(j);',
  285. 'end;']);
  286. AddUnit('src/unit2.pp',
  287. ['uses unit1;',
  288. 'procedure Do2(j: integer);'],
  289. ['procedure Do2(j: integer);',
  290. 'begin',
  291. ' unit1.i:=j;',
  292. 'end;']);
  293. AddFile('test1.pas',[
  294. 'uses unit1;',
  295. 'begin',
  296. ' Do1(3);',
  297. 'end.']);
  298. CheckPrecompile('test1.pas','src');
  299. end;
  300. procedure TTestCLI_Precompile.TestPCU_Class_Forward;
  301. begin
  302. AddUnit('src/system.pp',[
  303. 'type integer = longint;',
  304. 'procedure Writeln; varargs;'],
  305. ['procedure Writeln; begin end;']);
  306. AddUnit('src/unit1.pp',
  307. ['type',
  308. ' TClass = class of TObject;',
  309. ' TBirdClass = class of TBird;',
  310. ' TObject = class',
  311. ' FBirdClass: TBirdClass;',
  312. ' constructor Create;',
  313. ' constructor Create(Id: integer);',
  314. ' property BirdClass: TBirdClass read FBirdClass;',
  315. ' end;',
  316. ' TBird = class',
  317. ' constructor Create(d: double); overload;',
  318. ' end;',
  319. ''],
  320. ['constructor TObject.Create; begin end;',
  321. 'constructor TObject.Create(Id: integer); begin end;',
  322. 'constructor TBird.Create(d: double); begin end;']);
  323. AddFile('test1.pas',[
  324. 'uses unit1;',
  325. 'var',
  326. ' b: TBird;',
  327. ' c: TClass;',
  328. 'begin',
  329. ' c:=TObject;',
  330. ' c:=TBird;',
  331. ' c:=b.BirdClass;',
  332. ' b:=TBird.Create;',
  333. ' b:=TBird.Create(1);',
  334. ' b:=TBird.Create(3.3);',
  335. 'end.']);
  336. CheckPrecompile('test1.pas','src');
  337. end;
  338. procedure TTestCLI_Precompile.TestPCU_Class_Constructor;
  339. begin
  340. AddUnit('src/system.pp',[
  341. 'type integer = longint;',
  342. 'procedure Writeln; varargs;'],
  343. ['procedure Writeln; begin end;']);
  344. AddUnit('src/unit1.pp',[
  345. 'type',
  346. ' TObject = class',
  347. ' constructor Create;',
  348. ' end;',
  349. ' TBird = class',
  350. ' constructor Create; reintroduce;',
  351. ' end;',
  352. ' TCow = class',
  353. ' constructor Create; reintroduce;',
  354. ' end;',
  355. ''],[
  356. 'constructor TObject.Create; begin end;',
  357. 'constructor TBird.Create; begin end;',
  358. 'constructor TCow.Create; begin end;',
  359. '']);
  360. AddUnit('src/unit2.pp',[
  361. 'uses unit1;',
  362. 'procedure DoIt;',
  363. ''],[
  364. 'procedure DoIt;',
  365. 'begin',
  366. ' TBird.Create;',
  367. ' TCow.Create;',
  368. 'end;',
  369. '']);
  370. AddFile('test1.pas',[
  371. 'uses unit2;',
  372. 'begin',
  373. ' DoIt;',
  374. 'end.']);
  375. CheckPrecompile('test1.pas','src');
  376. end;
  377. procedure TTestCLI_Precompile.TestPCU_Class_ClassConstructor;
  378. begin
  379. AddUnit('src/system.pp',[
  380. 'type integer = longint;',
  381. 'procedure Writeln; varargs;'],
  382. ['procedure Writeln; begin end;']);
  383. AddUnit('src/unit1.pp',[
  384. 'type',
  385. ' TObject = class',
  386. ' constructor Create;',
  387. ' end;',
  388. ' TBird = class',
  389. ' class constructor InitBird;',
  390. ' end;',
  391. ''],[
  392. 'constructor TObject.Create; begin end;',
  393. 'class constructor TBird.InitBird;',
  394. 'begin',
  395. ' exit;',
  396. 'end;',
  397. '']);
  398. AddUnit('src/unit2.pp',[
  399. 'uses unit1;',
  400. 'procedure DoIt;',
  401. ''],[
  402. 'procedure DoIt;',
  403. 'begin',
  404. ' TBird.Create;',
  405. 'end;',
  406. '']);
  407. AddFile('test1.pas',[
  408. 'uses unit2;',
  409. 'begin',
  410. ' DoIt;',
  411. 'end.']);
  412. CheckPrecompile('test1.pas','src');
  413. end;
  414. procedure TTestCLI_Precompile.TestPCU_ClassInterface;
  415. begin
  416. AddUnit('src/system.pp',[
  417. '{$interfaces corba}',
  418. 'type',
  419. ' integer = longint;',
  420. ' IUnknown = interface',
  421. ' end;',
  422. 'procedure Writeln; varargs;'],
  423. ['procedure Writeln; begin end;']);
  424. AddUnit('src/unit1.pp',[
  425. 'type',
  426. ' IIntf = interface',
  427. ' function GetItems(Index: longint): longint;',
  428. ' procedure SetItems(Index: longint; Value: longint);',
  429. ' property Items[Index: longint]: longint read GetItems write SetItems; default;',
  430. ' end;',
  431. ''],[
  432. '']);
  433. AddUnit('src/unit2.pp',[
  434. 'uses unit1;',
  435. 'type',
  436. ' IAlias = IIntf;',
  437. ' TObject = class end;',
  438. ' TBird = class(IIntf)',
  439. ' strict private',
  440. ' function IIntf.GetItems = FetchItems;',
  441. ' function FetchItems(Index: longint): longint; virtual; abstract;',
  442. ' procedure SetItems(Index: longint; Value: longint); virtual; abstract;',
  443. ' end;',
  444. ''],[
  445. '']);
  446. AddUnit('src/unit3.pp',[
  447. 'uses unit2;',
  448. 'type',
  449. ' TEagle = class(TBird)',
  450. ' function FetchItems(Index: longint): longint; override;',
  451. ' procedure SetItems(Index: longint; Value: longint); override;',
  452. ' end;',
  453. ' TFlying = class(IAlias)',
  454. ' strict private',
  455. ' FEagle: TEagle;',
  456. ' property Eagle: TEagle read FEagle implements IAlias;',
  457. ' public',
  458. ' constructor Create;',
  459. ' end;',
  460. ''],[
  461. 'function TEagle.FetchItems(Index: longint): longint; begin end;',
  462. 'procedure TEagle.SetItems(Index: longint; Value: longint); begin end;',
  463. 'constructor TFlying.Create;',
  464. 'begin',
  465. ' FEagle:=nil;',
  466. 'end;',
  467. '']);
  468. AddFile('test1.pas',[
  469. 'uses unit2, unit3;',
  470. 'type IAlias2 = IAlias;',
  471. 'var',
  472. ' f: TFlying;',
  473. ' i: IAlias2;',
  474. 'begin',
  475. ' f:=TFlying.Create;',
  476. ' i:=f;',
  477. ' i[2]:=i[3];',
  478. 'end.']);
  479. CheckPrecompile('test1.pas','src');
  480. end;
  481. procedure TTestCLI_Precompile.TestPCU_EnumNames;
  482. var
  483. SharedParams: TStringList;
  484. begin
  485. AddUnit('src/system.pp',[
  486. 'type integer = longint;',
  487. ' TObject = class end;',
  488. 'procedure Writeln; varargs;'],
  489. ['procedure Writeln; begin end;']);
  490. AddUnit('src/unit1.pp',
  491. ['type',
  492. ' TEnum = (red,green,blue);',
  493. ' TBird = class ',
  494. ' private',
  495. ' Color: TEnum;',
  496. ' public',
  497. ' procedure Fly;',
  498. ' procedure Run;',
  499. ' end;',
  500. ''],
  501. ['procedure TBird.Fly;',
  502. 'begin',
  503. ' Color:=blue;',
  504. 'end;',
  505. 'procedure TBird.Run;',
  506. 'begin',
  507. ' Color:=green;',
  508. 'end;']);
  509. AddFile('test1.pas',[
  510. 'uses unit1;',
  511. 'var b: TBird;',
  512. 'begin',
  513. ' b.Fly();',
  514. ' b.Run();',
  515. 'end.']);
  516. SharedParams:=TStringList.Create;
  517. SharedParams.Add('-OoEnumNumbers-');
  518. CheckPrecompile('test1.pas','src',SharedParams);
  519. end;
  520. procedure TTestCLI_Precompile.TestPCU_Namespace;
  521. begin
  522. AddUnit('src/system.pp',[
  523. 'type integer = longint;',
  524. 'procedure Writeln; varargs;'],
  525. ['procedure Writeln; begin end;']);
  526. AddUnit('src/Web.Unit1.pp',[
  527. 'var i: integer;',
  528. ''],[
  529. '']);
  530. AddUnit('src/Unit2.pp',[
  531. 'uses WEB.uNit1;',
  532. 'procedure DoIt;',
  533. ''],[
  534. 'procedure DoIt;',
  535. 'begin',
  536. ' writeln(i);',
  537. 'end;',
  538. '']);
  539. AddFile('test1.pas',[
  540. 'uses unIT2;',
  541. 'begin',
  542. ' DoIt;',
  543. 'end.']);
  544. CheckPrecompile('test1.pas','src');
  545. AssertFileExists(UnitOutputDir+'/Unit2.'+PCUFormat.Ext);
  546. AssertFileExists(UnitOutputDir+'/Web.Unit1.'+PCUFormat.Ext);
  547. end;
  548. procedure TTestCLI_Precompile.TestPCU_CheckVersionMain;
  549. var
  550. aFile: TCLIFile;
  551. s, JSFilename, ExpectedSrc: string;
  552. begin
  553. AddUnit('src/system.pp',[
  554. 'type integer = longint;'],
  555. ['']);
  556. AddFile('test1.pas',[
  557. 'begin',
  558. 'end.']);
  559. CheckPrecompile('test1.pas','src',LinesToList(['-JoCheckVersion=Main','-Jm-','-Jc-']));
  560. JSFilename:=GetJSFilename('test1.js');
  561. aFile:=FindFile(JSFilename);
  562. AssertNotNull('File not found '+JSFilename,aFile);
  563. ExpectedSrc:=LinesToStr([
  564. UTF8BOM+'rtl.module("program",["system"],function () {',
  565. ' "use strict";',
  566. ' var $mod = this;',
  567. ' $mod.$main = function () {',
  568. ' rtl.checkVersion('+IntToStr((VersionMajor*100+VersionMinor)*100+VersionRelease)+');',
  569. ' };',
  570. '});',
  571. '']);
  572. if not CheckSrcDiff(ExpectedSrc,aFile.Source,s) then
  573. Fail('TTestCLI_Precompile.TestPCU_CheckVersionMain src diff: '+s);
  574. end;
  575. procedure TTestCLI_Precompile.TestPCU_CheckVersionMain2;
  576. var
  577. aFile: TCLIFile;
  578. s, JSFilename, ExpectedSrc: string;
  579. begin
  580. AddUnit('src/system.pp',[
  581. 'type integer = longint;',
  582. 'procedure Writeln; varargs;'],
  583. ['procedure Writeln; begin end;']);
  584. AddFile('test1.pas',[
  585. 'begin',
  586. ' Writeln;',
  587. 'end.']);
  588. CheckPrecompile('test1.pas','src',LinesToList(['-JoCheckVersion=Main','-Jm-','-Jc-']));
  589. JSFilename:=GetJSFilename('test1.js');
  590. aFile:=FindFile(JSFilename);
  591. AssertNotNull('File not found '+JSFilename,aFile);
  592. ExpectedSrc:=LinesToStr([
  593. UTF8BOM+'rtl.module("program",["system"],function () {',
  594. ' "use strict";',
  595. ' var $mod = this;',
  596. ' $mod.$main = function () {',
  597. ' rtl.checkVersion('+IntToStr((VersionMajor*100+VersionMinor)*100+VersionRelease)+');',
  598. ' pas.system.Writeln();',
  599. ' };',
  600. '});',
  601. '']);
  602. if not CheckSrcDiff(ExpectedSrc,aFile.Source,s) then
  603. Fail('TTestCLI_Precompile.TestPCU_CheckVersionMain src diff: '+s);
  604. end;
  605. procedure TTestCLI_Precompile.TestPCU_CheckVersionSystem;
  606. var
  607. aFile: TCLIFile;
  608. s, JSFilename, ExpectedSrc, VerStr: string;
  609. begin
  610. AddUnit('src/system.pp',[
  611. 'type integer = longint;'],
  612. ['']);
  613. AddFile('test1.pas',[
  614. 'begin',
  615. 'end.']);
  616. CheckPrecompile('test1.pas','src',LinesToList(['-JoCheckVersion=system','-Jm-','-Jc-']));
  617. JSFilename:=GetJSFilename('system.js');
  618. aFile:=FindFile(JSFilename);
  619. AssertNotNull('File not found '+JSFilename,aFile);
  620. writeln('TTestCLI_Precompile.TestPCU_CheckVersionMain ',aFile.Source);
  621. VerStr:=IntToStr((VersionMajor*100+VersionMinor)*100+VersionRelease);
  622. ExpectedSrc:=LinesToStr([
  623. UTF8BOM+'rtl.module("system",[],function () {',
  624. ' "use strict";',
  625. ' rtl.checkVersion('+VerStr+');',
  626. ' var $mod = this;',
  627. '});',
  628. '']);
  629. if not CheckSrcDiff(ExpectedSrc,aFile.Source,s) then
  630. Fail('TTestCLI_Precompile.TestPCU_CheckVersionMain src diff: '+s);
  631. end;
  632. procedure TTestCLI_Precompile.TestPCU_RecordGeneric_TValueInference;
  633. begin
  634. exit;
  635. AddUnit('src/system.pp',[
  636. 'type',
  637. ' integer = longint;',
  638. ' TObject = class',
  639. ' end;',
  640. ''],['']);
  641. AddUnit('src/typinfo.pas',[
  642. '{$modeswitch externalclass}',
  643. 'type',
  644. ' TTypeInfo = class external name ''rtl.tTypeInfo''',
  645. ' end;',
  646. ' TTypeInfoInteger = class external name ''rtl.tTypeInfoInteger''(TTypeInfo)',
  647. ' end;',
  648. ' PTypeInfo = Pointer;',
  649. ''],[
  650. '']);
  651. AddUnit('src/unit1.pas',[
  652. '{$modeswitch AdvancedRecords}',
  653. 'uses typinfo;',
  654. 'type',
  655. ' TValue = record',
  656. ' private',
  657. ' FTypeInfo: TTypeInfo;',
  658. ' FData: JSValue;',
  659. ' public',
  660. ' generic class function From<T>(const Value: T): TValue; static;',
  661. ' class procedure Make(ABuffer: JSValue; ATypeInfo: PTypeInfo; var Result: TValue); overload; static;',
  662. ' end;',
  663. ''],[
  664. 'generic class function TValue.From<T>(const Value: T): TValue;',
  665. 'begin',
  666. ' if Value=3 then ;',
  667. //' Make(Value, TypeInfo(T), Result);',
  668. 'end;',
  669. 'class procedure TValue.Make(ABuffer: JSValue; ATypeInfo: PTypeInfo; var Result: TValue);',
  670. 'begin',
  671. //' Result.FData := ABuffer;',
  672. //' Result.FTypeInfo := ATypeInfo;',
  673. 'end;',
  674. '']);
  675. AddFile('test1.pas',[
  676. '{$mode Delphi}',
  677. 'uses unit1;',
  678. 'begin',
  679. ' TValue.From<longint>(1234);',
  680. 'end.']);
  681. CheckPrecompile('test1.pas','src');
  682. end;
  683. Initialization
  684. RegisterTests([TTestCLI_Precompile]);
  685. RegisterPCUFormat;
  686. end.