tests.rtti.pas 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699
  1. unit tests.rtti;
  2. {$ifdef fpc}
  3. {$mode objfpc}{$H+}
  4. {$modeswitch advancedrecords}
  5. {$endif}
  6. interface
  7. uses
  8. {$IFDEF FPC}
  9. fpcunit,testregistry, testutils,
  10. {$ELSE FPC}
  11. TestFramework,
  12. {$ENDIF FPC}
  13. Classes, SysUtils, typinfo,
  14. Rtti;
  15. type
  16. { TTestCase1 }
  17. TTestCase1= class(TTestCase)
  18. published
  19. //procedure GetTypes;
  20. procedure GetTypeInteger;
  21. procedure GetTypePointer;
  22. procedure GetClassProperties;
  23. procedure GetClassPropertiesValue;
  24. procedure TestTRttiTypeProperties;
  25. procedure TestPropGetValueString;
  26. procedure TestPropGetValueInteger;
  27. procedure TestPropGetValueBoolean;
  28. procedure TestPropGetValueShortString;
  29. procedure TestPropGetValueProcString;
  30. procedure TestPropGetValueProcInteger;
  31. procedure TestPropGetValueProcBoolean;
  32. procedure TestPropGetValueProcShortString;
  33. procedure TestPropSetValueString;
  34. procedure TestPropSetValueInteger;
  35. procedure TestPropSetValueBoolean;
  36. procedure TestPropSetValueShortString;
  37. procedure TestGetValueStringCastError;
  38. procedure TestGetIsReadable;
  39. procedure TestIsWritable;
  40. procedure TestMakeNil;
  41. procedure TestMakeObject;
  42. procedure TestMakeArrayDynamic;
  43. procedure TestMakeArrayStatic;
  44. {$ifdef fpc}
  45. procedure TestMakeArrayOpen;
  46. {$endif}
  47. procedure TestDataSize;
  48. procedure TestDataSizeEmpty;
  49. procedure TestReferenceRawData;
  50. procedure TestReferenceRawDataEmpty;
  51. procedure TestIsManaged;
  52. {$ifdef fpc}
  53. procedure TestOpenArrayToDyn;
  54. {$endif}
  55. procedure TestInterface;
  56. {$ifdef fpc}
  57. procedure TestInterfaceRaw;
  58. {$endif}
  59. procedure TestProcVar;
  60. procedure TestMethod;
  61. end;
  62. implementation
  63. type
  64. {$M+}
  65. TGetClassProperties = class
  66. private
  67. FPubPropRO: integer;
  68. FPubPropRW: integer;
  69. published
  70. property PubPropRO: integer read FPubPropRO;
  71. property PubPropRW: integer read FPubPropRW write FPubPropRW;
  72. property PubPropSetRO: integer read FPubPropRO;
  73. property PubPropSetRW: integer read FPubPropRW write FPubPropRW;
  74. end;
  75. TGetClassPropertiesSub = class(TGetClassProperties)
  76. end;
  77. {$M-}
  78. { TTestValueClass }
  79. {$M+}
  80. TTestValueClass = class
  81. private
  82. FAInteger: integer;
  83. FAString: string;
  84. FABoolean: boolean;
  85. FAShortString: ShortString;
  86. function GetAInteger: integer;
  87. function GetAString: string;
  88. function GetABoolean: boolean;
  89. function GetAShortString: ShortString;
  90. procedure SetWriteOnly(AValue: integer);
  91. published
  92. property AInteger: Integer read FAInteger write FAInteger;
  93. property AString: string read FAString write FAString;
  94. property ABoolean: boolean read FABoolean write FABoolean;
  95. property AShortString: ShortString read FAShortString write FAShortString;
  96. property AGetInteger: Integer read GetAInteger;
  97. property AGetString: string read GetAString;
  98. property AGetBoolean: boolean read GetABoolean;
  99. property AGetShortString: ShortString read GetAShortString;
  100. property AWriteOnly: integer write SetWriteOnly;
  101. end;
  102. {$M-}
  103. {$M+}
  104. ITestInterface = interface
  105. procedure Test;
  106. function Test2: LongInt;
  107. procedure Test3(aArg1: LongInt; const aArg2: AnsiString; var aArg3: Boolean; out aArg4: Word);
  108. function Test4(aArg1: array of LongInt; aArg2: array of const): AnsiString;
  109. end;
  110. {$M-}
  111. TManagedRec = record
  112. s: string;
  113. end;
  114. {$ifdef fpc}
  115. TManagedRecOp = record
  116. class operator AddRef(var a: TManagedRecOp);
  117. end;
  118. {$endif}
  119. TNonManagedRec = record
  120. i: Integer;
  121. end;
  122. TManagedObj = object
  123. i: IInterface;
  124. end;
  125. TNonManagedObj = object
  126. d: double;
  127. end;
  128. TTestEnum = (te1, te2, te3, te4, te5);
  129. TTestSet = set of TTestEnum;
  130. TTestProc = procedure;
  131. TTestFunc1 = function: LongInt;
  132. TTestFunc2 = function(aArg1: LongInt; aArg2: array of LongInt): String;
  133. TTestMethod = procedure of object;
  134. TTestMethod1 = function: LongInt of object;
  135. TTestMethod2 = function(aArg1: LongInt; aArg2: array of LongInt): String of object;
  136. TTestHelper = class helper for TObject
  137. end;
  138. TArrayOfString = array[0..0] of string;
  139. TArrayOfManagedRec = array[0..0] of TManagedRec;
  140. TArrayOfNonManagedRec = array[0..0] of TNonManagedRec;
  141. TArrayOfByte = array[0..0] of byte;
  142. TArrayOfLongintDyn = array of LongInt;
  143. TArrayOfLongintStatic = array[0..3] of LongInt;
  144. TTestRecord = record
  145. Value1: LongInt;
  146. Value2: String;
  147. end;
  148. PTestRecord = ^TTestRecord;
  149. {$ifdef fpc}
  150. {$PUSH}
  151. {$INTERFACES CORBA}
  152. ICORBATest = interface
  153. end;
  154. {$POP}
  155. {$endif}
  156. {$ifdef fpc}
  157. class operator TManagedRecOp.AddRef(var a: TManagedRecOp);
  158. begin
  159. end;
  160. {$endif}
  161. { TTestValueClass }
  162. function TTestValueClass.GetAInteger: integer;
  163. begin
  164. result := FAInteger;
  165. end;
  166. function TTestValueClass.GetAString: string;
  167. begin
  168. result := FAString;
  169. end;
  170. function TTestValueClass.GetABoolean: boolean;
  171. begin
  172. result := FABoolean;
  173. end;
  174. function TTestValueClass.GetAShortString: ShortString;
  175. begin
  176. Result := FAShortString;
  177. end;
  178. procedure TTestValueClass.SetWriteOnly(AValue: integer);
  179. begin
  180. // Do nothing
  181. end;
  182. { Note: GetTypes currently only returns those types that had been acquired using
  183. GetType, so GetTypes itself can't be really tested currently }
  184. (*procedure TTestCase1.GetTypes;
  185. var
  186. LContext: TRttiContext;
  187. LType: TRttiType;
  188. IsTestCaseClassFound: boolean;
  189. begin
  190. LContext := TRttiContext.Create;
  191. { Enumerate all types declared in the application }
  192. for LType in LContext.GetTypes() do
  193. begin
  194. if LType.Name='TTestCase1' then
  195. IsTestCaseClassFound:=true;
  196. end;
  197. LContext.Free;
  198. CheckTrue(IsTestCaseClassFound, 'RTTI information does not contain class of testcase.');
  199. end;*)
  200. procedure TTestCase1.TestGetValueStringCastError;
  201. var
  202. ATestClass : TTestValueClass;
  203. c: TRttiContext;
  204. ARttiType: TRttiType;
  205. AValue: TValue;
  206. i: integer;
  207. HadException: boolean;
  208. begin
  209. c := TRttiContext.Create;
  210. try
  211. ATestClass := TTestValueClass.Create;
  212. ATestClass.AString := '12';
  213. try
  214. ARttiType := c.GetType(ATestClass.ClassInfo);
  215. AValue := ARttiType.GetProperty('astring').GetValue(ATestClass);
  216. HadException := false;
  217. try
  218. i := AValue.AsInteger;
  219. except
  220. on E: Exception do
  221. if E.ClassType=EInvalidCast then
  222. HadException := true;
  223. end;
  224. Check(HadException, 'No or invalid exception on invalid cast');
  225. finally
  226. AtestClass.Free;
  227. end;
  228. finally
  229. c.Free;
  230. end;
  231. end;
  232. procedure TTestCase1.TestMakeNil;
  233. var
  234. value: TValue;
  235. begin
  236. TValue.Make(Nil, Nil, value);
  237. CheckTrue(value.Kind = tkUnknown);
  238. CheckTrue(value.IsEmpty);
  239. CheckTrue(value.IsObject);
  240. CheckTrue(value.IsClass);
  241. CheckTrue(value.IsOrdinal);
  242. CheckFalse(value.IsArray);
  243. CheckTrue(value.AsObject = Nil);
  244. CheckTrue(value.AsClass = Nil);
  245. CheckTrue(value.AsInterface = Nil);
  246. CheckEquals(0, value.AsOrdinal);
  247. TValue.Make(Nil, TypeInfo(TObject), value);
  248. CheckTrue(value.IsEmpty);
  249. CheckTrue(value.IsObject);
  250. CheckTrue(value.IsClass);
  251. CheckTrue(value.IsOrdinal);
  252. CheckFalse(value.IsArray);
  253. CheckTrue(value.AsObject=Nil);
  254. CheckTrue(value.AsClass=Nil);
  255. CheckTrue(value.AsInterface=Nil);
  256. CheckEquals(0, value.AsOrdinal);
  257. TValue.Make(Nil, TypeInfo(TClass), value);
  258. CheckTrue(value.IsEmpty);
  259. CheckTrue(value.IsClass);
  260. CheckTrue(value.IsOrdinal);
  261. CheckFalse(value.IsArray);
  262. CheckTrue(value.AsObject=Nil);
  263. CheckTrue(value.AsClass=Nil);
  264. CheckTrue(value.AsInterface=Nil);
  265. CheckEquals(0, value.AsOrdinal);
  266. TValue.Make(Nil, TypeInfo(LongInt), value);
  267. CheckTrue(value.IsOrdinal);
  268. CheckFalse(value.IsEmpty);
  269. CheckFalse(value.IsClass);
  270. CheckFalse(value.IsObject);
  271. CheckFalse(value.IsArray);
  272. CheckEquals(0, value.AsOrdinal);
  273. CheckEquals(0, value.AsInteger);
  274. CheckEquals(0, value.AsInt64);
  275. CheckEquals(0, value.AsUInt64);
  276. TValue.Make(Nil, TypeInfo(String), value);
  277. CheckFalse(value.IsEmpty);
  278. CheckFalse(value.IsObject);
  279. CheckFalse(value.IsClass);
  280. CheckFalse(value.IsArray);
  281. CheckEquals('', value.AsString);
  282. end;
  283. procedure TTestCase1.TestMakeObject;
  284. var
  285. AValue: TValue;
  286. ATestClass: TTestValueClass;
  287. begin
  288. ATestClass := TTestValueClass.Create;
  289. ATestClass.AInteger := 54329;
  290. TValue.Make(@ATestClass, TypeInfo(TTestValueClass),AValue);
  291. CheckEquals(AValue.IsClass, False);
  292. CheckEquals(AValue.IsObject, True);
  293. Check(AValue.AsObject=ATestClass);
  294. Check(PPointer(AValue.GetReferenceToRawData)^ = Pointer(ATestClass));
  295. CheckEquals(TTestValueClass(AValue.AsObject).AInteger, 54329);
  296. ATestClass.Free;
  297. end;
  298. procedure TTestCase1.TestMakeArrayDynamic;
  299. var
  300. arr: TArrayOfLongintDyn;
  301. value: TValue;
  302. begin
  303. SetLength(arr, 2);
  304. arr[0] := 42;
  305. arr[1] := 21;
  306. TValue.Make(@arr, TypeInfo(TArrayOfLongintDyn), value);
  307. CheckEquals(value.IsArray, True);
  308. CheckEquals(value.IsObject, False);
  309. CheckEquals(value.IsOrdinal, False);
  310. CheckEquals(value.IsClass, False);
  311. CheckEquals(value.GetArrayLength, 2);
  312. CheckEquals(value.GetArrayElement(0).AsInteger, 42);
  313. CheckEquals(value.GetArrayElement(1).AsInteger, 21);
  314. Check(PPointer(value.GetReferenceToRawData)^ = Pointer(arr));
  315. value.SetArrayElement(0, 84);
  316. CheckEquals(arr[0], 84);
  317. end;
  318. procedure TTestCase1.TestMakeArrayStatic;
  319. type
  320. TArrStat = array[0..1] of LongInt;
  321. TArrStat2D = array[0..1, 0..1] of LongInt;
  322. var
  323. arr: TArrStat;
  324. arr2D: TArrStat2D;
  325. value: TValue;
  326. begin
  327. arr[0] := 42;
  328. arr[1] := 21;
  329. TValue.Make(@arr, TypeInfo(TArrStat), value);
  330. CheckEquals(value.IsArray, True);
  331. CheckEquals(value.IsObject, False);
  332. CheckEquals(value.IsOrdinal, False);
  333. CheckEquals(value.IsClass, False);
  334. CheckEquals(value.GetArrayLength, 2);
  335. CheckEquals(value.GetArrayElement(0).AsInteger, 42);
  336. CheckEquals(value.GetArrayElement(1).AsInteger, 21);
  337. value.SetArrayElement(0, 84);
  338. { since this is a static array the original array isn't touched! }
  339. CheckEquals(arr[0], 42);
  340. arr2D[0, 0] := 42;
  341. arr2D[0, 1] := 21;
  342. arr2D[1, 0] := 84;
  343. arr2D[1, 1] := 63;
  344. TValue.Make(@arr2D, TypeInfo(TArrStat2D), value);
  345. CheckEquals(value.IsArray, True);
  346. CheckEquals(value.GetArrayLength, 4);
  347. CheckEquals(value.GetArrayElement(0).AsInteger, 42);
  348. CheckEquals(value.GetArrayElement(1).AsInteger, 21);
  349. CheckEquals(value.GetArrayElement(2).AsInteger, 84);
  350. CheckEquals(value.GetArrayElement(3).AsInteger, 63);
  351. end;
  352. {$ifdef fpc}
  353. procedure TTestCase1.TestMakeArrayOpen;
  354. procedure TestOpenArrayValueCopy(aArr: array of LongInt);
  355. var
  356. value: TValue;
  357. begin
  358. TValue.MakeOpenArray(@aArr[0], Length(aArr), PTypeInfo(TypeInfo(aArr)), value);
  359. CheckEquals(value.IsArray, True);
  360. CheckEquals(value.IsOpenArray, True);
  361. CheckEquals(value.IsObject, False);
  362. CheckEquals(value.IsOrdinal, False);
  363. CheckEquals(value.IsClass, False);
  364. CheckEquals(value.GetArrayLength, 2);
  365. CheckEquals(value.GetArrayElement(0).AsInteger, 42);
  366. CheckEquals(value.GetArrayElement(1).AsInteger, 21);
  367. value.SetArrayElement(0, 84);
  368. { since this is an open array the original array is modified! }
  369. CheckEquals(aArr[0], 84);
  370. end;
  371. procedure TestOpenArrayValueVar(var aArr: array of LongInt);
  372. var
  373. value: TValue;
  374. begin
  375. TValue.MakeOpenArray(@aArr[0], Length(aArr), PTypeInfo(TypeInfo(aArr)), value);
  376. CheckEquals(value.IsArray, True);
  377. CheckEquals(value.IsOpenArray, True);
  378. CheckEquals(value.IsObject, False);
  379. CheckEquals(value.IsOrdinal, False);
  380. CheckEquals(value.IsClass, False);
  381. CheckEquals(value.GetArrayLength, 2);
  382. CheckEquals(value.GetArrayElement(0).AsInteger, 42);
  383. CheckEquals(value.GetArrayElement(1).AsInteger, 21);
  384. value.SetArrayElement(0, 84);
  385. { since this is an open array the original array is modified! }
  386. CheckEquals(aArr[0], 84);
  387. end;
  388. procedure TestOpenArrayValueOut(var aArr: array of LongInt);
  389. var
  390. value: TValue;
  391. begin
  392. TValue.MakeOpenArray(@aArr[0], Length(aArr), PTypeInfo(TypeInfo(aArr)), value);
  393. CheckEquals(value.IsArray, True);
  394. CheckEquals(value.IsOpenArray, True);
  395. CheckEquals(value.IsObject, False);
  396. CheckEquals(value.IsOrdinal, False);
  397. CheckEquals(value.IsClass, False);
  398. CheckEquals(value.GetArrayLength, 2);
  399. CheckEquals(value.GetArrayElement(0).AsInteger, 42);
  400. CheckEquals(value.GetArrayElement(1).AsInteger, 21);
  401. value.SetArrayElement(0, 84);
  402. value.SetArrayElement(1, 128);
  403. { since this is an open array the original array is modified! }
  404. CheckEquals(aArr[0], 84);
  405. CheckEquals(aArr[1], 128);
  406. CheckEquals(value.GetArrayElement(0).AsInteger, 84);
  407. CheckEquals(value.GetArrayElement(1).AsInteger, 128);
  408. end;
  409. var
  410. arr: array of LongInt;
  411. begin
  412. TestOpenArrayValueCopy([42, 21]);
  413. arr := [42, 21];
  414. TestOpenArrayValueVar(arr);
  415. CheckEquals(arr[0], 84);
  416. CheckEquals(arr[1], 21);
  417. arr := [42, 21];
  418. TestOpenArrayValueOut(arr);
  419. CheckEquals(arr[0], 84);
  420. CheckEquals(arr[1], 128);
  421. end;
  422. {$endif}
  423. procedure TTestCase1.TestGetIsReadable;
  424. var
  425. c: TRttiContext;
  426. ARttiType: TRttiType;
  427. AProperty: TRttiProperty;
  428. begin
  429. c := TRttiContext.Create;
  430. try
  431. ARttiType := c.GetType(TTestValueClass);
  432. AProperty := ARttiType.GetProperty('aBoolean');
  433. CheckEquals(AProperty.IsReadable, true);
  434. AProperty := ARttiType.GetProperty('aGetBoolean');
  435. CheckEquals(AProperty.IsReadable, true);
  436. AProperty := ARttiType.GetProperty('aWriteOnly');
  437. CheckEquals(AProperty.IsReadable, False);
  438. finally
  439. c.Free;
  440. end;
  441. end;
  442. procedure TTestCase1.TestIsWritable;
  443. var
  444. c: TRttiContext;
  445. ARttiType: TRttiType;
  446. AProperty: TRttiProperty;
  447. begin
  448. c := TRttiContext.Create;
  449. try
  450. ARttiType := c.GetType(TTestValueClass);
  451. AProperty := ARttiType.GetProperty('aBoolean');
  452. CheckEquals(AProperty.IsWritable, true);
  453. AProperty := ARttiType.GetProperty('aGetBoolean');
  454. CheckEquals(AProperty.IsWritable, false);
  455. AProperty := ARttiType.GetProperty('aWriteOnly');
  456. CheckEquals(AProperty.IsWritable, True);
  457. finally
  458. c.Free;
  459. end;
  460. end;
  461. procedure TTestCase1.TestPropGetValueBoolean;
  462. var
  463. ATestClass : TTestValueClass;
  464. c: TRttiContext;
  465. ARttiType: TRttiType;
  466. AProperty: TRttiProperty;
  467. AValue: TValue;
  468. begin
  469. c := TRttiContext.Create;
  470. try
  471. ATestClass := TTestValueClass.Create;
  472. ATestClass.ABoolean := true;
  473. try
  474. ARttiType := c.GetType(ATestClass.ClassInfo);
  475. Check(assigned(ARttiType));
  476. AProperty := ARttiType.GetProperty('aBoolean');
  477. AValue := AProperty.GetValue(ATestClass);
  478. CheckEquals(true,AValue.AsBoolean);
  479. ATestClass.ABoolean := false;
  480. CheckEquals(true, AValue.AsBoolean);
  481. CheckEquals('True', AValue.ToString);
  482. CheckEquals(True, AValue.IsOrdinal);
  483. CheckEquals(1, AValue.AsOrdinal);
  484. finally
  485. AtestClass.Free;
  486. end;
  487. CheckEquals(True,AValue.AsBoolean);
  488. finally
  489. c.Free;
  490. end;
  491. end;
  492. procedure TTestCase1.TestPropGetValueShortString;
  493. var
  494. ATestClass : TTestValueClass;
  495. c: TRttiContext;
  496. ARttiType: TRttiType;
  497. AProperty: TRttiProperty;
  498. AValue: TValue;
  499. begin
  500. c := TRttiContext.Create;
  501. try
  502. ATestClass := TTestValueClass.Create;
  503. ATestClass.AShortString := 'Hello World';
  504. try
  505. ARttiType := c.GetType(ATestClass.ClassInfo);
  506. Check(assigned(ARttiType));
  507. AProperty := ARttiType.GetProperty('aShortString');
  508. AValue := AProperty.GetValue(ATestClass);
  509. CheckEquals('Hello World',AValue.AsString);
  510. ATestClass.AShortString := 'Foobar';
  511. CheckEquals('Hello World', AValue.AsString);
  512. CheckEquals(False, AValue.IsOrdinal);
  513. CheckEquals(False, AValue.IsObject);
  514. CheckEquals(False, AValue.IsArray);
  515. CheckEquals(False, AValue.IsClass);
  516. finally
  517. AtestClass.Free;
  518. end;
  519. CheckEquals('Hello World',AValue.AsString);
  520. finally
  521. c.Free;
  522. end;
  523. end;
  524. procedure TTestCase1.TestPropGetValueInteger;
  525. var
  526. ATestClass : TTestValueClass;
  527. c: TRttiContext;
  528. ARttiType: TRttiType;
  529. AProperty: TRttiProperty;
  530. AValue: TValue;
  531. begin
  532. c := TRttiContext.Create;
  533. try
  534. ATestClass := TTestValueClass.Create;
  535. ATestClass.AInteger := 472349;
  536. try
  537. ARttiType := c.GetType(ATestClass.ClassInfo);
  538. Check(assigned(ARttiType));
  539. AProperty := ARttiType.GetProperty('ainteger');
  540. AValue := AProperty.GetValue(ATestClass);
  541. CheckEquals(472349,AValue.AsInteger);
  542. ATestClass.AInteger := 12;
  543. CheckEquals(472349, AValue.AsInteger);
  544. CheckEquals('472349', AValue.ToString);
  545. CheckEquals(True, AValue.IsOrdinal);
  546. finally
  547. AtestClass.Free;
  548. end;
  549. CheckEquals(472349,AValue.AsInteger);
  550. finally
  551. c.Free;
  552. end;
  553. end;
  554. procedure TTestCase1.TestPropGetValueString;
  555. var
  556. ATestClass : TTestValueClass;
  557. c: TRttiContext;
  558. ARttiType: TRttiType;
  559. AProperty: TRttiProperty;
  560. AValue: TValue;
  561. i: int64;
  562. begin
  563. c := TRttiContext.Create;
  564. try
  565. ATestClass := TTestValueClass.Create;
  566. ATestClass.AString := 'Hello World';
  567. try
  568. ARttiType := c.GetType(ATestClass.ClassInfo);
  569. Check(assigned(ARttiType));
  570. AProperty := ARttiType.GetProperty('astring');
  571. AValue := AProperty.GetValue(ATestClass);
  572. CheckEquals('Hello World',AValue.AsString);
  573. ATestClass.AString := 'Goodbye World';
  574. CheckEquals('Hello World',AValue.AsString);
  575. CheckEquals('Hello World',AValue.ToString);
  576. Check(TypeInfo(string)=AValue.TypeInfo);
  577. Check(AValue.TypeData=GetTypeData(AValue.TypeInfo));
  578. Check(AValue.IsEmpty=false);
  579. Check(AValue.IsObject=false);
  580. Check(AValue.IsClass=false);
  581. CheckEquals(AValue.IsOrdinal, false);
  582. CheckEquals(AValue.TryAsOrdinal(i), false);
  583. CheckEquals(AValue.IsType(TypeInfo(string)), true);
  584. CheckEquals(AValue.IsType(TypeInfo(integer)), false);
  585. CheckEquals(AValue.IsArray, false);
  586. finally
  587. AtestClass.Free;
  588. end;
  589. CheckEquals('Hello World',AValue.AsString);
  590. finally
  591. c.Free;
  592. end;
  593. end;
  594. procedure TTestCase1.TestPropGetValueProcBoolean;
  595. var
  596. ATestClass : TTestValueClass;
  597. c: TRttiContext;
  598. ARttiType: TRttiType;
  599. AProperty: TRttiProperty;
  600. AValue: TValue;
  601. begin
  602. c := TRttiContext.Create;
  603. try
  604. ATestClass := TTestValueClass.Create;
  605. ATestClass.ABoolean := true;
  606. try
  607. ARttiType := c.GetType(ATestClass.ClassInfo);
  608. Check(assigned(ARttiType));
  609. AProperty := ARttiType.GetProperty('aGetBoolean');
  610. AValue := AProperty.GetValue(ATestClass);
  611. CheckEquals(true,AValue.AsBoolean);
  612. finally
  613. AtestClass.Free;
  614. end;
  615. CheckEquals(True,AValue.AsBoolean);
  616. finally
  617. c.Free;
  618. end;
  619. end;
  620. procedure TTestCase1.TestPropGetValueProcShortString;
  621. var
  622. ATestClass : TTestValueClass;
  623. c: TRttiContext;
  624. ARttiType: TRttiType;
  625. AProperty: TRttiProperty;
  626. AValue: TValue;
  627. begin
  628. c := TRttiContext.Create;
  629. try
  630. ATestClass := TTestValueClass.Create;
  631. ATestClass.AShortString := 'Hello World';
  632. try
  633. ARttiType := c.GetType(ATestClass.ClassInfo);
  634. Check(assigned(ARttiType));
  635. AProperty := ARttiType.GetProperty('aGetShortString');
  636. AValue := AProperty.GetValue(ATestClass);
  637. CheckEquals('Hello World',AValue.AsString);
  638. finally
  639. AtestClass.Free;
  640. end;
  641. CheckEquals('Hello World',AValue.AsString);
  642. finally
  643. c.Free;
  644. end;
  645. end;
  646. procedure TTestCase1.TestPropSetValueString;
  647. var
  648. ATestClass : TTestValueClass;
  649. c: TRttiContext;
  650. ARttiType: TRttiType;
  651. AProperty: TRttiProperty;
  652. AValue: TValue;
  653. s: string;
  654. begin
  655. c := TRttiContext.Create;
  656. try
  657. ATestClass := TTestValueClass.Create;
  658. try
  659. ARttiType := c.GetType(ATestClass.ClassInfo);
  660. AProperty := ARttiType.GetProperty('astring');
  661. s := 'ipse lorem or something like that';
  662. TValue.Make(@s, TypeInfo(string), AValue);
  663. AProperty.SetValue(ATestClass, AValue);
  664. CheckEquals(ATestClass.AString, s);
  665. s := 'Another string';
  666. CheckEquals(ATestClass.AString, 'ipse lorem or something like that');
  667. finally
  668. AtestClass.Free;
  669. end;
  670. finally
  671. c.Free;
  672. end;
  673. end;
  674. procedure TTestCase1.TestPropSetValueInteger;
  675. var
  676. ATestClass : TTestValueClass;
  677. c: TRttiContext;
  678. ARttiType: TRttiType;
  679. AProperty: TRttiProperty;
  680. AValue: TValue;
  681. i: integer;
  682. begin
  683. c := TRttiContext.Create;
  684. try
  685. ATestClass := TTestValueClass.Create;
  686. try
  687. ARttiType := c.GetType(ATestClass.ClassInfo);
  688. AProperty := ARttiType.GetProperty('aInteger');
  689. i := -43573;
  690. TValue.Make(@i, TypeInfo(Integer), AValue);
  691. AProperty.SetValue(ATestClass, AValue);
  692. CheckEquals(ATestClass.AInteger, i);
  693. i := 1;
  694. CheckEquals(ATestClass.AInteger, -43573);
  695. finally
  696. AtestClass.Free;
  697. end;
  698. finally
  699. c.Free;
  700. end;
  701. end;
  702. procedure TTestCase1.TestPropSetValueBoolean;
  703. var
  704. ATestClass : TTestValueClass;
  705. c: TRttiContext;
  706. ARttiType: TRttiType;
  707. AProperty: TRttiProperty;
  708. AValue: TValue;
  709. b: boolean;
  710. begin
  711. c := TRttiContext.Create;
  712. try
  713. ATestClass := TTestValueClass.Create;
  714. try
  715. ARttiType := c.GetType(ATestClass.ClassInfo);
  716. AProperty := ARttiType.GetProperty('aboolean');
  717. b := true;
  718. TValue.Make(@b, TypeInfo(Boolean), AValue);
  719. AProperty.SetValue(ATestClass, AValue);
  720. CheckEquals(ATestClass.ABoolean, b);
  721. b := false;
  722. CheckEquals(ATestClass.ABoolean, true);
  723. TValue.Make(@b, TypeInfo(Boolean), AValue);
  724. AProperty.SetValue(ATestClass, AValue);
  725. CheckEquals(ATestClass.ABoolean, false);
  726. finally
  727. AtestClass.Free;
  728. end;
  729. finally
  730. c.Free;
  731. end;
  732. end;
  733. procedure TTestCase1.TestPropSetValueShortString;
  734. var
  735. ATestClass : TTestValueClass;
  736. c: TRttiContext;
  737. ARttiType: TRttiType;
  738. AProperty: TRttiProperty;
  739. AValue: TValue;
  740. s: string;
  741. ss: ShortString;
  742. begin
  743. c := TRttiContext.Create;
  744. try
  745. ATestClass := TTestValueClass.Create;
  746. try
  747. ARttiType := c.GetType(ATestClass.ClassInfo);
  748. AProperty := ARttiType.GetProperty('aShortString');
  749. s := 'ipse lorem or something like that';
  750. TValue.Make(@s, TypeInfo(String), AValue);
  751. AProperty.SetValue(ATestClass, AValue);
  752. CheckEquals(ATestClass.AShortString, s);
  753. s := 'Another string';
  754. CheckEquals(ATestClass.AShortString, 'ipse lorem or something like that');
  755. ss := 'Hello World';
  756. TValue.Make(@ss, TypeInfo(ShortString), AValue);
  757. AProperty.SetValue(ATestClass, AValue);
  758. CheckEquals(ATestClass.AShortString, ss);
  759. ss := 'Foobar';
  760. CheckEquals(ATestClass.AShortString, 'Hello World');
  761. finally
  762. AtestClass.Free;
  763. end;
  764. finally
  765. c.Free;
  766. end;
  767. end;
  768. procedure TTestCase1.TestPropGetValueProcInteger;
  769. var
  770. ATestClass : TTestValueClass;
  771. c: TRttiContext;
  772. ARttiType: TRttiType;
  773. AProperty: TRttiProperty;
  774. AValue: TValue;
  775. begin
  776. c := TRttiContext.Create;
  777. try
  778. ATestClass := TTestValueClass.Create;
  779. ATestClass.AInteger := 472349;
  780. try
  781. ARttiType := c.GetType(ATestClass.ClassInfo);
  782. Check(assigned(ARttiType));
  783. AProperty := ARttiType.GetProperty('agetinteger');
  784. AValue := AProperty.GetValue(ATestClass);
  785. CheckEquals(472349,AValue.AsInteger);
  786. finally
  787. AtestClass.Free;
  788. end;
  789. CheckEquals(472349,AValue.AsInteger);
  790. finally
  791. c.Free;
  792. end;
  793. end;
  794. procedure TTestCase1.TestPropGetValueProcString;
  795. var
  796. ATestClass : TTestValueClass;
  797. c: TRttiContext;
  798. ARttiType: TRttiType;
  799. AProperty: TRttiProperty;
  800. AValue: TValue;
  801. begin
  802. c := TRttiContext.Create;
  803. try
  804. ATestClass := TTestValueClass.Create;
  805. ATestClass.AString := 'Hello World';
  806. try
  807. ARttiType := c.GetType(ATestClass.ClassInfo);
  808. Check(assigned(ARttiType));
  809. AProperty := ARttiType.GetProperty('agetstring');
  810. AValue := AProperty.GetValue(ATestClass);
  811. CheckEquals('Hello World',AValue.AsString);
  812. finally
  813. AtestClass.Free;
  814. end;
  815. CheckEquals('Hello World',AValue.AsString);
  816. finally
  817. c.Free;
  818. end;
  819. end;
  820. procedure TTestCase1.TestTRttiTypeProperties;
  821. var
  822. c: TRttiContext;
  823. ARttiType: TRttiType;
  824. begin
  825. c := TRttiContext.Create;
  826. try
  827. ARttiType := c.GetType(TTestValueClass);
  828. Check(assigned(ARttiType));
  829. CheckEquals(ARttiType.Name,'TTestValueClass');
  830. Check(ARttiType.TypeKind=tkClass);
  831. // CheckEquals(ARttiType.IsPublicType,false);
  832. CheckEquals(ARttiType.TypeSize,SizeOf(TObject));
  833. CheckEquals(ARttiType.IsManaged,false);
  834. CheckEquals(ARttiType.BaseType.classname,'TRttiInstanceType');
  835. CheckEquals(ARttiType.IsInstance,True);
  836. CheckEquals(ARttiType.AsInstance.DeclaringUnitName,'tests.rtti');
  837. Check(ARttiType.BaseType.Name='TObject');
  838. Check(ARttiType.AsInstance.BaseType.Name='TObject');
  839. CheckEquals(ARttiType.IsOrdinal,False);
  840. CheckEquals(ARttiType.IsRecord,False);
  841. CheckEquals(ARttiType.IsSet,False);
  842. finally
  843. c.Free;
  844. end;
  845. end;
  846. procedure TTestCase1.GetTypeInteger;
  847. var
  848. LContext: TRttiContext;
  849. LType: TRttiType;
  850. begin
  851. LContext := TRttiContext.Create;
  852. LType := LContext.GetType(TypeInfo(integer));
  853. {$ifdef fpc}
  854. CheckEquals(LType.Name, 'LongInt');
  855. {$else}
  856. CheckEquals(LType.Name, 'Integer');
  857. {$endif}
  858. LContext.Free;
  859. end;
  860. procedure TTestCase1.GetTypePointer;
  861. var
  862. context: TRttiContext;
  863. t: TRttiType;
  864. p: TRttiPointerType absolute t;
  865. begin
  866. context := TRttiContext.Create;
  867. try
  868. t := context.GetType(TypeInfo(Pointer));
  869. Assert(t is TRttiPointerType, 'Type of Pointer is not a TRttiPointerType');
  870. Assert(not Assigned(p.ReferredType), 'ReferredType of Pointer is not Nil');
  871. t := context.GetType(TypeInfo(PLongInt));
  872. Assert(t is TRttiPointerType, 'Type of Pointer is not a TRttiPointerType');
  873. Assert(Assigned(p.ReferredType), 'ReferredType of PLongInt is Nil');
  874. Assert(p.ReferredType = context.GetType(TypeInfo(LongInt)), 'ReferredType of PLongInt is not a LongInt');
  875. t := context.GetType(TypeInfo(PWideChar));
  876. Assert(t is TRttiPointerType, 'Type of Pointer is not a TRttiPointerType');
  877. Assert(Assigned(p.ReferredType), 'ReferredType of PWideChar is Nil');
  878. Assert(p.ReferredType = context.GetType(TypeInfo(WideChar)), 'ReferredType of PWideChar is not a WideChar');
  879. finally
  880. context.Free;
  881. end;
  882. end;
  883. procedure TTestCase1.GetClassProperties;
  884. var
  885. LContext: TRttiContext;
  886. LType: TRttiType;
  887. PropList, PropList2: {$ifdef fpc}specialize{$endif} TArray<TRttiProperty>;
  888. i: LongInt;
  889. begin
  890. LContext := TRttiContext.Create;
  891. LType := LContext.GetType(TypeInfo(TGetClassProperties));
  892. PropList := LType.GetProperties;
  893. CheckEquals(4, length(PropList));
  894. CheckEquals('PubPropRO', PropList[0].Name);
  895. CheckEquals('PubPropRW', PropList[1].Name);
  896. CheckEquals('PubPropSetRO', PropList[2].Name);
  897. CheckEquals('PubPropSetRW', PropList[3].Name);
  898. LType := LContext.GetType(TypeInfo(TGetClassPropertiesSub));
  899. PropList2 := LType.GetProperties;
  900. CheckEquals(Length(PropList), Length(PropList2));
  901. for i := 0 to High(PropList) do
  902. Check(PropList[i] = PropList2[i], 'Property instances are not equal');
  903. LContext.Free;
  904. end;
  905. procedure TTestCase1.GetClassPropertiesValue;
  906. var
  907. AGetClassProperties: TGetClassProperties;
  908. LContext: TRttiContext;
  909. LType: TRttiType;
  910. AValue: TValue;
  911. begin
  912. LContext := TRttiContext.Create;
  913. LType := LContext.GetType(TGetClassProperties);
  914. AGetClassProperties := TGetClassProperties.Create;
  915. try
  916. AGetClassProperties.PubPropRW:=12345;
  917. AValue := LType.GetProperty('PubPropRW').GetValue(AGetClassProperties);
  918. CheckEquals(12345, AValue.AsInteger);
  919. finally
  920. AGetClassProperties.Free;
  921. end;
  922. LContext.Free;
  923. end;
  924. procedure TTestCase1.TestReferenceRawData;
  925. var
  926. value: TValue;
  927. str: String;
  928. intf: IInterface;
  929. i: LongInt;
  930. test: TTestRecord;
  931. arrdyn: TArrayOfLongintDyn;
  932. arrstat: TArrayOfLongintStatic;
  933. begin
  934. str := 'Hello World';
  935. UniqueString(str);
  936. TValue.Make(@str, TypeInfo(String), value);
  937. Check(PPointer(value.GetReferenceToRawData)^ = Pointer(str), 'Reference to string data differs');
  938. intf := TInterfacedObject.Create;
  939. TValue.Make(@intf, TypeInfo(IInterface), value);
  940. Check(PPointer(value.GetReferenceToRawData)^ = Pointer(intf), 'Reference to interface data differs');
  941. i := 42;
  942. TValue.Make(@i, TypeInfo(LongInt), value);
  943. Check(value.GetReferenceToRawData <> @i, 'Reference to longint is equal');
  944. Check(PLongInt(value.GetReferenceToRawData)^ = PLongInt(@i)^, 'Reference to longint data differs');
  945. test.value1 := 42;
  946. test.value2 := 'Hello World';
  947. TValue.Make(@test, TypeInfo(TTestRecord), value);
  948. Check(value.GetReferenceToRawData <> @test, 'Reference to record is equal');
  949. Check(PTestRecord(value.GetReferenceToRawData)^.value1 = PTestRecord(@test)^.value1, 'Reference to record data value1 differs');
  950. Check(PTestRecord(value.GetReferenceToRawData)^.value2 = PTestRecord(@test)^.value2, 'Reference to record data value2 differs');
  951. SetLength(arrdyn, 3);
  952. arrdyn[0] := 42;
  953. arrdyn[1] := 23;
  954. arrdyn[2] := 49;
  955. TValue.Make(@arrdyn, TypeInfo(TArrayOfLongintDyn), value);
  956. Check(PPointer(value.GetReferenceToRawData)^ = Pointer(arrdyn), 'Reference to dynamic array data differs');
  957. arrstat[0] := 42;
  958. arrstat[1] := 23;
  959. arrstat[2] := 49;
  960. arrstat[3] := 59;
  961. TValue.Make(@arrstat, TypeInfo(TArrayOfLongintStatic), value);
  962. Check(value.GetReferenceToRawData <> @arrstat, 'Reference to static array is equal');
  963. Check(PLongInt(value.GetReferenceToRawData)^ = PLongInt(@arrstat)^, 'Reference to static array data differs');
  964. end;
  965. procedure TTestCase1.TestReferenceRawDataEmpty;
  966. var
  967. value: TValue;
  968. begin
  969. TValue.Make(Nil, TypeInfo(String), value);
  970. Check(Assigned(value.GetReferenceToRawData()), 'Reference to empty String is not assigned');
  971. Check(not Assigned(PPointer(value.GetReferenceToRawData)^), 'Empty String data is assigned');
  972. TValue.Make(Nil, TypeInfo(IInterface), value);
  973. Check(Assigned(value.GetReferenceToRawData()), 'Reference to empty interface is not assigned');
  974. Check(not Assigned(PPointer(value.GetReferenceToRawData)^), 'Empty interface data is assigned');
  975. TValue.Make(Nil, TypeInfo(LongInt), value);
  976. Check(Assigned(value.GetReferenceToRawData()), 'Reference to empty LongInt is not assigned');
  977. Check(PLongInt(value.GetReferenceToRawData)^ = 0, 'Empty longint data is not 0');
  978. TValue.Make(Nil, TypeInfo(TTestRecord), value);
  979. Check(Assigned(value.GetReferenceToRawData()), 'Reference to empty record is not assigned');
  980. Check(PTestRecord(value.GetReferenceToRawData)^.value1 = 0, 'Empty record data value1 is not 0');
  981. Check(PTestRecord(value.GetReferenceToRawData)^.value2 = '', 'Empty record data value2 is not empty');
  982. TValue.Make(Nil, TypeInfo(TArrayOfLongintDyn), value);
  983. Check(Assigned(value.GetReferenceToRawData()), 'Reference to empty dynamic array is not assigned');
  984. Check(not Assigned(PPointer(value.GetReferenceToRawData)^), 'Empty dynamic array data is assigned');
  985. TValue.Make(Nil, TypeInfo(TArrayOfLongintStatic), value);
  986. Check(Assigned(value.GetReferenceToRawData()), 'Reference to empty static array is not assigned');
  987. Check(PLongInt(value.GetReferenceToRawData)^ = 0, 'Empty static array data is not 0');
  988. end;
  989. procedure TTestCase1.TestDataSize;
  990. var
  991. u8: UInt8;
  992. u16: UInt16;
  993. u32: UInt32;
  994. u64: UInt64;
  995. s8: Int8;
  996. s16: Int16;
  997. s32: Int32;
  998. s64: Int64;
  999. f32: Single;
  1000. f64: Double;
  1001. {$ifdef FPC_HAS_TYPE_EXTENDED}
  1002. f80: Extended;
  1003. {$endif}
  1004. fco: Comp;
  1005. fcu: Currency;
  1006. ss: ShortString;
  1007. sa: AnsiString;
  1008. su: UnicodeString;
  1009. sw: WideString;
  1010. o: TObject;
  1011. c: TClass;
  1012. i: IInterface;
  1013. ad: TArrayOfLongintDyn;
  1014. _as: TArrayOfLongintStatic;
  1015. b8: Boolean;
  1016. {$ifdef fpc}
  1017. b16: Boolean16;
  1018. b32: Boolean32;
  1019. b64: Boolean64;
  1020. {$endif}
  1021. bl8: ByteBool;
  1022. bl16: WordBool;
  1023. bl32: LongBool;
  1024. {$ifdef fpc}
  1025. bl64: QWordBool;
  1026. {$endif}
  1027. e: TTestEnum;
  1028. s: TTestSet;
  1029. t: TTestRecord;
  1030. p: Pointer;
  1031. proc: TTestProc;
  1032. method: TTestMethod;
  1033. value: TValue;
  1034. begin
  1035. u8:=245;
  1036. TValue.Make(@u8, TypeInfo(UInt8), value);
  1037. CheckEquals(1, value.DataSize, 'Size of UInt8 differs');
  1038. u16:=789;
  1039. TValue.Make(@u16, TypeInfo(UInt16), value);
  1040. CheckEquals(2, value.DataSize, 'Size of UInt16 differs');
  1041. u32:=568789;
  1042. TValue.Make(@u32, TypeInfo(UInt32), value);
  1043. CheckEquals(4, value.DataSize, 'Size of UInt32 differs');
  1044. u64:=$abdcefadbcef;
  1045. TValue.Make(@u64, TypeInfo(UInt64), value);
  1046. CheckEquals(8, value.DataSize, 'Size of UInt64 differs');
  1047. s8:=-32;
  1048. TValue.Make(@s8, TypeInfo(Int8), value);
  1049. CheckEquals(1, value.DataSize, 'Size of Int8 differs');
  1050. s16:=-5345;
  1051. TValue.Make(@s16, TypeInfo(Int16), value);
  1052. CheckEquals(2, value.DataSize, 'Size of Int16 differs');
  1053. s32:=-234567;
  1054. TValue.Make(@s32, TypeInfo(Int32), value);
  1055. CheckEquals(4, value.DataSize, 'Size of Int32 differs');
  1056. s64:=23456789012;
  1057. TValue.Make(@s64, TypeInfo(Int64), value);
  1058. CheckEquals(8, value.DataSize, 'Size of Int64 differs');
  1059. b8:=false;
  1060. TValue.Make(@b8, TypeInfo(Boolean), value);
  1061. CheckEquals(1, value.DataSize, 'Size of Boolean differs');
  1062. {$ifdef fpc}
  1063. b16:=true;
  1064. TValue.Make(@b16, TypeInfo(Boolean16), value);
  1065. CheckEquals(2, value.DataSize, 'Size of Boolean16 differs');
  1066. b32:=false;
  1067. TValue.Make(@b32, TypeInfo(Boolean32), value);
  1068. CheckEquals(4, value.DataSize, 'Size of Boolean32 differs');
  1069. b64:=true;
  1070. TValue.Make(@b64, TypeInfo(Boolean64), value);
  1071. CheckEquals(8, value.DataSize, 'Size of Boolean64 differs');
  1072. {$endif}
  1073. bl8:=true;
  1074. TValue.Make(@bl8, TypeInfo(ByteBool), value);
  1075. CheckEquals(1, value.DataSize, 'Size of ByteBool differs');
  1076. bl16:=false;
  1077. TValue.Make(@bl16, TypeInfo(WordBool), value);
  1078. CheckEquals(2, value.DataSize, 'Size of WordBool differs');
  1079. bl32:=false;
  1080. TValue.Make(@bl32, TypeInfo(LongBool), value);
  1081. CheckEquals(4, value.DataSize, 'Size of LongBool differs');
  1082. {$ifdef fpc}
  1083. bl64:=true;
  1084. TValue.Make(@bl64, TypeInfo(QWordBool), value);
  1085. CheckEquals(8, value.DataSize, 'Size of QWordBool differs');
  1086. {$endif}
  1087. f32:=4.567;
  1088. TValue.Make(@f32, TypeInfo(Single), value);
  1089. CheckEquals(4, value.DataSize, 'Size of Single differs');
  1090. f64:=-3456.678;
  1091. TValue.Make(@f64, TypeInfo(Double), value);
  1092. CheckEquals(8, value.DataSize, 'Size of Double differs');
  1093. {$ifdef FPC_HAS_TYPE_EXTENDED}
  1094. f80:=-2345.678;
  1095. TValue.Make(@f80, TypeInfo(Extended), value);
  1096. CheckEquals(10, value.DataSize, 'Size of Extended differs');
  1097. {$endif}
  1098. fcu:=56.78;
  1099. TValue.Make(@fcu, TypeInfo(Currency), value);
  1100. CheckEquals(SizeOf(Currency), value.DataSize, 'Size of Currency differs');
  1101. fco:=456;
  1102. TValue.Make(@fco, TypeInfo(Comp), value);
  1103. CheckEquals(SizeOf(Comp), value.DataSize, 'Size of Comp differs');
  1104. ss := '';
  1105. TValue.Make(@ss, TypeInfo(ShortString), value);
  1106. CheckEquals(254, value.DataSize, 'Size ofShortString differs');
  1107. sa:= '';
  1108. TValue.Make(@sa, TypeInfo(AnsiString), value);
  1109. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of AnsiString differs');
  1110. sw := '';
  1111. TValue.Make(@sw, TypeInfo(WideString), value);
  1112. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of WideString differs');
  1113. su:='';
  1114. TValue.Make(@su, TypeInfo(UnicodeString), value);
  1115. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of UnicodeString differs');
  1116. o := TTestValueClass.Create;
  1117. TValue.Make(@o, TypeInfo(TObject), value);
  1118. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of TObject differs');
  1119. o.Free;
  1120. c := TObject;
  1121. TValue.Make(@c, TypeInfo(TClass), value);
  1122. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of TClass differs');
  1123. i := Nil;
  1124. TValue.Make(@i, TypeInfo(IInterface), value);
  1125. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of IInterface differs');
  1126. TValue.Make(@t, TypeInfo(TTestRecord), value);
  1127. CheckEquals(SizeOf(TTestRecord), value.DataSize, 'Size of TTestRecord differs');
  1128. proc := Nil;
  1129. TValue.Make(@proc, TypeInfo(TTestProc), value);
  1130. CheckEquals(SizeOf(TTestProc), value.DataSize, 'Size of TTestProc differs');
  1131. method := Nil;
  1132. TValue.Make(@method, TypeInfo(TTestMethod), value);
  1133. CheckEquals(SizeOf(TTestMethod), value.DataSize, 'Size of TTestMethod differs');
  1134. TValue.Make(@_as, TypeInfo(TArrayOfLongintStatic), value);
  1135. CheckEquals(SizeOf(TArrayOfLongintStatic), value.DataSize, 'Size of TArrayOfLongintStatic differs');
  1136. TValue.Make(@ad, TypeInfo(TArrayOfLongintDyn), value);
  1137. CheckEquals(SizeOf(TArrayOfLongintDyn), value.DataSize, 'Size of TArrayOfLongintDyn differs');
  1138. e:=low(TTestEnum);
  1139. TValue.Make(@e, TypeInfo(TTestEnum), value);
  1140. CheckEquals(SizeOf(TTestEnum), value.DataSize, 'Size of TTestEnum differs');
  1141. s:=[low(TTestEnum),high(TTestEnum)];
  1142. TValue.Make(@s, TypeInfo(TTestSet), value);
  1143. CheckEquals(SizeOf(TTestSet), value.DataSize, 'Size of TTestSet differs');
  1144. p := Nil;
  1145. TValue.Make(@p, TypeInfo(Pointer), value);
  1146. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of Pointer differs');
  1147. end;
  1148. procedure TTestCase1.TestDataSizeEmpty;
  1149. var
  1150. value: TValue;
  1151. begin
  1152. TValue.Make(Nil, TypeInfo(UInt8), value);
  1153. CheckEquals(1, value.DataSize, 'Size of UInt8 differs');
  1154. TValue.Make(Nil, TypeInfo(UInt16), value);
  1155. CheckEquals(2, value.DataSize, 'Size of UInt16 differs');
  1156. TValue.Make(Nil, TypeInfo(UInt32), value);
  1157. CheckEquals(4, value.DataSize, 'Size of UInt32 differs');
  1158. TValue.Make(Nil, TypeInfo(UInt64), value);
  1159. CheckEquals(8, value.DataSize, 'Size of UInt64 differs');
  1160. TValue.Make(Nil, TypeInfo(Int8), value);
  1161. CheckEquals(1, value.DataSize, 'Size of Int8 differs');
  1162. TValue.Make(Nil, TypeInfo(Int16), value);
  1163. CheckEquals(2, value.DataSize, 'Size of Int16 differs');
  1164. TValue.Make(Nil, TypeInfo(Int32), value);
  1165. CheckEquals(4, value.DataSize, 'Size of Int32 differs');
  1166. TValue.Make(Nil, TypeInfo(Int64), value);
  1167. CheckEquals(8, value.DataSize, 'Size of Int64 differs');
  1168. TValue.Make(Nil, TypeInfo(Boolean), value);
  1169. CheckEquals(1, value.DataSize, 'Size of Boolean differs');
  1170. {$ifdef fpc}
  1171. TValue.Make(Nil, TypeInfo(Boolean16), value);
  1172. CheckEquals(2, value.DataSize, 'Size of Boolean16 differs');
  1173. TValue.Make(Nil, TypeInfo(Boolean32), value);
  1174. CheckEquals(4, value.DataSize, 'Size of Boolean32 differs');
  1175. TValue.Make(Nil, TypeInfo(Boolean64), value);
  1176. CheckEquals(8, value.DataSize, 'Size of Boolean64 differs');
  1177. {$endif}
  1178. TValue.Make(Nil, TypeInfo(ByteBool), value);
  1179. CheckEquals(1, value.DataSize, 'Size of ByteBool differs');
  1180. TValue.Make(Nil, TypeInfo(WordBool), value);
  1181. CheckEquals(2, value.DataSize, 'Size of WordBool differs');
  1182. TValue.Make(Nil, TypeInfo(LongBool), value);
  1183. CheckEquals(4, value.DataSize, 'Size of LongBool differs');
  1184. {$ifdef fpc}
  1185. TValue.Make(Nil, TypeInfo(QWordBool), value);
  1186. CheckEquals(8, value.DataSize, 'Size of QWordBool differs');
  1187. {$endif}
  1188. TValue.Make(Nil, TypeInfo(Single), value);
  1189. CheckEquals(4, value.DataSize, 'Size of Single differs');
  1190. TValue.Make(Nil, TypeInfo(Double), value);
  1191. CheckEquals(8, value.DataSize, 'Size of Double differs');
  1192. {$ifdef FPC_HAS_TYPE_EXTENDED}
  1193. TValue.Make(Nil, TypeInfo(Extended), value);
  1194. CheckEquals(10, value.DataSize, 'Size of Extended differs');
  1195. {$endif}
  1196. TValue.Make(Nil, TypeInfo(Currency), value);
  1197. CheckEquals(SizeOf(Currency), value.DataSize, 'Size of Currency differs');
  1198. TValue.Make(Nil, TypeInfo(Comp), value);
  1199. CheckEquals(SizeOf(Comp), value.DataSize, 'Size of Comp differs');
  1200. TValue.Make(Nil, TypeInfo(ShortString), value);
  1201. CheckEquals(254, value.DataSize, 'Size of ShortString differs');
  1202. TValue.Make(Nil, TypeInfo(AnsiString), value);
  1203. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of Pointer differs');
  1204. TValue.Make(Nil, TypeInfo(WideString), value);
  1205. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of WideString differs');
  1206. TValue.Make(Nil, TypeInfo(UnicodeString), value);
  1207. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of UnicodeString differs');
  1208. TValue.Make(Nil, TypeInfo(TObject), value);
  1209. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of TObject differs');
  1210. TValue.Make(Nil, TypeInfo(TClass), value);
  1211. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of TClass differs');
  1212. TValue.Make(Nil, TypeInfo(IInterface), value);
  1213. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of IInterface differs');
  1214. TValue.Make(Nil, TypeInfo(TTestRecord), value);
  1215. CheckEquals(SizeOf(TTestRecord), value.DataSize, 'Size of TTestRecord differs');
  1216. TValue.Make(Nil, TypeInfo(TTestProc), value);
  1217. CheckEquals(SizeOf(TTestProc), value.DataSize, 'Size of TTestProc differs');
  1218. TValue.Make(Nil, TypeInfo(TTestMethod), value);
  1219. CheckEquals(SizeOf(TTestMethod), value.DataSize, 'Size of TTestMethod differs');
  1220. TValue.Make(Nil, TypeInfo(TArrayOfLongintStatic), value);
  1221. CheckEquals(SizeOf(TArrayOfLongintStatic), value.DataSize, 'Size of TArrayOfLongintStatic differs');
  1222. TValue.Make(Nil, TypeInfo(TArrayOfLongintDyn), value);
  1223. CheckEquals(SizeOf(TArrayOfLongintDyn), value.DataSize, 'Size of TArrayOfLongintDyn differs');
  1224. TValue.Make(Nil, TypeInfo(TTestEnum), value);
  1225. CheckEquals(SizeOf(TTestEnum), value.DataSize, 'Size of TTestEnum differs');
  1226. TValue.Make(Nil, TypeInfo(TTestSet), value);
  1227. CheckEquals(SizeOf(TTestSet), value.DataSize, 'Size of TTestSet differs');
  1228. TValue.Make(Nil, TypeInfo(Pointer), value);
  1229. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of Pointer differs');
  1230. end;
  1231. procedure TTestCase1.TestIsManaged;
  1232. begin
  1233. CheckEquals(true, IsManaged(TypeInfo(ansistring)), 'IsManaged for tkAString');
  1234. CheckEquals(true, IsManaged(TypeInfo(widestring)), 'IsManaged for tkWString');
  1235. CheckEquals(true, IsManaged(TypeInfo(Variant)), 'IsManaged for tkVariant');
  1236. CheckEquals(true, IsManaged(TypeInfo(TArrayOfManagedRec)),
  1237. 'IsManaged for tkArray (with managed ElType)');
  1238. CheckEquals(true, IsManaged(TypeInfo(TArrayOfString)),
  1239. 'IsManaged for tkArray (with managed ElType)');
  1240. CheckEquals(true, IsManaged(TypeInfo(TManagedRec)), 'IsManaged for tkRecord');
  1241. {$ifdef fpc}
  1242. CheckEquals(true, IsManaged(TypeInfo(TManagedRecOp)), 'IsManaged for tkRecord');
  1243. {$endif}
  1244. CheckEquals(true, IsManaged(TypeInfo(IInterface)), 'IsManaged for tkInterface');
  1245. CheckEquals(true, IsManaged(TypeInfo(TManagedObj)), 'IsManaged for tkObject');
  1246. {$ifdef fpc}
  1247. CheckEquals(true, IsManaged(TypeInfo(specialize TArray<byte>)), 'IsManaged for tkDynArray');
  1248. {$else}
  1249. CheckEquals(true, IsManaged(TypeInfo(TArray<byte>)), 'IsManaged for tkDynArray');
  1250. {$endif}
  1251. CheckEquals(true, IsManaged(TypeInfo(unicodestring)), 'IsManaged for tkUString');
  1252. CheckEquals(false, IsManaged(TypeInfo(shortstring)), 'IsManaged for tkSString');
  1253. CheckEquals(false, IsManaged(TypeInfo(Byte)), 'IsManaged for tkInteger');
  1254. CheckEquals(false, IsManaged(TypeInfo(Char)), 'IsManaged for tkChar');
  1255. CheckEquals(false, IsManaged(TypeInfo(TTestEnum)), 'IsManaged for tkEnumeration');
  1256. CheckEquals(false, IsManaged(TypeInfo(Single)), 'IsManaged for tkFloat');
  1257. CheckEquals(false, IsManaged(TypeInfo(TTestSet)), 'IsManaged for tkSet');
  1258. {$ifdef fpc}
  1259. CheckEquals(false, IsManaged(TypeInfo(TTestMethod)), 'IsManaged for tkMethod');
  1260. {$else}
  1261. { Delphi bug (or sabotage). For some reason Delphi considers method pointers to be managed (only in newer versions, probably since XE7) :/ }
  1262. CheckEquals({$if RTLVersion>=28}true{$else}false{$endif}, IsManaged(TypeInfo(TTestMethod)), 'IsManaged for tkMethod');
  1263. {$endif}
  1264. CheckEquals(false, IsManaged(TypeInfo(TArrayOfByte)),
  1265. 'IsManaged for tkArray (with non managed ElType)');
  1266. CheckEquals(false, IsManaged(TypeInfo(TArrayOfNonManagedRec)),
  1267. 'IsManaged for tkArray (with non managed ElType)');
  1268. CheckEquals(false, IsManaged(TypeInfo(TNonManagedRec)), 'IsManaged for tkRecord');
  1269. CheckEquals(false, IsManaged(TypeInfo(TObject)), 'IsManaged for tkClass');
  1270. CheckEquals(false, IsManaged(TypeInfo(TNonManagedObj)), 'IsManaged for tkObject');
  1271. CheckEquals(false, IsManaged(TypeInfo(WideChar)), 'IsManaged for tkWChar');
  1272. CheckEquals(false, IsManaged(TypeInfo(Boolean)), 'IsManaged for tkBool');
  1273. CheckEquals(false, IsManaged(TypeInfo(Int64)), 'IsManaged for tkInt64');
  1274. CheckEquals(false, IsManaged(TypeInfo(UInt64)), 'IsManaged for tkQWord');
  1275. {$ifdef fpc}
  1276. CheckEquals(false, IsManaged(TypeInfo(ICORBATest)), 'IsManaged for tkInterfaceRaw');
  1277. {$endif}
  1278. CheckEquals(false, IsManaged(TypeInfo(TTestProc)), 'IsManaged for tkProcVar');
  1279. CheckEquals(false, IsManaged(TypeInfo(TTestHelper)), 'IsManaged for tkHelper');
  1280. {$ifdef fpc}
  1281. CheckEquals(false, IsManaged(TypeInfo(file)), 'IsManaged for tkFile');
  1282. {$endif}
  1283. CheckEquals(false, IsManaged(TypeInfo(TClass)), 'IsManaged for tkClassRef');
  1284. CheckEquals(false, IsManaged(TypeInfo(Pointer)), 'IsManaged for tkPointer');
  1285. CheckEquals(false, IsManaged(nil), 'IsManaged for nil');
  1286. end;
  1287. {$ifdef fpc}
  1288. procedure TTestCase1.TestOpenArrayToDyn;
  1289. procedure OpenArrayProc(aArr: array of LongInt);
  1290. var
  1291. value: TValue;
  1292. begin
  1293. {$ifndef InLazIDE}
  1294. value := specialize OpenArrayToDynArrayValue<LongInt>(aArr);
  1295. {$endif}
  1296. CheckEquals(value.IsArray, True);
  1297. CheckEquals(value.IsOpenArray, False);
  1298. CheckEquals(value.IsObject, False);
  1299. CheckEquals(value.IsOrdinal, False);
  1300. CheckEquals(value.IsClass, False);
  1301. CheckEquals(value.GetArrayLength, 2);
  1302. CheckEquals(value.GetArrayElement(0).AsInteger, 42);
  1303. CheckEquals(value.GetArrayElement(1).AsInteger, 84);
  1304. value.SetArrayElement(0, 21);
  1305. { since this is a copy the original array is not modified! }
  1306. CheckEquals(aArr[0], 42);
  1307. end;
  1308. begin
  1309. OpenArrayProc([42, 84]);
  1310. end;
  1311. {$endif}
  1312. procedure TTestCase1.TestInterface;
  1313. var
  1314. context: TRttiContext;
  1315. t: TRttiType;
  1316. ti1, ti2: TRttiInterfaceType;
  1317. methods: {$ifdef fpc}specialize{$endif} TArray<TRttiMethod>;
  1318. params: {$ifdef fpc}specialize{$endif} TArray<TRttiParameter>;
  1319. method: TRttiMethod;
  1320. param: TRttiParameter;
  1321. flag: TParamFlag;
  1322. begin
  1323. context := TRttiContext.Create;
  1324. try
  1325. t := context.GetType(TypeInfo(IInterface));
  1326. Check(t is TRttiInterfaceType, 'Type is not an interface type');
  1327. Check(not Assigned(t.BaseType), 'Base type is assigned');
  1328. ti1 := TRttiInterfaceType(t);
  1329. Check(not Assigned(ti1.BaseType), 'Base type is assigned');
  1330. methods := t.GetMethods;
  1331. CheckEquals(0, Length(methods), 'Overall method count does not match');
  1332. methods := t.GetDeclaredMethods;
  1333. CheckEquals(0, Length(methods), 'Declared method conut does not match');
  1334. t := context.GetType(TypeInfo(ITestInterface));
  1335. Check(t is TRttiInterfaceType, 'Type is not an interface type');
  1336. Check(Assigned(t.BaseType), 'Base type is not assigned');
  1337. Check(t.BaseType = TRttiType(ti1), 'Base type does not match');
  1338. ti2 := TRttiInterfaceType(t);
  1339. Check(Assigned(ti2.BaseType), 'Base type is not assigned');
  1340. Check(ti2.BaseType = ti1, 'Base type does not match');
  1341. methods := t.GetMethods;
  1342. CheckEquals(4, Length(methods), 'Overall method count does not match');
  1343. methods := t.GetDeclaredMethods;
  1344. CheckEquals(4, Length(methods), 'Declared method count does not match');
  1345. method := methods[0];
  1346. CheckEquals(method.Name, 'Test', 'Method name of Test does not match');
  1347. Check(method.CallingConvention = ccReg, 'Calling convention of Test does not match');
  1348. Check(method.MethodKind = mkProcedure, 'Method kind of Test does not match');
  1349. Check(method.DispatchKind = dkInterface, 'Dispatch kind of Test does not match');
  1350. Check(not Assigned(method.CodeAddress), 'Code address of Test is not Nil');
  1351. CheckEquals(method.VirtualIndex, 3, 'Virtual index of Test does not match');
  1352. Check(not Assigned(method.ReturnType), 'Return type of Test is not Nil');
  1353. params := method.GetParameters;
  1354. CheckEquals(0, Length(params), 'Parameter count of Test does not match');
  1355. method := methods[1];
  1356. CheckEquals(method.Name, 'Test2', 'Method name of Test2 does not match');
  1357. Check(method.CallingConvention = ccReg, 'Calling convention of Test2 does not match');
  1358. Check(method.MethodKind = mkFunction, 'Method kind of Test2 does not match');
  1359. Check(method.DispatchKind = dkInterface, 'Dispatch kind of Test2 does not match');
  1360. Check(not Assigned(method.CodeAddress), 'Code address of Test2 is not Nil');
  1361. CheckEquals(method.VirtualIndex, 4, 'Virtual index of Test2 does not match');
  1362. Check(Assigned(method.ReturnType), 'Return type of Test2 is Nil');
  1363. Check(method.ReturnType.TypeKind = tkInteger, 'Return type of Test2 is not an ordinal');
  1364. params := method.GetParameters;
  1365. CheckEquals(0, Length(params), 'Parameter count of Test2 does not match');
  1366. method := methods[2];
  1367. CheckEquals(method.Name, 'Test3', 'Method name of Test3 does not match');
  1368. Check(method.CallingConvention = ccReg, 'Calling convention of Test3 does not match');
  1369. Check(method.MethodKind = mkProcedure, 'Method kind of Test3 does not match');
  1370. Check(method.DispatchKind = dkInterface, 'Dispatch kind of Test3 does not match');
  1371. Check(not Assigned(method.CodeAddress), 'Code address of Test3 is not Nil');
  1372. CheckEquals(method.VirtualIndex, 5, 'Virtual index of Test3 does not match');
  1373. Check(not Assigned(method.ReturnType), 'Return type of Test3 is not Nil');
  1374. params := method.GetParameters;
  1375. CheckEquals(4, Length(params), 'Parameter count of Test3 does not match');
  1376. param := params[0];
  1377. CheckEquals(param.Name, 'aArg1', 'Parameter name of Test3.aArg1 does not match');
  1378. Check(param.Flags = [], 'Parameter flags of Test3.aArg1 do not match');
  1379. Check(Assigned(param.ParamType), 'Parameter type of Test3.aArg1 is Nil');
  1380. Check(param.ParamType.TypeKind = tkInteger, 'Parameter type of Test3.aArg1 is not an ordinal');
  1381. param := params[1];
  1382. CheckEquals(param.Name, 'aArg2', 'Parameter name of Test3.aArg2 does not match');
  1383. Check(param.Flags = [pfConst], 'Parameter flags of Test3.aArg2 do not match');
  1384. Check(Assigned(param.ParamType), 'Parameter type of Test3.aArg2 is Nil');
  1385. Check(param.ParamType.TypeKind = tkAnsiString, 'Parameter type of Test3.aArg2 is not a string');
  1386. param := params[2];
  1387. CheckEquals(param.Name, 'aArg3', 'Parameter name of Test3.aArg3 does not match');
  1388. Check(param.Flags = [pfVar], 'Parameter flags of Test3.aArg3 do not match');
  1389. Check(Assigned(param.ParamType), 'Parameter type of Test3.aArg3 is Nil');
  1390. Check(param.ParamType.TypeKind = {$ifdef fpc}tkBool{$else}tkEnumeration{$endif}, 'Parameter type of Test3.aArg3 is not a boolean');
  1391. param := params[3];
  1392. CheckEquals(param.Name, 'aArg4', 'Parameter name of Test3.aArg4 does not match');
  1393. Check(param.Flags = [pfOut], 'Parameter flags of Test3.aArg4 do not match');
  1394. Check(Assigned(param.ParamType), 'Parameter type of Test3.aArg4 is Nil');
  1395. Check(param.ParamType.TypeKind = tkInteger, 'Parameter type of Test3.aArg4 is not a string');
  1396. method := methods[3];
  1397. CheckEquals(method.Name, 'Test4', 'Method name of Test4 does not match');
  1398. Check(method.CallingConvention = ccReg, 'Calling convention of Test4 does not match');
  1399. Check(method.MethodKind = mkFunction, 'Method kind of Test4 does not match');
  1400. Check(method.DispatchKind = dkInterface, 'Dispatch kind of Test4 does not match');
  1401. Check(not Assigned(method.CodeAddress), 'Code address of Test4 is not Nil');
  1402. CheckEquals(method.VirtualIndex, 6, 'Virtual index of Test4 does not match');
  1403. Check(Assigned(method.ReturnType), 'Return type of Test4 is not Nil');
  1404. Check(method.ReturnType.TypeKind = tkAnsiString, 'Return type of Test4 is not a string');
  1405. params := method.GetParameters;
  1406. CheckEquals(2, Length(params), 'Parameter count of Test4 does not match');
  1407. param := params[0];
  1408. CheckEquals(param.Name, 'aArg1', 'Parameter name of Test4.aArg1 does not match');
  1409. Check(param.Flags = [pfArray, pfReference], 'Parameter flags of Test4.aArg1 do not match');
  1410. Check(Assigned(param.ParamType), 'Parameter type of Test4.aArg1 is Nil');
  1411. Check(param.ParamType.TypeKind = tkInteger, 'Parameter type of Test4.aArg1 is not an ordinal');
  1412. param := params[1];
  1413. CheckEquals(param.Name, 'aArg2', 'Parameter name of Test4.aArg2 does not match');
  1414. Check(param.Flags = [pfArray, pfReference], 'Parameter flags of Test4.aArg2 do not match');
  1415. Check(Assigned(param.ParamType), 'Parameter type of Test4.aArg2 is Nil');
  1416. Check(param.ParamType.TypeKind = tkRecord, 'Parameter type of Test4.aArg2 is not a record');
  1417. finally
  1418. context.Free;
  1419. end;
  1420. end;
  1421. {$ifdef fpc}
  1422. procedure TTestCase1.TestInterfaceRaw;
  1423. var
  1424. context: TRttiContext;
  1425. t: TRttiType;
  1426. ti: TRttiInterfaceType;
  1427. begin
  1428. context := TRttiContext.Create;
  1429. try
  1430. t := context.GetType(TypeInfo(ICORBATest));
  1431. Check(t is TRttiInterfaceType, 'Type is not a raw interface type');
  1432. Check(not Assigned(t.BaseType), 'Base type is assigned');
  1433. ti := TRttiInterfaceType(t);
  1434. Check(not Assigned(ti.BaseType), 'Base type is assigned');
  1435. finally
  1436. context.Free;
  1437. end;
  1438. end;
  1439. procedure TTestCase1.TestProcVar;
  1440. var
  1441. context: TRttiContext;
  1442. t: TRttiType;
  1443. p: TRttiProcedureType;
  1444. params: {$ifdef fpc}specialize{$endif} TArray<TRttiParameter>;
  1445. begin
  1446. context := TRttiContext.Create;
  1447. try
  1448. t := context.GetType(PTypeInfo(TypeInfo(TTestProc)));
  1449. Check(Assigned(t), 'Rtti Type is Nil');
  1450. Check(t is TRttiInvokableType, 'Rtti Type is not an invokeable');
  1451. Check(t is TRttiProcedureType, 'Rtti Type is not a procedure type');
  1452. p := t as TRttiProcedureType;
  1453. Check(p.CallingConvention = ccReg, 'Calling convention does not match');
  1454. Check(not Assigned(p.ReturnType), 'Return type is assigned');
  1455. CheckEquals(0, Length(p.GetParameters), 'Procedure variable has parameters');
  1456. t := context.GetType(PTypeInfo(TypeInfo(TTestFunc1)));
  1457. Check(Assigned(t), 'Rtti Type is Nil');
  1458. Check(t is TRttiInvokableType, 'Rtti Type is not an invokeable');
  1459. Check(t is TRttiProcedureType, 'Rtti Type is not a procedure type');
  1460. p := t as TRttiProcedureType;
  1461. Check(p.CallingConvention = ccReg, 'Calling convention does not match');
  1462. Check(Assigned(p.ReturnType), 'Return type is not assigned');
  1463. //Check(p.ReturnType is TRttiOrdinalType, 'Return type is not an ordinal type');
  1464. CheckEquals(0, Length(p.GetParameters), 'Procedure variable has parameters');
  1465. t := context.GetType(PTypeInfo(TypeInfo(TTestFunc2)));
  1466. Check(Assigned(t), 'Rtti Type is Nil');
  1467. Check(t is TRttiInvokableType, 'Rtti Type is not an invokeable');
  1468. Check(t is TRttiProcedureType, 'Rtti Type is not a procedure type');
  1469. p := t as TRttiProcedureType;
  1470. Check(p.CallingConvention = ccReg, 'Calling convention does not match');
  1471. Check(Assigned(p.ReturnType), 'Return type is not assigned');
  1472. Check(p.ReturnType is TRttiStringType, 'Return type is not a string type');
  1473. params := p.GetParameters;
  1474. CheckEquals(2, Length(params), 'Procedure variable has incorrect amount of parameters');
  1475. Check(params[0].ParamType.TypeKind in [tkInteger, tkInt64], 'Parameter 1 is not an ordinal type');
  1476. //Check(params[0].ParamType is TRttiOrdinalType, 'Parameter 1 is not an ordinal type');
  1477. Check(pfArray in params[1].Flags, 'Parameter 2 is not an array');
  1478. Check(params[1].ParamType.TypeKind in [tkInteger, tkInt64], 'Parameter 2 is not an ordinal array');
  1479. finally
  1480. context.Free;
  1481. end;
  1482. end;
  1483. procedure TTestCase1.TestMethod;
  1484. var
  1485. context: TRttiContext;
  1486. t: TRttiType;
  1487. m: TRttiMethodType;
  1488. params: {$ifdef fpc}specialize{$endif} TArray<TRttiParameter>;
  1489. begin
  1490. context := TRttiContext.Create;
  1491. try
  1492. t := context.GetType(PTypeInfo(TypeInfo(TTestMethod)));
  1493. Check(Assigned(t), 'Rtti Type is Nil');
  1494. Check(t is TRttiInvokableType, 'Rtti Type is not an invokeable');
  1495. Check(t is TRttiMethodType, 'Rtti Type is not a method type');
  1496. m := t as TRttiMethodType;
  1497. Check(m.CallingConvention = ccReg, 'Calling convention does not match');
  1498. Check(not Assigned(m.ReturnType), 'Return type is assigned');
  1499. CheckEquals(0, Length(m.GetParameters), 'Method variable has parameters');
  1500. t := context.GetType(PTypeInfo(TypeInfo(TTestMethod1)));
  1501. Check(Assigned(t), 'Rtti Type is Nil');
  1502. Check(t is TRttiInvokableType, 'Rtti Type is not an invokeable');
  1503. Check(t is TRttiMethodType, 'Rtti Type is not a method type');
  1504. m := t as TRttiMethodType;
  1505. Check(m.CallingConvention = ccReg, 'Calling convention does not match');
  1506. Check(Assigned(m.ReturnType), 'Return type is not assigned');
  1507. //Check(p.ReturnType is TRttiOrdinalType, 'Return type is not an ordinal type');
  1508. CheckEquals(0, Length(m.GetParameters), 'Method variable has parameters');
  1509. t := context.GetType(PTypeInfo(TypeInfo(TTestMethod2)));
  1510. Check(Assigned(t), 'Rtti Type is Nil');
  1511. Check(t is TRttiInvokableType, 'Rtti Type is not an invokeable');
  1512. Check(t is TRttiMethodType, 'Rtti Type is not a method type');
  1513. m := t as TRttiMethodType;
  1514. Check(m.CallingConvention = ccReg, 'Calling convention does not match');
  1515. Check(Assigned(m.ReturnType), 'Return type is not assigned');
  1516. Check(m.ReturnType is TRttiStringType, 'Return type is not a string type');
  1517. params := m.GetParameters;
  1518. CheckEquals(2, Length(params), 'Method variable has incorrect amount of parameters');
  1519. Check(params[0].ParamType.TypeKind in [tkInteger, tkInt64], 'Parameter 1 is not an ordinal type');
  1520. //Check(params[0].ParamType is TRttiOrdinalType, 'Parameter 1 is not an ordinal type');
  1521. Check(pfArray in params[1].Flags, 'Parameter 2 is not an array');
  1522. Check(params[1].ParamType.TypeKind in [tkInteger, tkInt64], 'Parameter 2 is not an ordinal array');
  1523. finally
  1524. context.Free;
  1525. end;
  1526. end;
  1527. {$endif}
  1528. initialization
  1529. {$ifdef fpc}
  1530. RegisterTest(TTestCase1);
  1531. {$else fpc}
  1532. RegisterTest(TTestCase1.Suite);
  1533. {$endif fpc}
  1534. end.