tests.rtti.pas 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242
  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 GetClassProperties;
  22. procedure GetClassPropertiesValue;
  23. procedure TestTRttiTypeProperties;
  24. procedure TestPropGetValueString;
  25. procedure TestPropGetValueInteger;
  26. procedure TestPropGetValueBoolean;
  27. procedure TestPropGetValueShortString;
  28. procedure TestPropGetValueProcString;
  29. procedure TestPropGetValueProcInteger;
  30. procedure TestPropGetValueProcBoolean;
  31. procedure TestPropGetValueProcShortString;
  32. procedure TestPropSetValueString;
  33. procedure TestPropSetValueInteger;
  34. procedure TestPropSetValueBoolean;
  35. procedure TestPropSetValueShortString;
  36. procedure TestGetValueStringCastError;
  37. procedure TestGetIsReadable;
  38. procedure TestIsWritable;
  39. procedure TestMakeNil;
  40. procedure TestMakeObject;
  41. procedure TestMakeArrayDynamic;
  42. procedure TestMakeArrayStatic;
  43. procedure TestDataSize;
  44. procedure TestDataSizeEmpty;
  45. procedure TestReferenceRawData;
  46. procedure TestReferenceRawDataEmpty;
  47. procedure TestIsManaged;
  48. end;
  49. implementation
  50. type
  51. {$M+}
  52. TGetClassProperties = class
  53. private
  54. FPubPropRO: integer;
  55. FPubPropRW: integer;
  56. published
  57. property PubPropRO: integer read FPubPropRO;
  58. property PubPropRW: integer read FPubPropRW write FPubPropRW;
  59. property PubPropSetRO: integer read FPubPropRO;
  60. property PubPropSetRW: integer read FPubPropRW write FPubPropRW;
  61. end;
  62. {$M-}
  63. { TTestValueClass }
  64. {$M+}
  65. TTestValueClass = class
  66. private
  67. FAInteger: integer;
  68. FAString: string;
  69. FABoolean: boolean;
  70. FAShortString: ShortString;
  71. function GetAInteger: integer;
  72. function GetAString: string;
  73. function GetABoolean: boolean;
  74. function GetAShortString: ShortString;
  75. procedure SetWriteOnly(AValue: integer);
  76. published
  77. property AInteger: Integer read FAInteger write FAInteger;
  78. property AString: string read FAString write FAString;
  79. property ABoolean: boolean read FABoolean write FABoolean;
  80. property AShortString: ShortString read FAShortString write FAShortString;
  81. property AGetInteger: Integer read GetAInteger;
  82. property AGetString: string read GetAString;
  83. property AGetBoolean: boolean read GetABoolean;
  84. property AGetShortString: ShortString read GetAShortString;
  85. property AWriteOnly: integer write SetWriteOnly;
  86. end;
  87. {$M-}
  88. TManagedRec = record
  89. s: string;
  90. end;
  91. {$ifdef fpc}
  92. TManagedRecOp = record
  93. class operator AddRef(var a: TManagedRecOp);
  94. end;
  95. {$endif}
  96. TNonManagedRec = record
  97. i: Integer;
  98. end;
  99. TManagedObj = object
  100. i: IInterface;
  101. end;
  102. TNonManagedObj = object
  103. d: double;
  104. end;
  105. TTestEnum = (te1, te2, te3, te4, te5);
  106. TTestSet = set of TTestEnum;
  107. TTestProc = procedure;
  108. TTestMethod = procedure of object;
  109. TTestHelper = class helper for TObject
  110. end;
  111. TArrayOfString = array[0..0] of string;
  112. TArrayOfManagedRec = array[0..0] of TManagedRec;
  113. TArrayOfNonManagedRec = array[0..0] of TNonManagedRec;
  114. TArrayOfByte = array[0..0] of byte;
  115. TArrayOfLongintDyn = array of LongInt;
  116. TArrayOfLongintStatic = array[0..3] of LongInt;
  117. TTestRecord = record
  118. Value1: LongInt;
  119. Value2: String;
  120. end;
  121. PTestRecord = ^TTestRecord;
  122. {$ifdef fpc}
  123. {$PUSH}
  124. {$INTERFACES CORBA}
  125. ICORBATest = interface
  126. end;
  127. {$POP}
  128. {$endif}
  129. {$ifdef fpc}
  130. class operator TManagedRecOp.AddRef(var a: TManagedRecOp);
  131. begin
  132. end;
  133. {$endif}
  134. { TTestValueClass }
  135. function TTestValueClass.GetAInteger: integer;
  136. begin
  137. result := FAInteger;
  138. end;
  139. function TTestValueClass.GetAString: string;
  140. begin
  141. result := FAString;
  142. end;
  143. function TTestValueClass.GetABoolean: boolean;
  144. begin
  145. result := FABoolean;
  146. end;
  147. function TTestValueClass.GetAShortString: ShortString;
  148. begin
  149. Result := FAShortString;
  150. end;
  151. procedure TTestValueClass.SetWriteOnly(AValue: integer);
  152. begin
  153. // Do nothing
  154. end;
  155. { Note: GetTypes currently only returns those types that had been acquired using
  156. GetType, so GetTypes itself can't be really tested currently }
  157. (*procedure TTestCase1.GetTypes;
  158. var
  159. LContext: TRttiContext;
  160. LType: TRttiType;
  161. IsTestCaseClassFound: boolean;
  162. begin
  163. LContext := TRttiContext.Create;
  164. { Enumerate all types declared in the application }
  165. for LType in LContext.GetTypes() do
  166. begin
  167. if LType.Name='TTestCase1' then
  168. IsTestCaseClassFound:=true;
  169. end;
  170. LContext.Free;
  171. CheckTrue(IsTestCaseClassFound, 'RTTI information does not contain class of testcase.');
  172. end;*)
  173. procedure TTestCase1.TestGetValueStringCastError;
  174. var
  175. ATestClass : TTestValueClass;
  176. c: TRttiContext;
  177. ARttiType: TRttiType;
  178. AValue: TValue;
  179. i: integer;
  180. HadException: boolean;
  181. begin
  182. c := TRttiContext.Create;
  183. try
  184. ATestClass := TTestValueClass.Create;
  185. ATestClass.AString := '12';
  186. try
  187. ARttiType := c.GetType(ATestClass.ClassInfo);
  188. AValue := ARttiType.GetProperty('astring').GetValue(ATestClass);
  189. HadException := false;
  190. try
  191. i := AValue.AsInteger;
  192. except
  193. on E: Exception do
  194. if E.ClassType=EInvalidCast then
  195. HadException := true;
  196. end;
  197. Check(HadException, 'No or invalid exception on invalid cast');
  198. finally
  199. AtestClass.Free;
  200. end;
  201. finally
  202. c.Free;
  203. end;
  204. end;
  205. procedure TTestCase1.TestMakeNil;
  206. var
  207. value: TValue;
  208. begin
  209. TValue.Make(Nil, Nil, value);
  210. CheckTrue(value.Kind = tkUnknown);
  211. CheckTrue(value.IsEmpty);
  212. CheckTrue(value.IsObject);
  213. CheckTrue(value.IsClass);
  214. CheckTrue(value.IsOrdinal);
  215. CheckFalse(value.IsArray);
  216. CheckTrue(value.AsObject = Nil);
  217. CheckTrue(value.AsClass = Nil);
  218. CheckTrue(value.AsInterface = Nil);
  219. CheckEquals(0, value.AsOrdinal);
  220. TValue.Make(Nil, TypeInfo(TObject), value);
  221. CheckTrue(value.IsEmpty);
  222. CheckTrue(value.IsObject);
  223. CheckTrue(value.IsClass);
  224. CheckTrue(value.IsOrdinal);
  225. CheckFalse(value.IsArray);
  226. CheckTrue(value.AsObject=Nil);
  227. CheckTrue(value.AsClass=Nil);
  228. CheckTrue(value.AsInterface=Nil);
  229. CheckEquals(0, value.AsOrdinal);
  230. TValue.Make(Nil, TypeInfo(TClass), value);
  231. CheckTrue(value.IsEmpty);
  232. CheckTrue(value.IsClass);
  233. CheckTrue(value.IsOrdinal);
  234. CheckFalse(value.IsArray);
  235. CheckTrue(value.AsObject=Nil);
  236. CheckTrue(value.AsClass=Nil);
  237. CheckTrue(value.AsInterface=Nil);
  238. CheckEquals(0, value.AsOrdinal);
  239. TValue.Make(Nil, TypeInfo(LongInt), value);
  240. CheckTrue(value.IsOrdinal);
  241. CheckFalse(value.IsEmpty);
  242. CheckFalse(value.IsClass);
  243. CheckFalse(value.IsObject);
  244. CheckFalse(value.IsArray);
  245. CheckEquals(0, value.AsOrdinal);
  246. CheckEquals(0, value.AsInteger);
  247. CheckEquals(0, value.AsInt64);
  248. CheckEquals(0, value.AsUInt64);
  249. TValue.Make(Nil, TypeInfo(String), value);
  250. CheckFalse(value.IsEmpty);
  251. CheckFalse(value.IsObject);
  252. CheckFalse(value.IsClass);
  253. CheckFalse(value.IsArray);
  254. CheckEquals('', value.AsString);
  255. end;
  256. procedure TTestCase1.TestMakeObject;
  257. var
  258. AValue: TValue;
  259. ATestClass: TTestValueClass;
  260. begin
  261. ATestClass := TTestValueClass.Create;
  262. ATestClass.AInteger := 54329;
  263. TValue.Make(@ATestClass, TypeInfo(TTestValueClass),AValue);
  264. CheckEquals(AValue.IsClass, False);
  265. CheckEquals(AValue.IsObject, True);
  266. Check(AValue.AsObject=ATestClass);
  267. CheckEquals(TTestValueClass(AValue.AsObject).AInteger, 54329);
  268. ATestClass.Free;
  269. end;
  270. procedure TTestCase1.TestMakeArrayDynamic;
  271. var
  272. arr: TArrayOfLongintDyn;
  273. value: TValue;
  274. begin
  275. SetLength(arr, 2);
  276. arr[0] := 42;
  277. arr[1] := 21;
  278. TValue.Make(@arr, TypeInfo(TArrayOfLongintDyn), value);
  279. CheckEquals(value.IsArray, True);
  280. CheckEquals(value.IsObject, False);
  281. CheckEquals(value.IsOrdinal, False);
  282. CheckEquals(value.IsClass, False);
  283. CheckEquals(value.GetArrayLength, 2);
  284. CheckEquals(value.GetArrayElement(0).AsInteger, 42);
  285. CheckEquals(value.GetArrayElement(1).AsInteger, 21);
  286. value.SetArrayElement(0, 84);
  287. CheckEquals(arr[0], 84);
  288. end;
  289. procedure TTestCase1.TestMakeArrayStatic;
  290. type
  291. TArrStat = array[0..1] of LongInt;
  292. TArrStat2D = array[0..1, 0..1] of LongInt;
  293. var
  294. arr: TArrStat;
  295. arr2D: TArrStat2D;
  296. value: TValue;
  297. begin
  298. arr[0] := 42;
  299. arr[1] := 21;
  300. TValue.Make(@arr, TypeInfo(TArrStat), value);
  301. CheckEquals(value.IsArray, True);
  302. CheckEquals(value.IsObject, False);
  303. CheckEquals(value.IsOrdinal, False);
  304. CheckEquals(value.IsClass, False);
  305. CheckEquals(value.GetArrayLength, 2);
  306. CheckEquals(value.GetArrayElement(0).AsInteger, 42);
  307. CheckEquals(value.GetArrayElement(1).AsInteger, 21);
  308. value.SetArrayElement(0, 84);
  309. { since this is a static array the original array isn't touched! }
  310. CheckEquals(arr[0], 42);
  311. arr2D[0, 0] := 42;
  312. arr2D[0, 1] := 21;
  313. arr2D[1, 0] := 84;
  314. arr2D[1, 1] := 63;
  315. TValue.Make(@arr2D, TypeInfo(TArrStat2D), value);
  316. CheckEquals(value.IsArray, True);
  317. CheckEquals(value.GetArrayLength, 4);
  318. CheckEquals(value.GetArrayElement(0).AsInteger, 42);
  319. CheckEquals(value.GetArrayElement(1).AsInteger, 21);
  320. CheckEquals(value.GetArrayElement(2).AsInteger, 84);
  321. CheckEquals(value.GetArrayElement(3).AsInteger, 63);
  322. end;
  323. procedure TTestCase1.TestGetIsReadable;
  324. var
  325. c: TRttiContext;
  326. ARttiType: TRttiType;
  327. AProperty: TRttiProperty;
  328. begin
  329. c := TRttiContext.Create;
  330. try
  331. ARttiType := c.GetType(TTestValueClass);
  332. AProperty := ARttiType.GetProperty('aBoolean');
  333. CheckEquals(AProperty.IsReadable, true);
  334. AProperty := ARttiType.GetProperty('aGetBoolean');
  335. CheckEquals(AProperty.IsReadable, true);
  336. AProperty := ARttiType.GetProperty('aWriteOnly');
  337. CheckEquals(AProperty.IsReadable, False);
  338. finally
  339. c.Free;
  340. end;
  341. end;
  342. procedure TTestCase1.TestIsWritable;
  343. var
  344. c: TRttiContext;
  345. ARttiType: TRttiType;
  346. AProperty: TRttiProperty;
  347. begin
  348. c := TRttiContext.Create;
  349. try
  350. ARttiType := c.GetType(TTestValueClass);
  351. AProperty := ARttiType.GetProperty('aBoolean');
  352. CheckEquals(AProperty.IsWritable, true);
  353. AProperty := ARttiType.GetProperty('aGetBoolean');
  354. CheckEquals(AProperty.IsWritable, false);
  355. AProperty := ARttiType.GetProperty('aWriteOnly');
  356. CheckEquals(AProperty.IsWritable, True);
  357. finally
  358. c.Free;
  359. end;
  360. end;
  361. procedure TTestCase1.TestPropGetValueBoolean;
  362. var
  363. ATestClass : TTestValueClass;
  364. c: TRttiContext;
  365. ARttiType: TRttiType;
  366. AProperty: TRttiProperty;
  367. AValue: TValue;
  368. begin
  369. c := TRttiContext.Create;
  370. try
  371. ATestClass := TTestValueClass.Create;
  372. ATestClass.ABoolean := true;
  373. try
  374. ARttiType := c.GetType(ATestClass.ClassInfo);
  375. Check(assigned(ARttiType));
  376. AProperty := ARttiType.GetProperty('aBoolean');
  377. AValue := AProperty.GetValue(ATestClass);
  378. CheckEquals(true,AValue.AsBoolean);
  379. ATestClass.ABoolean := false;
  380. CheckEquals(true, AValue.AsBoolean);
  381. CheckEquals('True', AValue.ToString);
  382. CheckEquals(True, AValue.IsOrdinal);
  383. CheckEquals(1, AValue.AsOrdinal);
  384. finally
  385. AtestClass.Free;
  386. end;
  387. CheckEquals(True,AValue.AsBoolean);
  388. finally
  389. c.Free;
  390. end;
  391. end;
  392. procedure TTestCase1.TestPropGetValueShortString;
  393. var
  394. ATestClass : TTestValueClass;
  395. c: TRttiContext;
  396. ARttiType: TRttiType;
  397. AProperty: TRttiProperty;
  398. AValue: TValue;
  399. begin
  400. c := TRttiContext.Create;
  401. try
  402. ATestClass := TTestValueClass.Create;
  403. ATestClass.AShortString := 'Hello World';
  404. try
  405. ARttiType := c.GetType(ATestClass.ClassInfo);
  406. Check(assigned(ARttiType));
  407. AProperty := ARttiType.GetProperty('aShortString');
  408. AValue := AProperty.GetValue(ATestClass);
  409. CheckEquals('Hello World',AValue.AsString);
  410. ATestClass.AShortString := 'Foobar';
  411. CheckEquals('Hello World', AValue.AsString);
  412. CheckEquals(False, AValue.IsOrdinal);
  413. CheckEquals(False, AValue.IsObject);
  414. CheckEquals(False, AValue.IsArray);
  415. CheckEquals(False, AValue.IsClass);
  416. finally
  417. AtestClass.Free;
  418. end;
  419. CheckEquals('Hello World',AValue.AsString);
  420. finally
  421. c.Free;
  422. end;
  423. end;
  424. procedure TTestCase1.TestPropGetValueInteger;
  425. var
  426. ATestClass : TTestValueClass;
  427. c: TRttiContext;
  428. ARttiType: TRttiType;
  429. AProperty: TRttiProperty;
  430. AValue: TValue;
  431. begin
  432. c := TRttiContext.Create;
  433. try
  434. ATestClass := TTestValueClass.Create;
  435. ATestClass.AInteger := 472349;
  436. try
  437. ARttiType := c.GetType(ATestClass.ClassInfo);
  438. Check(assigned(ARttiType));
  439. AProperty := ARttiType.GetProperty('ainteger');
  440. AValue := AProperty.GetValue(ATestClass);
  441. CheckEquals(472349,AValue.AsInteger);
  442. ATestClass.AInteger := 12;
  443. CheckEquals(472349, AValue.AsInteger);
  444. CheckEquals('472349', AValue.ToString);
  445. CheckEquals(True, AValue.IsOrdinal);
  446. finally
  447. AtestClass.Free;
  448. end;
  449. CheckEquals(472349,AValue.AsInteger);
  450. finally
  451. c.Free;
  452. end;
  453. end;
  454. procedure TTestCase1.TestPropGetValueString;
  455. var
  456. ATestClass : TTestValueClass;
  457. c: TRttiContext;
  458. ARttiType: TRttiType;
  459. AProperty: TRttiProperty;
  460. AValue: TValue;
  461. i: int64;
  462. begin
  463. c := TRttiContext.Create;
  464. try
  465. ATestClass := TTestValueClass.Create;
  466. ATestClass.AString := 'Hello World';
  467. try
  468. ARttiType := c.GetType(ATestClass.ClassInfo);
  469. Check(assigned(ARttiType));
  470. AProperty := ARttiType.GetProperty('astring');
  471. AValue := AProperty.GetValue(ATestClass);
  472. CheckEquals('Hello World',AValue.AsString);
  473. ATestClass.AString := 'Goodbye World';
  474. CheckEquals('Hello World',AValue.AsString);
  475. CheckEquals('Hello World',AValue.ToString);
  476. Check(TypeInfo(string)=AValue.TypeInfo);
  477. Check(AValue.TypeData=GetTypeData(AValue.TypeInfo));
  478. Check(AValue.IsEmpty=false);
  479. Check(AValue.IsObject=false);
  480. Check(AValue.IsClass=false);
  481. CheckEquals(AValue.IsOrdinal, false);
  482. CheckEquals(AValue.TryAsOrdinal(i), false);
  483. CheckEquals(AValue.IsType(TypeInfo(string)), true);
  484. CheckEquals(AValue.IsType(TypeInfo(integer)), false);
  485. CheckEquals(AValue.IsArray, false);
  486. finally
  487. AtestClass.Free;
  488. end;
  489. CheckEquals('Hello World',AValue.AsString);
  490. finally
  491. c.Free;
  492. end;
  493. end;
  494. procedure TTestCase1.TestPropGetValueProcBoolean;
  495. var
  496. ATestClass : TTestValueClass;
  497. c: TRttiContext;
  498. ARttiType: TRttiType;
  499. AProperty: TRttiProperty;
  500. AValue: TValue;
  501. begin
  502. c := TRttiContext.Create;
  503. try
  504. ATestClass := TTestValueClass.Create;
  505. ATestClass.ABoolean := true;
  506. try
  507. ARttiType := c.GetType(ATestClass.ClassInfo);
  508. Check(assigned(ARttiType));
  509. AProperty := ARttiType.GetProperty('aGetBoolean');
  510. AValue := AProperty.GetValue(ATestClass);
  511. CheckEquals(true,AValue.AsBoolean);
  512. finally
  513. AtestClass.Free;
  514. end;
  515. CheckEquals(True,AValue.AsBoolean);
  516. finally
  517. c.Free;
  518. end;
  519. end;
  520. procedure TTestCase1.TestPropGetValueProcShortString;
  521. var
  522. ATestClass : TTestValueClass;
  523. c: TRttiContext;
  524. ARttiType: TRttiType;
  525. AProperty: TRttiProperty;
  526. AValue: TValue;
  527. begin
  528. c := TRttiContext.Create;
  529. try
  530. ATestClass := TTestValueClass.Create;
  531. ATestClass.AShortString := 'Hello World';
  532. try
  533. ARttiType := c.GetType(ATestClass.ClassInfo);
  534. Check(assigned(ARttiType));
  535. AProperty := ARttiType.GetProperty('aGetShortString');
  536. AValue := AProperty.GetValue(ATestClass);
  537. CheckEquals('Hello World',AValue.AsString);
  538. finally
  539. AtestClass.Free;
  540. end;
  541. CheckEquals('Hello World',AValue.AsString);
  542. finally
  543. c.Free;
  544. end;
  545. end;
  546. procedure TTestCase1.TestPropSetValueString;
  547. var
  548. ATestClass : TTestValueClass;
  549. c: TRttiContext;
  550. ARttiType: TRttiType;
  551. AProperty: TRttiProperty;
  552. AValue: TValue;
  553. s: string;
  554. begin
  555. c := TRttiContext.Create;
  556. try
  557. ATestClass := TTestValueClass.Create;
  558. try
  559. ARttiType := c.GetType(ATestClass.ClassInfo);
  560. AProperty := ARttiType.GetProperty('astring');
  561. s := 'ipse lorem or something like that';
  562. TValue.Make(@s, TypeInfo(string), AValue);
  563. AProperty.SetValue(ATestClass, AValue);
  564. CheckEquals(ATestClass.AString, s);
  565. s := 'Another string';
  566. CheckEquals(ATestClass.AString, 'ipse lorem or something like that');
  567. finally
  568. AtestClass.Free;
  569. end;
  570. finally
  571. c.Free;
  572. end;
  573. end;
  574. procedure TTestCase1.TestPropSetValueInteger;
  575. var
  576. ATestClass : TTestValueClass;
  577. c: TRttiContext;
  578. ARttiType: TRttiType;
  579. AProperty: TRttiProperty;
  580. AValue: TValue;
  581. i: integer;
  582. begin
  583. c := TRttiContext.Create;
  584. try
  585. ATestClass := TTestValueClass.Create;
  586. try
  587. ARttiType := c.GetType(ATestClass.ClassInfo);
  588. AProperty := ARttiType.GetProperty('aInteger');
  589. i := -43573;
  590. TValue.Make(@i, TypeInfo(Integer), AValue);
  591. AProperty.SetValue(ATestClass, AValue);
  592. CheckEquals(ATestClass.AInteger, i);
  593. i := 1;
  594. CheckEquals(ATestClass.AInteger, -43573);
  595. finally
  596. AtestClass.Free;
  597. end;
  598. finally
  599. c.Free;
  600. end;
  601. end;
  602. procedure TTestCase1.TestPropSetValueBoolean;
  603. var
  604. ATestClass : TTestValueClass;
  605. c: TRttiContext;
  606. ARttiType: TRttiType;
  607. AProperty: TRttiProperty;
  608. AValue: TValue;
  609. b: boolean;
  610. begin
  611. c := TRttiContext.Create;
  612. try
  613. ATestClass := TTestValueClass.Create;
  614. try
  615. ARttiType := c.GetType(ATestClass.ClassInfo);
  616. AProperty := ARttiType.GetProperty('aboolean');
  617. b := true;
  618. TValue.Make(@b, TypeInfo(Boolean), AValue);
  619. AProperty.SetValue(ATestClass, AValue);
  620. CheckEquals(ATestClass.ABoolean, b);
  621. b := false;
  622. CheckEquals(ATestClass.ABoolean, true);
  623. TValue.Make(@b, TypeInfo(Boolean), AValue);
  624. AProperty.SetValue(ATestClass, AValue);
  625. CheckEquals(ATestClass.ABoolean, false);
  626. finally
  627. AtestClass.Free;
  628. end;
  629. finally
  630. c.Free;
  631. end;
  632. end;
  633. procedure TTestCase1.TestPropSetValueShortString;
  634. var
  635. ATestClass : TTestValueClass;
  636. c: TRttiContext;
  637. ARttiType: TRttiType;
  638. AProperty: TRttiProperty;
  639. AValue: TValue;
  640. s: string;
  641. ss: ShortString;
  642. begin
  643. c := TRttiContext.Create;
  644. try
  645. ATestClass := TTestValueClass.Create;
  646. try
  647. ARttiType := c.GetType(ATestClass.ClassInfo);
  648. AProperty := ARttiType.GetProperty('aShortString');
  649. s := 'ipse lorem or something like that';
  650. TValue.Make(@s, TypeInfo(String), AValue);
  651. AProperty.SetValue(ATestClass, AValue);
  652. CheckEquals(ATestClass.AShortString, s);
  653. s := 'Another string';
  654. CheckEquals(ATestClass.AShortString, 'ipse lorem or something like that');
  655. ss := 'Hello World';
  656. TValue.Make(@ss, TypeInfo(ShortString), AValue);
  657. AProperty.SetValue(ATestClass, AValue);
  658. CheckEquals(ATestClass.AShortString, ss);
  659. ss := 'Foobar';
  660. CheckEquals(ATestClass.AShortString, 'Hello World');
  661. finally
  662. AtestClass.Free;
  663. end;
  664. finally
  665. c.Free;
  666. end;
  667. end;
  668. procedure TTestCase1.TestPropGetValueProcInteger;
  669. var
  670. ATestClass : TTestValueClass;
  671. c: TRttiContext;
  672. ARttiType: TRttiType;
  673. AProperty: TRttiProperty;
  674. AValue: TValue;
  675. begin
  676. c := TRttiContext.Create;
  677. try
  678. ATestClass := TTestValueClass.Create;
  679. ATestClass.AInteger := 472349;
  680. try
  681. ARttiType := c.GetType(ATestClass.ClassInfo);
  682. Check(assigned(ARttiType));
  683. AProperty := ARttiType.GetProperty('agetinteger');
  684. AValue := AProperty.GetValue(ATestClass);
  685. CheckEquals(472349,AValue.AsInteger);
  686. finally
  687. AtestClass.Free;
  688. end;
  689. CheckEquals(472349,AValue.AsInteger);
  690. finally
  691. c.Free;
  692. end;
  693. end;
  694. procedure TTestCase1.TestPropGetValueProcString;
  695. var
  696. ATestClass : TTestValueClass;
  697. c: TRttiContext;
  698. ARttiType: TRttiType;
  699. AProperty: TRttiProperty;
  700. AValue: TValue;
  701. begin
  702. c := TRttiContext.Create;
  703. try
  704. ATestClass := TTestValueClass.Create;
  705. ATestClass.AString := 'Hello World';
  706. try
  707. ARttiType := c.GetType(ATestClass.ClassInfo);
  708. Check(assigned(ARttiType));
  709. AProperty := ARttiType.GetProperty('agetstring');
  710. AValue := AProperty.GetValue(ATestClass);
  711. CheckEquals('Hello World',AValue.AsString);
  712. finally
  713. AtestClass.Free;
  714. end;
  715. CheckEquals('Hello World',AValue.AsString);
  716. finally
  717. c.Free;
  718. end;
  719. end;
  720. procedure TTestCase1.TestTRttiTypeProperties;
  721. var
  722. c: TRttiContext;
  723. ARttiType: TRttiType;
  724. begin
  725. c := TRttiContext.Create;
  726. try
  727. ARttiType := c.GetType(TTestValueClass);
  728. Check(assigned(ARttiType));
  729. CheckEquals(ARttiType.Name,'TTestValueClass');
  730. Check(ARttiType.TypeKind=tkClass);
  731. // CheckEquals(ARttiType.IsPublicType,false);
  732. CheckEquals(ARttiType.TypeSize,SizeOf(TObject));
  733. CheckEquals(ARttiType.IsManaged,false);
  734. CheckEquals(ARttiType.BaseType.classname,'TRttiInstanceType');
  735. CheckEquals(ARttiType.IsInstance,True);
  736. CheckEquals(ARttiType.AsInstance.DeclaringUnitName,'tests.rtti');
  737. Check(ARttiType.BaseType.Name='TObject');
  738. Check(ARttiType.AsInstance.BaseType.Name='TObject');
  739. CheckEquals(ARttiType.IsOrdinal,False);
  740. CheckEquals(ARttiType.IsRecord,False);
  741. CheckEquals(ARttiType.IsSet,False);
  742. finally
  743. c.Free;
  744. end;
  745. end;
  746. procedure TTestCase1.GetTypeInteger;
  747. var
  748. LContext: TRttiContext;
  749. LType: TRttiType;
  750. begin
  751. LContext := TRttiContext.Create;
  752. LType := LContext.GetType(TypeInfo(integer));
  753. {$ifdef fpc}
  754. CheckEquals(LType.Name, 'LongInt');
  755. {$else}
  756. CheckEquals(LType.Name, 'Integer');
  757. {$endif}
  758. LContext.Free;
  759. end;
  760. procedure TTestCase1.GetClassProperties;
  761. var
  762. LContext: TRttiContext;
  763. LType: TRttiType;
  764. PropList: {$ifdef fpc}specialize{$endif} TArray<TRttiProperty>;
  765. begin
  766. LContext := TRttiContext.Create;
  767. LType := LContext.GetType(TypeInfo(TGetClassProperties));
  768. PropList := LType.GetProperties;
  769. CheckEquals(4, length(PropList));
  770. CheckEquals('PubPropRO', PropList[0].Name);
  771. CheckEquals('PubPropRW', PropList[1].Name);
  772. CheckEquals('PubPropSetRO', PropList[2].Name);
  773. CheckEquals('PubPropSetRW', PropList[3].Name);
  774. LContext.Free;
  775. end;
  776. procedure TTestCase1.GetClassPropertiesValue;
  777. var
  778. AGetClassProperties: TGetClassProperties;
  779. LContext: TRttiContext;
  780. LType: TRttiType;
  781. AValue: TValue;
  782. begin
  783. LContext := TRttiContext.Create;
  784. LType := LContext.GetType(TGetClassProperties);
  785. AGetClassProperties := TGetClassProperties.Create;
  786. try
  787. AGetClassProperties.PubPropRW:=12345;
  788. AValue := LType.GetProperty('PubPropRW').GetValue(AGetClassProperties);
  789. CheckEquals(12345, AValue.AsInteger);
  790. finally
  791. AGetClassProperties.Free;
  792. end;
  793. LContext.Free;
  794. end;
  795. procedure TTestCase1.TestReferenceRawData;
  796. var
  797. value: TValue;
  798. str: String;
  799. intf: IInterface;
  800. i: LongInt;
  801. test: TTestRecord;
  802. arrdyn: TArrayOfLongintDyn;
  803. arrstat: TArrayOfLongintStatic;
  804. begin
  805. str := 'Hello World';
  806. UniqueString(str);
  807. TValue.Make(@str, TypeInfo(String), value);
  808. Check(PPointer(value.GetReferenceToRawData)^ = Pointer(str), 'Reference to string data differs');
  809. intf := TInterfacedObject.Create;
  810. TValue.Make(@intf, TypeInfo(IInterface), value);
  811. Check(PPointer(value.GetReferenceToRawData)^ = Pointer(intf), 'Reference to interface data differs');
  812. i := 42;
  813. TValue.Make(@i, TypeInfo(LongInt), value);
  814. Check(value.GetReferenceToRawData <> @i, 'Reference to longint is equal');
  815. Check(PLongInt(value.GetReferenceToRawData)^ = PLongInt(@i)^, 'Reference to longint data differs');
  816. test.value1 := 42;
  817. test.value2 := 'Hello World';
  818. TValue.Make(@test, TypeInfo(TTestRecord), value);
  819. Check(value.GetReferenceToRawData <> @test, 'Reference to record is equal');
  820. Check(PTestRecord(value.GetReferenceToRawData)^.value1 = PTestRecord(@test)^.value1, 'Reference to record data value1 differs');
  821. Check(PTestRecord(value.GetReferenceToRawData)^.value2 = PTestRecord(@test)^.value2, 'Reference to record data value2 differs');
  822. SetLength(arrdyn, 3);
  823. arrdyn[0] := 42;
  824. arrdyn[1] := 23;
  825. arrdyn[2] := 49;
  826. TValue.Make(@arrdyn, TypeInfo(TArrayOfLongintDyn), value);
  827. Check(PPointer(value.GetReferenceToRawData)^ = Pointer(arrdyn), 'Reference to dynamic array data differs');
  828. arrstat[0] := 42;
  829. arrstat[1] := 23;
  830. arrstat[2] := 49;
  831. arrstat[3] := 59;
  832. TValue.Make(@arrstat, TypeInfo(TArrayOfLongintStatic), value);
  833. Check(value.GetReferenceToRawData <> @arrstat, 'Reference to static array is equal');
  834. Check(PLongInt(value.GetReferenceToRawData)^ = PLongInt(@arrstat)^, 'Reference to static array data differs');
  835. end;
  836. procedure TTestCase1.TestReferenceRawDataEmpty;
  837. var
  838. value: TValue;
  839. begin
  840. TValue.Make(Nil, TypeInfo(String), value);
  841. Check(Assigned(value.GetReferenceToRawData()), 'Reference to empty String is not assigned');
  842. Check(not Assigned(PPointer(value.GetReferenceToRawData)^), 'Empty String data is assigned');
  843. TValue.Make(Nil, TypeInfo(IInterface), value);
  844. Check(Assigned(value.GetReferenceToRawData()), 'Reference to empty interface is not assigned');
  845. Check(not Assigned(PPointer(value.GetReferenceToRawData)^), 'Empty interface data is assigned');
  846. TValue.Make(Nil, TypeInfo(LongInt), value);
  847. Check(Assigned(value.GetReferenceToRawData()), 'Reference to empty LongInt is not assigned');
  848. Check(PLongInt(value.GetReferenceToRawData)^ = 0, 'Empty longint data is not 0');
  849. TValue.Make(Nil, TypeInfo(TTestRecord), value);
  850. Check(Assigned(value.GetReferenceToRawData()), 'Reference to empty record is not assigned');
  851. Check(PTestRecord(value.GetReferenceToRawData)^.value1 = 0, 'Empty record data value1 is not 0');
  852. Check(PTestRecord(value.GetReferenceToRawData)^.value2 = '', 'Empty record data value2 is not empty');
  853. TValue.Make(Nil, TypeInfo(TArrayOfLongintDyn), value);
  854. Check(Assigned(value.GetReferenceToRawData()), 'Reference to empty dynamic array is not assigned');
  855. Check(not Assigned(PPointer(value.GetReferenceToRawData)^), 'Empty dynamic array data is assigned');
  856. TValue.Make(Nil, TypeInfo(TArrayOfLongintStatic), value);
  857. Check(Assigned(value.GetReferenceToRawData()), 'Reference to empty static array is not assigned');
  858. Check(PLongInt(value.GetReferenceToRawData)^ = 0, 'Empty static array data is not 0');
  859. end;
  860. procedure TTestCase1.TestDataSize;
  861. var
  862. u8: UInt8;
  863. u16: UInt16;
  864. u32: UInt32;
  865. u64: UInt64;
  866. s8: Int8;
  867. s16: Int16;
  868. s32: Int32;
  869. s64: Int64;
  870. f32: Single;
  871. f64: Double;
  872. {$ifdef FPC_HAS_TYPE_EXTENDED}
  873. f80: Extended;
  874. {$endif}
  875. fco: Comp;
  876. fcu: Currency;
  877. ss: ShortString;
  878. sa: AnsiString;
  879. su: UnicodeString;
  880. sw: WideString;
  881. o: TObject;
  882. c: TClass;
  883. i: IInterface;
  884. ad: TArrayOfLongintDyn;
  885. _as: TArrayOfLongintStatic;
  886. b8: Boolean;
  887. {$ifdef fpc}
  888. b16: Boolean16;
  889. b32: Boolean32;
  890. b64: Boolean64;
  891. {$endif}
  892. bl8: ByteBool;
  893. bl16: WordBool;
  894. bl32: LongBool;
  895. {$ifdef fpc}
  896. bl64: QWordBool;
  897. {$endif}
  898. e: TTestEnum;
  899. s: TTestSet;
  900. t: TTestRecord;
  901. p: Pointer;
  902. proc: TTestProc;
  903. method: TTestMethod;
  904. value: TValue;
  905. begin
  906. TValue.Make(@u8, TypeInfo(UInt8), value);
  907. CheckEquals(1, value.DataSize, 'Size of UInt8 differs');
  908. TValue.Make(@u16, TypeInfo(UInt16), value);
  909. CheckEquals(2, value.DataSize, 'Size of UInt16 differs');
  910. TValue.Make(@u32, TypeInfo(UInt32), value);
  911. CheckEquals(4, value.DataSize, 'Size of UInt32 differs');
  912. TValue.Make(@u64, TypeInfo(UInt64), value);
  913. CheckEquals(8, value.DataSize, 'Size of UInt64 differs');
  914. TValue.Make(@s8, TypeInfo(Int8), value);
  915. CheckEquals(1, value.DataSize, 'Size of Int8 differs');
  916. TValue.Make(@s16, TypeInfo(Int16), value);
  917. CheckEquals(2, value.DataSize, 'Size of Int16 differs');
  918. TValue.Make(@s32, TypeInfo(Int32), value);
  919. CheckEquals(4, value.DataSize, 'Size of Int32 differs');
  920. TValue.Make(@s64, TypeInfo(Int64), value);
  921. CheckEquals(8, value.DataSize, 'Size of Int64 differs');
  922. TValue.Make(@b8, TypeInfo(Boolean), value);
  923. CheckEquals(1, value.DataSize, 'Size of Boolean differs');
  924. {$ifdef fpc}
  925. TValue.Make(@b16, TypeInfo(Boolean16), value);
  926. CheckEquals(2, value.DataSize, 'Size of Boolean16 differs');
  927. TValue.Make(@b32, TypeInfo(Boolean32), value);
  928. CheckEquals(4, value.DataSize, 'Size of Boolean32 differs');
  929. TValue.Make(@b64, TypeInfo(Boolean64), value);
  930. CheckEquals(8, value.DataSize, 'Size of Boolean64 differs');
  931. {$endif}
  932. TValue.Make(@bl8, TypeInfo(ByteBool), value);
  933. CheckEquals(1, value.DataSize, 'Size of ByteBool differs');
  934. TValue.Make(@bl16, TypeInfo(WordBool), value);
  935. CheckEquals(2, value.DataSize, 'Size of WordBool differs');
  936. TValue.Make(@bl32, TypeInfo(LongBool), value);
  937. CheckEquals(4, value.DataSize, 'Size of LongBool differs');
  938. {$ifdef fpc}
  939. TValue.Make(@bl64, TypeInfo(QWordBool), value);
  940. CheckEquals(8, value.DataSize, 'Size of QWordBool differs');
  941. {$endif}
  942. TValue.Make(@f32, TypeInfo(Single), value);
  943. CheckEquals(4, value.DataSize, 'Size of Single differs');
  944. TValue.Make(@f64, TypeInfo(Double), value);
  945. CheckEquals(8, value.DataSize, 'Size of Double differs');
  946. {$ifdef FPC_HAS_TYPE_EXTENDED}
  947. TValue.Make(@f80, TypeInfo(Extended), value);
  948. CheckEquals(10, value.DataSize, 'Size of Extended differs');
  949. {$endif}
  950. TValue.Make(@fcu, TypeInfo(Currency), value);
  951. CheckEquals(SizeOf(Currency), value.DataSize, 'Size of Currency differs');
  952. TValue.Make(@fco, TypeInfo(Comp), value);
  953. CheckEquals(SizeOf(Comp), value.DataSize, 'Size of Comp differs');
  954. ss := '';
  955. TValue.Make(@ss, TypeInfo(ShortString), value);
  956. CheckEquals(254, value.DataSize, 'Size ofShortString differs');
  957. TValue.Make(@sa, TypeInfo(AnsiString), value);
  958. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of AnsiString differs');
  959. TValue.Make(@sw, TypeInfo(WideString), value);
  960. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of WideString differs');
  961. TValue.Make(@su, TypeInfo(UnicodeString), value);
  962. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of UnicodeString differs');
  963. o := TTestValueClass.Create;
  964. TValue.Make(@o, TypeInfo(TObject), value);
  965. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of TObject differs');
  966. o.Free;
  967. c := TObject;
  968. TValue.Make(@c, TypeInfo(TClass), value);
  969. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of TClass differs');
  970. TValue.Make(@i, TypeInfo(IInterface), value);
  971. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of IInterface differs');
  972. TValue.Make(@t, TypeInfo(TTestRecord), value);
  973. CheckEquals(SizeOf(TTestRecord), value.DataSize, 'Size of TTestRecord differs');
  974. proc := Nil;
  975. TValue.Make(@proc, TypeInfo(TTestProc), value);
  976. CheckEquals(SizeOf(TTestProc), value.DataSize, 'Size of TTestProc differs');
  977. method := Nil;
  978. TValue.Make(@method, TypeInfo(TTestMethod), value);
  979. CheckEquals(SizeOf(TTestMethod), value.DataSize, 'Size of TTestMethod differs');
  980. TValue.Make(@_as, TypeInfo(TArrayOfLongintStatic), value);
  981. CheckEquals(SizeOf(TArrayOfLongintStatic), value.DataSize, 'Size of TArrayOfLongintStatic differs');
  982. TValue.Make(@ad, TypeInfo(TArrayOfLongintDyn), value);
  983. CheckEquals(SizeOf(TArrayOfLongintDyn), value.DataSize, 'Size of TArrayOfLongintDyn differs');
  984. TValue.Make(@e, TypeInfo(TTestEnum), value);
  985. CheckEquals(SizeOf(TTestEnum), value.DataSize, 'Size of TTestEnum differs');
  986. TValue.Make(@s, TypeInfo(TTestSet), value);
  987. CheckEquals(SizeOf(TTestSet), value.DataSize, 'Size of TTestSet differs');
  988. p := Nil;
  989. TValue.Make(@p, TypeInfo(Pointer), value);
  990. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of Pointer differs');
  991. end;
  992. procedure TTestCase1.TestDataSizeEmpty;
  993. var
  994. value: TValue;
  995. begin
  996. TValue.Make(Nil, TypeInfo(UInt8), value);
  997. CheckEquals(1, value.DataSize, 'Size of UInt8 differs');
  998. TValue.Make(Nil, TypeInfo(UInt16), value);
  999. CheckEquals(2, value.DataSize, 'Size of UInt16 differs');
  1000. TValue.Make(Nil, TypeInfo(UInt32), value);
  1001. CheckEquals(4, value.DataSize, 'Size of UInt32 differs');
  1002. TValue.Make(Nil, TypeInfo(UInt64), value);
  1003. CheckEquals(8, value.DataSize, 'Size of UInt64 differs');
  1004. TValue.Make(Nil, TypeInfo(Int8), value);
  1005. CheckEquals(1, value.DataSize, 'Size of Int8 differs');
  1006. TValue.Make(Nil, TypeInfo(Int16), value);
  1007. CheckEquals(2, value.DataSize, 'Size of Int16 differs');
  1008. TValue.Make(Nil, TypeInfo(Int32), value);
  1009. CheckEquals(4, value.DataSize, 'Size of Int32 differs');
  1010. TValue.Make(Nil, TypeInfo(Int64), value);
  1011. CheckEquals(8, value.DataSize, 'Size of Int64 differs');
  1012. TValue.Make(Nil, TypeInfo(Boolean), value);
  1013. CheckEquals(1, value.DataSize, 'Size of Boolean differs');
  1014. {$ifdef fpc}
  1015. TValue.Make(Nil, TypeInfo(Boolean16), value);
  1016. CheckEquals(2, value.DataSize, 'Size of Boolean16 differs');
  1017. TValue.Make(Nil, TypeInfo(Boolean32), value);
  1018. CheckEquals(4, value.DataSize, 'Size of Boolean32 differs');
  1019. TValue.Make(Nil, TypeInfo(Boolean64), value);
  1020. CheckEquals(8, value.DataSize, 'Size of Boolean64 differs');
  1021. {$endif}
  1022. TValue.Make(Nil, TypeInfo(ByteBool), value);
  1023. CheckEquals(1, value.DataSize, 'Size of ByteBool differs');
  1024. TValue.Make(Nil, TypeInfo(WordBool), value);
  1025. CheckEquals(2, value.DataSize, 'Size of WordBool differs');
  1026. TValue.Make(Nil, TypeInfo(LongBool), value);
  1027. CheckEquals(4, value.DataSize, 'Size of LongBool differs');
  1028. {$ifdef fpc}
  1029. TValue.Make(Nil, TypeInfo(QWordBool), value);
  1030. CheckEquals(8, value.DataSize, 'Size of QWordBool differs');
  1031. {$endif}
  1032. TValue.Make(Nil, TypeInfo(Single), value);
  1033. CheckEquals(4, value.DataSize, 'Size of Single differs');
  1034. TValue.Make(Nil, TypeInfo(Double), value);
  1035. CheckEquals(8, value.DataSize, 'Size of Double differs');
  1036. {$ifdef FPC_HAS_TYPE_EXTENDED}
  1037. TValue.Make(Nil, TypeInfo(Extended), value);
  1038. CheckEquals(10, value.DataSize, 'Size of Extended differs');
  1039. {$endif}
  1040. TValue.Make(Nil, TypeInfo(Currency), value);
  1041. CheckEquals(SizeOf(Currency), value.DataSize, 'Size of Currency differs');
  1042. TValue.Make(Nil, TypeInfo(Comp), value);
  1043. CheckEquals(SizeOf(Comp), value.DataSize, 'Size of Comp differs');
  1044. TValue.Make(Nil, TypeInfo(ShortString), value);
  1045. CheckEquals(254, value.DataSize, 'Size of ShortString differs');
  1046. TValue.Make(Nil, TypeInfo(AnsiString), value);
  1047. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of Pointer differs');
  1048. TValue.Make(Nil, TypeInfo(WideString), value);
  1049. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of WideString differs');
  1050. TValue.Make(Nil, TypeInfo(UnicodeString), value);
  1051. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of UnicodeString differs');
  1052. TValue.Make(Nil, TypeInfo(TObject), value);
  1053. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of TObject differs');
  1054. TValue.Make(Nil, TypeInfo(TClass), value);
  1055. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of TClass differs');
  1056. TValue.Make(Nil, TypeInfo(IInterface), value);
  1057. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of IInterface differs');
  1058. TValue.Make(Nil, TypeInfo(TTestRecord), value);
  1059. CheckEquals(SizeOf(TTestRecord), value.DataSize, 'Size of TTestRecord differs');
  1060. TValue.Make(Nil, TypeInfo(TTestProc), value);
  1061. CheckEquals(SizeOf(TTestProc), value.DataSize, 'Size of TTestProc differs');
  1062. TValue.Make(Nil, TypeInfo(TTestMethod), value);
  1063. CheckEquals(SizeOf(TTestMethod), value.DataSize, 'Size of TTestMethod differs');
  1064. TValue.Make(Nil, TypeInfo(TArrayOfLongintStatic), value);
  1065. CheckEquals(SizeOf(TArrayOfLongintStatic), value.DataSize, 'Size of TArrayOfLongintStatic differs');
  1066. TValue.Make(Nil, TypeInfo(TArrayOfLongintDyn), value);
  1067. CheckEquals(SizeOf(TArrayOfLongintDyn), value.DataSize, 'Size of TArrayOfLongintDyn differs');
  1068. TValue.Make(Nil, TypeInfo(TTestEnum), value);
  1069. CheckEquals(SizeOf(TTestEnum), value.DataSize, 'Size of TTestEnum differs');
  1070. TValue.Make(Nil, TypeInfo(TTestSet), value);
  1071. CheckEquals(SizeOf(TTestSet), value.DataSize, 'Size of TTestSet differs');
  1072. TValue.Make(Nil, TypeInfo(Pointer), value);
  1073. CheckEquals(SizeOf(Pointer), value.DataSize, 'Size of Pointer differs');
  1074. end;
  1075. procedure TTestCase1.TestIsManaged;
  1076. begin
  1077. CheckEquals(true, IsManaged(TypeInfo(ansistring)), 'IsManaged for tkAString');
  1078. CheckEquals(true, IsManaged(TypeInfo(widestring)), 'IsManaged for tkWString');
  1079. CheckEquals(true, IsManaged(TypeInfo(Variant)), 'IsManaged for tkVariant');
  1080. CheckEquals(true, IsManaged(TypeInfo(TArrayOfManagedRec)),
  1081. 'IsManaged for tkArray (with managed ElType)');
  1082. CheckEquals(true, IsManaged(TypeInfo(TArrayOfString)),
  1083. 'IsManaged for tkArray (with managed ElType)');
  1084. CheckEquals(true, IsManaged(TypeInfo(TManagedRec)), 'IsManaged for tkRecord');
  1085. {$ifdef fpc}
  1086. CheckEquals(true, IsManaged(TypeInfo(TManagedRecOp)), 'IsManaged for tkRecord');
  1087. {$endif}
  1088. CheckEquals(true, IsManaged(TypeInfo(IInterface)), 'IsManaged for tkInterface');
  1089. CheckEquals(true, IsManaged(TypeInfo(TManagedObj)), 'IsManaged for tkObject');
  1090. {$ifdef fpc}
  1091. CheckEquals(true, IsManaged(TypeInfo(specialize TArray<byte>)), 'IsManaged for tkDynArray');
  1092. {$else}
  1093. CheckEquals(true, IsManaged(TypeInfo(TArray<byte>)), 'IsManaged for tkDynArray');
  1094. {$endif}
  1095. CheckEquals(true, IsManaged(TypeInfo(unicodestring)), 'IsManaged for tkUString');
  1096. CheckEquals(false, IsManaged(TypeInfo(shortstring)), 'IsManaged for tkSString');
  1097. CheckEquals(false, IsManaged(TypeInfo(Byte)), 'IsManaged for tkInteger');
  1098. CheckEquals(false, IsManaged(TypeInfo(Char)), 'IsManaged for tkChar');
  1099. CheckEquals(false, IsManaged(TypeInfo(TTestEnum)), 'IsManaged for tkEnumeration');
  1100. CheckEquals(false, IsManaged(TypeInfo(Single)), 'IsManaged for tkFloat');
  1101. CheckEquals(false, IsManaged(TypeInfo(TTestSet)), 'IsManaged for tkSet');
  1102. {$ifdef fpc}
  1103. CheckEquals(false, IsManaged(TypeInfo(TTestMethod)), 'IsManaged for tkMethod');
  1104. {$else}
  1105. { Delphi bug (or sabotage). For some reason Delphi considers method pointers to be managed (only in newer versions, probably since XE7) :/ }
  1106. CheckEquals({$if RTLVersion>=28}true{$else}false{$endif}, IsManaged(TypeInfo(TTestMethod)), 'IsManaged for tkMethod');
  1107. {$endif}
  1108. CheckEquals(false, IsManaged(TypeInfo(TArrayOfByte)),
  1109. 'IsManaged for tkArray (with non managed ElType)');
  1110. CheckEquals(false, IsManaged(TypeInfo(TArrayOfNonManagedRec)),
  1111. 'IsManaged for tkArray (with non managed ElType)');
  1112. CheckEquals(false, IsManaged(TypeInfo(TNonManagedRec)), 'IsManaged for tkRecord');
  1113. CheckEquals(false, IsManaged(TypeInfo(TObject)), 'IsManaged for tkClass');
  1114. CheckEquals(false, IsManaged(TypeInfo(TNonManagedObj)), 'IsManaged for tkObject');
  1115. CheckEquals(false, IsManaged(TypeInfo(WideChar)), 'IsManaged for tkWChar');
  1116. CheckEquals(false, IsManaged(TypeInfo(Boolean)), 'IsManaged for tkBool');
  1117. CheckEquals(false, IsManaged(TypeInfo(Int64)), 'IsManaged for tkInt64');
  1118. CheckEquals(false, IsManaged(TypeInfo(UInt64)), 'IsManaged for tkQWord');
  1119. {$ifdef fpc}
  1120. CheckEquals(false, IsManaged(TypeInfo(ICORBATest)), 'IsManaged for tkInterfaceRaw');
  1121. {$endif}
  1122. CheckEquals(false, IsManaged(TypeInfo(TTestProc)), 'IsManaged for tkProcVar');
  1123. CheckEquals(false, IsManaged(TypeInfo(TTestHelper)), 'IsManaged for tkHelper');
  1124. {$ifdef fpc}
  1125. CheckEquals(false, IsManaged(TypeInfo(file)), 'IsManaged for tkFile');
  1126. {$endif}
  1127. CheckEquals(false, IsManaged(TypeInfo(TClass)), 'IsManaged for tkClassRef');
  1128. CheckEquals(false, IsManaged(TypeInfo(Pointer)), 'IsManaged for tkPointer');
  1129. CheckEquals(false, IsManaged(nil), 'IsManaged for nil');
  1130. end;
  1131. initialization
  1132. {$ifdef fpc}
  1133. RegisterTest(TTestCase1);
  1134. {$else fpc}
  1135. RegisterTest(TTestCase1.Suite);
  1136. {$endif fpc}
  1137. end.